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

   Два ритма:
   .is-beat — «кадр»: во весь экран, одна мысль, фильм светлый и в движении
   .is-read — «текст»: плотная вёрстка, фильм уходит в тень и ЗАМИРАЕТ

   Правила языка: ни одной коробки и ни одной заливки — только
   волосяные линии; между крупным и мелким кеглем нет «средних»
   размеров; блоки садятся со сдвигом по 12-колоночной сетке,
   а не по центру.
   ========================================================= */

.page { position: relative; z-index: var(--z-page); }

.chapter { position: relative; }

/* Контент «кадра» прижат к низу: сверху кадр дышит, внизу
   тип садится на плотную подложку. Это композиция киноплаката,
   а не «текст по центру поверх картинки». */
.chapter.is-beat {
  min-height: calc(var(--vh, 1svh) * 100);
  display: grid;
  align-content: end;
  padding-block: clamp(8rem, calc(var(--vh, 1svh) * 19), 13rem) clamp(4.5rem, calc(var(--vh, 1svh) * 11), 8rem);
}

.chapter.is-read { padding-block: var(--pad); }

/* Переход — чистая плёнка. Здесь проигрывается ровно один клип,
   от шва до шва. Текста нет намеренно: все блоки стоят на швах,
   а между ними идёт только кино. */
.chapter.is-move {
  min-height: calc(var(--vh, 1svh) * 105);
}

/* Донный скрим живёт на фиксированном слое фильма (film__scrim):
   секционный псевдоэлемент давал видимый стык между двумя «кадрами». */

.chapter.is-beat h1,
.chapter.is-beat h2,
.chapter.is-beat p { text-shadow: 0 2px 24px rgba(2, 5, 11, 0.95); }

.chapter.is-beat .lead,
.chapter.is-beat p { color: rgba(240, 232, 218, 0.94); }

/* ---- Угловой маркер главы: римская цифра + имя ---- */
.mark {
  position: absolute;
  top: clamp(5.5rem, calc(var(--vh, 1svh) * 13), 8.5rem);
  left: var(--gut);
  right: var(--gut);
  display: flex;
  align-items: center;
  gap: 1.1rem;
  pointer-events: none;
}
.mark__line { flex: 1; height: 1px; background: var(--hair); }
.mark .slate { white-space: nowrap; }

/* ============ I. Пролог ============ */

.hero__top { display: flex; align-items: baseline; gap: 1.2rem; margin-bottom: clamp(1.6rem, calc(var(--vh, 1svh) * 4), 3rem); }
.hero__top .hair { flex: 1; min-width: 2.5rem; }

/* Слот надписи рассчитан на три слова («ОДИН ЗАХОД В ГОДУ»), а здесь
   целое предложение. С разрядкой 0.38em оно расползлось бы на четыре
   строки и вытеснило линейку: убавляем разрядку и разрешаем перенос. */
.label--long {
  letter-spacing: 0.16em;
  max-width: 56ch;
  line-height: 1.75;
}

.hero h1 { max-width: 15ch; }

.hero__lower {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: clamp(1.6rem, 4vw, 4rem);
  margin-top: clamp(2.2rem, calc(var(--vh, 1svh) * 5), 3.6rem);
  padding-top: clamp(1.6rem, calc(var(--vh, 1svh) * 3), 2.4rem);
  border-top: 1px solid var(--hair);
}
.hero__sub { max-width: 40ch; }

.hero__offer { display: flex; flex-direction: column; align-items: flex-end; gap: 0.5rem; }
.hero__cta { margin-top: 1.6rem; }

/* подсказка уходит вправо: слева весь низ занят типом */
.hint {
  position: absolute;
  bottom: clamp(1.5rem, calc(var(--vh, 1svh) * 3.5), 2.6rem);
  right: var(--gut);
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-size: var(--t-label);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--bone-dim);
  transition: opacity 0.6s var(--ease);
}
.is-past-hero .hint { opacity: 0; }
.hint__line {
  width: 56px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--champ));
  transform-origin: right;
  animation: hint 2.6s var(--ease) infinite;
}
@keyframes hint {
  0%   { transform: scaleX(0); opacity: 0; }
  40%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

/* ============ II. Манифест ============ */

.manifest__lines {
  font-family: var(--display);
  font-size: var(--t-beat);
  line-height: 1.04;
  letter-spacing: -0.02em;
}
/* строгий потомок: внутрь этих строк скрипт кладёт ещё span'ы на слово */
.manifest__lines > span { display: block; }
.manifest__lines > span + span { color: var(--champ-hi); padding-left: clamp(2rem, 11vw, 11rem); }

.manifest__text {
  grid-column: 6 / -1;
  margin-top: clamp(2.4rem, calc(var(--vh, 1svh) * 6), 4.5rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--hair);
}

/* ============ III. Глубина ============ */

.depth p {
  font-family: var(--display);
  font-size: var(--t-beat);
  line-height: 1.06;
  letter-spacing: -0.02em;
  max-width: 20ch;
}
.depth em { display: block; padding-left: clamp(2rem, 9vw, 9rem); }

/* ============ IV. Мастер ============

   Переделано целиком. Что было не так, по скриншоту с большого экрана:
   заголовок в узкой колонке ломался на шесть рваных строк, фото висело
   маленьким прямоугольником с пустотой под ним на пол-экрана, число и
   подпись в фактах слипались, а правая половина экрана пустовала.

   Стало: заголовок во всю ширину над блоком и в две ровные строки, фото
   крупное и в раме со сдвигом — она даёт глубину, которой не хватало,
   имя лежит прямо на кадре. Факты — волосяная таблица с крупными
   числами дидоном, каждое на своей строке. */

.master {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  column-gap: clamp(2.5rem, 6vw, 6rem);
  row-gap: clamp(2.5rem, calc(var(--vh, 1svh) * 6), 4.5rem);
  align-items: start;
}

.master__intro { grid-column: 1 / -1; }
.master__intro h2 {
  margin-top: 1.2rem;
  /* мера в знаках — чтобы строка ломалась там, где задумано, а не как выйдет */
  max-width: 24ch;
}

/* ---- Фото в раме со сдвигом ----
   Рамка не обводит кадр, а стоит за ним со смещением: приём из печатной
   вёрстки, который даёт слой и воздух там, где раньше был плоский
   прямоугольник на плоском фоне. */
.master__photo {
  position: relative;
  align-self: start;
}
.master__photo::before {
  content: "";
  position: absolute;
  inset: clamp(0.9rem, 2vw, 1.6rem) calc(-1 * clamp(0.9rem, 2vw, 1.6rem))
          calc(-1 * clamp(0.9rem, 2vw, 1.6rem)) clamp(0.9rem, 2vw, 1.6rem);
  border: 1px solid var(--hair-warm);
  pointer-events: none;
  transition: transform 0.8s var(--ease);
}
.master__photo:hover::before { transform: translate(4px, 4px); }

.master__photo img {
  position: relative;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  filter: saturate(0.94);
}

/* имя лежит на кадре, а не висит под ним отдельной строкой */
.master__caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  display: grid;
  gap: 0.3rem;
  padding: clamp(3rem, 8vw, 5rem) clamp(1rem, 2.5vw, 1.6rem) clamp(1rem, 2.2vw, 1.4rem);
  background: linear-gradient(180deg, transparent 0%, rgba(2, 5, 11, 0.86) 62%);
}
.master__name {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1rem + 0.7vw, 1.6rem);
  line-height: 1.1;
  color: var(--bone);
}
.master__role {
  font-family: var(--ui);
  font-size: var(--t-label);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--champ);
}

.master__photo.is-empty img { display: none; }
.master__photo.is-empty::after {
  content: "Павел Андреев";
  display: grid;
  place-content: center;
  aspect-ratio: 4 / 5;
  border: 1px solid var(--hair);
  color: var(--bone-dim);
  font-size: var(--t-label);
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

.master__body > .lead { max-width: 44ch; }

/* факты — волосяная таблица, а не карточки.
   Число и подпись раньше слипались: колонка под число была задана в
   процентах и на широком экране схлопывалась. Теперь она по содержимому. */
.facts {
  list-style: none;
  margin-top: clamp(2.2rem, calc(var(--vh, 1svh) * 5), 3.4rem);
}
.facts li {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: clamp(1.2rem, 3vw, 2.6rem);
  align-items: baseline;
  padding: clamp(1.1rem, 2.4vw, 1.6rem) 0;
  border-top: 1px solid var(--hair);
  transition: border-color 0.6s var(--ease);
}
.facts li:last-child { border-bottom: 1px solid var(--hair); }
.facts li:hover { border-color: var(--hair-warm); }
.facts b {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.5rem, 1rem + 1.6vw, 2.4rem);
  color: var(--champ-hi);
  white-space: nowrap;
  letter-spacing: -0.01em;
  line-height: 1;
}
.facts span { font-size: var(--t-small); color: var(--bone-mid); max-width: 32ch; }

@media (max-width: 900px) {
  .master { grid-template-columns: 1fr; }
  .master__photo { max-width: 24rem; }
  .master__photo::before { inset: 0.7rem -0.7rem -0.7rem 0.7rem; }
}

/* ============ V. Метод — лестница вглубь ============ */

.method__head { grid-column: 1 / 8; margin-bottom: clamp(2.6rem, calc(var(--vh, 1svh) * 7), 4.5rem); }
.method__head h2 { margin-top: 1.2rem; max-width: 16ch; }
.levels { grid-column: 1 / -1; }

.level {
  display: grid;
  grid-template-columns: 3.2rem 1fr;
  gap: clamp(1rem, 3vw, 2.6rem);
  padding: clamp(1.6rem, calc(var(--vh, 1svh) * 3.4), 2.4rem) 0;
  border-top: 1px solid var(--hair);
  transition: border-color 0.6s var(--ease);
}
.level:last-child { border-bottom: 1px solid var(--hair); }

/* каждый следующий уровень глубже — форма повторяет смысл */
.level:nth-child(2) { padding-left: clamp(0rem, 3vw, 3.5rem); }
.level:nth-child(3) { padding-left: clamp(0rem, 6vw, 7rem); }
.level:nth-child(4) { padding-left: clamp(0rem, 9vw, 10.5rem); }

.level h3 { margin-bottom: 0.5rem; }
.level p { color: var(--bone-mid); font-size: var(--t-small); max-width: 52ch; }

.method__note { grid-column: 6 / -1; margin-top: clamp(2.4rem, calc(var(--vh, 1svh) * 6), 4rem); }

/* ============ VI. Сферы ============ */

.spheres__head { grid-column: 1 / 9; margin-bottom: clamp(2.6rem, calc(var(--vh, 1svh) * 7), 4.5rem); }
.spheres__head h2 { margin-top: 1.2rem; }
.spheres__list { grid-column: 1 / -1; }

.sphere {
  display: grid;
  grid-template-columns: minmax(9rem, 2fr) 6fr;
  gap: clamp(1rem, 3vw, 3rem);
  padding: clamp(1.9rem, calc(var(--vh, 1svh) * 4), 2.8rem) 0;
  border-top: 1px solid var(--hair);
}
.sphere:last-child { border-bottom: 1px solid var(--hair); }
.sphere h3 {
  font-size: clamp(1.4rem, 1rem + 1.3vw, 2.05rem);
  color: var(--champ-hi);
}
.sphere__now, .sphere__after { font-size: var(--t-small); }
.sphere__now { color: var(--bone-dim); }
.sphere__after { color: var(--bone); }
.sphere__now .label, .sphere__after .label { margin-bottom: 0.7rem; }

/* Итог сферы читают в последнюю очередь и часто на телефоне,
   поэтому набран не «примечанием», а полноценным текстом. */
.spheres__note {
  grid-column: 5 / -1;
  margin-top: clamp(2rem, calc(var(--vh, 1svh) * 5), 3rem);
  font-size: clamp(1.02rem, 0.95rem + 0.35vw, 1.22rem);
  line-height: 1.55;
  color: var(--bone);
}

/* =========================================================
   КАРУСЕЛЬ
   Листается пальцем, колесом и стрелками. Никакой автопрокрутки:
   она уводила страницу и её нельзя было остановить.
   ========================================================= */

/* min-width: 0 обязателен: без него ячейка сетки растягивается под
   суммарную ширину слайдов, и страница уезжает вбок */
.carousel { position: relative; min-width: 0; }

.carousel__track {
  display: flex;
  gap: clamp(1rem, 2.5vw, 2rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* дойдя до края, не отдаём жест странице — иначе прокрутка прыгает */
  overscroll-behavior-x: contain;
  /* карусель не должна участвовать в привязке прокрутки страницы */
  overflow-anchor: none;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-bottom: 0.4rem;
}
.carousel__track::-webkit-scrollbar { display: none; }

.carousel .slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  min-width: 0;
}

/* пара «сейчас → после» внутри слайда */
.sphere .slide {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1rem, 3vw, 3rem);
  align-content: start;
}

/* ---- точки и стрелки ---- */

.carousel__bar {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin-top: 1.1rem;
}

/* min-width и overflow — страховка: указатель не должен уметь
   раздвинуть раскладку, сколько бы отзывов туда ни положили */
.carousel__dots {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

.carousel__count {
  font-family: var(--ui);
  font-size: var(--t-label);
  letter-spacing: 0.22em;
  color: var(--bone-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Точки были 22x2 px цветом rgba(240,232,218,0.14) — на тёмном фоне их
   попросту не видно, и человек не догадывался, что под «Деньгами» есть
   ещё четыре истории. Теперь линия заметная, а нажимать можно по площади
   44 px: сама точка тонкая, поле вокруг — нет. */
.carousel__dot {
  width: 26px; height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  position: relative;
}
.carousel__dot::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 3px;
  margin-top: -1.5px;
  background: rgba(240, 232, 218, 0.38);
  transition: background 0.4s var(--ease), height 0.3s var(--ease);
}
.carousel__dot[aria-current="true"]::before {
  background: var(--champ);
  height: 4px;
  margin-top: -2px;
}

/* 34x34 меньше нормы касания: палец мажет. */
.carousel__arrow {
  width: 44px; height: 44px;
  display: grid;
  place-content: center;
  border: 1px solid var(--hair-warm);
  background: transparent;
  color: var(--champ-hi);
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  transition: background 0.4s var(--ease), opacity 0.4s var(--ease);
}
.carousel__arrow:hover { background: rgba(216, 185, 143, 0.14); }
/* 0.25 читалось как украшение, а не как «дальше некуда» */
.carousel__arrow[disabled] { opacity: 0.4; cursor: default; }

/* ---- лента отзывов ---- */

/* Отзывы показываем скриншотами, как в актуальных в инстаграме:
   так видно, что это живая переписка, а не набранный нами текст.
   Высота у карточек разная — выравниваем по верху. */
.carousel--reviews .carousel__track { align-items: start; }

/* Ширину задаём через .carousel--reviews .slide, а не через .shot:
   у общего правила .carousel .slide специфичность выше, и одиночный
   класс им перебивался — скрины растягивались на всю ленту. */
.carousel--reviews .slide {
  flex: 0 0 clamp(240px, 26vw, 320px);
}

.shot {
  overflow: hidden;
  border: 1px solid var(--hair);
  background: var(--deep);
  transition: border-color 0.45s var(--ease);
}
.shot:hover { border-color: var(--hair-warm); }

/* Все карточки отзывов приведены к одному формату 4:5 ещё при сборке:
   скриншоты пришли с соотношением от 2.33 до 0.46, и лента из-за этого
   выглядела рваной. Теперь каждая вписана в общее поле на подложке цвета
   сайта и прогрета в тёплый тон, поэтому здесь достаточно держать формат —
   ни обрезки, ни ограничения высоты больше не нужно. */
.shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
}
.carousel--reviews cite {
  display: block;
  margin-top: 1rem;
  font-style: normal;
  font-size: var(--t-label);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

/* ============ VII. Сканирование ============ */

.scan__body { grid-column: 4 / 11; }
.scan h2 { margin: 1.4rem 0 1.8rem; }
.scan p { max-width: 50ch; }

/* ============ VIII. Семь дней ============ */

.week {
  overflow: hidden;
  min-height: calc(var(--vh, 1svh) * 175);
  display: grid;
  align-content: center;
}
.week__head { margin-bottom: clamp(2.6rem, calc(var(--vh, 1svh) * 7), 4.5rem); }
.week__head h2 { margin-top: 1.2rem; }

.week__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 94%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 94%, transparent 100%);
}
.week__track {
  display: flex;
  gap: clamp(1.6rem, 3.5vw, 3.2rem);
  width: max-content;
  padding-inline: var(--gut);
  will-change: transform;
}

/* карточка без рамки: только линия сверху — как строка в расписании */
.day {
  width: clamp(230px, 24vw, 300px);
  flex: 0 0 auto;
  padding-top: 1.1rem;
  border-top: 1px solid var(--hair);
  transition: border-color 0.5s var(--ease);
}
.day__num {
  font-family: var(--display);
  font-size: clamp(2.2rem, 1.6rem + 1.4vw, 3.1rem);
  line-height: 1;
  color: var(--champ);
  letter-spacing: -0.02em;
}
.day h3 { margin: 0.9rem 0 0.6rem; }
.day p { font-size: var(--t-small); color: var(--bone-mid); }

.week__progress { position: relative; height: 1px; margin: clamp(2rem, calc(var(--vh, 1svh) * 5), 3rem) var(--gut) 0; background: var(--hair); }
.week__progress i { position: absolute; inset: 0 auto 0 0; width: 14%; background: var(--champ); transform-origin: left; }

/* ============ IX. Яхта ============ */

.yacht__head { grid-column: 1 / 9; margin-bottom: clamp(2.6rem, calc(var(--vh, 1svh) * 7), 4.5rem); }
.yacht__head h2 { margin-top: 1.2rem; }
.decks { grid-column: 1 / -1; }

.deck {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: clamp(1rem, 3vw, 2.4rem);
  padding: clamp(1.5rem, calc(var(--vh, 1svh) * 3.2), 2.1rem) 0;
  border-top: 1px solid var(--hair);
  align-items: start;
}
.deck:last-child { border-bottom: 1px solid var(--hair); }
.deck p { color: var(--bone-mid); font-size: var(--t-small); margin-top: 0.4rem; max-width: 54ch; }

/* цифры как графика */
.stats {
  grid-column: 1 / -1;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: clamp(1.6rem, 3.5vw, 3rem);
  margin-top: clamp(3rem, calc(var(--vh, 1svh) * 7), 4.5rem);
}
.stats b {
  display: block;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.4rem, 1.4rem + 2.6vw, 4rem);
  line-height: 0.95;
  color: var(--champ-hi);
  letter-spacing: -0.03em;
  margin-bottom: 0.7rem;
}
.stats span { font-size: var(--t-label); letter-spacing: 0.26em; text-transform: uppercase; color: var(--bone-dim); }

/* ============ X. Сессии ============ */

.sessions__body { grid-column: 3 / 11; }
.sessions h2 { margin: 1.4rem 0 1.8rem; }
.sessions p { max-width: 52ch; }

/* ============ XI. Цена — свёрстана как счёт ============ */

.price__head { margin-bottom: clamp(2.4rem, calc(var(--vh, 1svh) * 6), 4rem); }
.price__head h2 { margin-top: 1.2rem; }

.bill__row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 1rem;
  padding: 1.15rem 0;
  border-top: 1px solid var(--hair);
}
.bill__row span { font-size: var(--t-small); color: var(--bone-dim); }
.bill__row b {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.15rem, 1rem + 0.7vw, 1.5rem);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.bill__row.is-total { border-top-color: var(--hair-warm); }
.bill__row.is-total span { color: var(--bone); }
.bill__row.is-total b { color: var(--champ-hi); }

/* Итоговая цифра — единственное место на странице, где свет исходит
   от самого типа. Ореол лежит под цифрой отдельным слоем, чтобы не
   размывать её контур тенью. */
.price__final { position: relative; margin-top: clamp(3.5rem, calc(var(--vh, 1svh) * 9), 6rem); }
.price__final::before {
  content: "";
  position: absolute;
  left: -12%; top: 10%;
  width: 90%; aspect-ratio: 2 / 1;
  background: radial-gradient(50% 50% at 50% 50%,
    rgba(216, 185, 143, 0.20) 0%,
    rgba(216, 185, 143, 0.07) 45%,
    transparent 72%);
  opacity: 0;
  transition: opacity 1.6s var(--slow) 0.4s;
  pointer-events: none;
}
.price__final.is-in::before { opacity: 1; }

.price__big {
  position: relative;
  font-family: var(--display);
  font-size: clamp(3.2rem, 1.4rem + 8vw, 8rem);
  line-height: 0.94;
  letter-spacing: -0.035em;
  color: var(--champ-hi);
  margin: 1rem 0 1.4rem;
  font-variant-numeric: tabular-nums;
}
.price__final .note { max-width: 38ch; margin-bottom: 2.6rem; }

/* ---- Счётчик: цифра растёт, коробка стоит ----
   Двойник с финальной суммой задаёт размер и остаётся невидимым; живое
   значение лежит в той же ячейке сетки поверх него. Раскладка страницы
   при этом не пересчитывается ни разу за анимацию. */
.count { display: inline-grid; }
.count > * { grid-area: 1 / 1; white-space: nowrap; }
.count__sizer { visibility: hidden; }

/* цифра не должна тянуть за собой пересчёт соседей */
.price__big { contain: layout; }

/* ============ XII. Включено ============ */

.included__head { grid-column: 1 / 6; }
.included__head h2 { margin-top: 1.2rem; }
.included__cols {
  grid-column: 6 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0 clamp(1.6rem, 4vw, 3.5rem);
}
.included__cols ul { list-style: none; }
.included__cols li {
  font-size: var(--t-small);
  color: var(--bone-mid);
  padding: 0.85rem 0;
  border-top: 1px solid var(--hair);
}

/* ============ XIII. Отзывы ============ */

.reviews__head h2 { margin-top: 1.2rem; }
.reviews__flag {
  display: inline-block;
  margin-top: 1.1rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px dashed var(--hair-warm);
  font-size: var(--t-label);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

.reviews .carousel { margin-top: clamp(2.4rem, calc(var(--vh, 1svh) * 6), 3.5rem); }

/* ============ XIV. Вопросы ============ */

.faq__head { grid-column: 1 / 5; }
.faq__head h2 { margin-top: 1.2rem; }
.faq__list { grid-column: 6 / -1; }

.faq details { border-top: 1px solid var(--hair); }
.faq details:last-of-type { border-bottom: 1px solid var(--hair); }
.faq summary {
  position: relative;
  padding: 1.35rem 2.6rem 1.35rem 0;
  font-family: var(--display);
  font-size: clamp(1.05rem, 0.98rem + 0.42vw, 1.3rem);
  cursor: pointer;
  list-style: none;
  transition: color 0.4s var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after,
.faq summary::before {
  content: "";
  position: absolute;
  right: 0.3rem; top: 50%;
  width: 12px; height: 1px;
  background: var(--champ);
}
.faq summary::before { transform: rotate(90deg); transition: opacity 0.4s var(--ease), transform 0.4s var(--ease); }
.faq details[open] summary::before { opacity: 0; transform: rotate(0); }
.faq summary:hover { color: var(--champ-hi); }
.faq details p { padding-bottom: 1.6rem; max-width: 58ch; font-size: var(--t-small); color: var(--bone-mid); }

/* ============ XV. Бронь ============ */

.booking__body { grid-column: 3 / 11; }
.booking h2 { margin: 1.4rem 0 clamp(2.2rem, calc(var(--vh, 1svh) * 5), 3.2rem); }

.book-form { display: grid; gap: 0; max-width: 560px; }
.book-form input {
  padding: 1.1rem 0;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--hair);
  color: var(--bone);
  font-family: var(--ui);
  font-size: 1.05rem;
  font-weight: 300;
  transition: border-color 0.4s var(--ease);
}
.book-form input::placeholder { color: var(--bone-dim); }
.book-form input:focus { outline: none; border-bottom-color: var(--champ); }
.book-form .btn { margin-top: 2.2rem; justify-self: start; }
.book-form.is-sent .btn { pointer-events: none; }

.booking__note { margin-top: 1.6rem; }

.booking__urge {
  margin-bottom: clamp(2rem, calc(var(--vh, 1svh) * 5), 3rem);
  font-size: clamp(1.05rem, 0.97rem + 0.4vw, 1.28rem);
  color: var(--champ-hi);
}

/* ---- выбор мессенджера ---- */

.book-form__where {
  margin-top: 1.8rem;
  padding: 0;
  border: 0;
}
.book-form__where .label { margin-bottom: 0.9rem; }

.choice { display: flex; flex-wrap: wrap; gap: 0.7rem; }

.choice label {
  position: relative;
  cursor: pointer;
}
/* сам радиопереключатель убираем, но оставляем доступным с клавиатуры */
.choice input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.choice span {
  display: block;
  padding: 0.75rem 1.4rem;
  border: 1px solid var(--hair);
  font-size: var(--t-small);
  color: var(--bone-mid);
  transition: border-color 0.4s var(--ease), color 0.4s var(--ease), background 0.4s var(--ease);
}
.choice label:hover span { border-color: var(--hair-warm); color: var(--bone); }
.choice input:checked + span {
  border-color: var(--champ);
  color: var(--champ-hi);
  background: rgba(216, 185, 143, 0.12);
}
.choice input:focus-visible + span { outline: 2px solid var(--champ-hi); outline-offset: 3px; }

.footer {
  position: relative;
  z-index: var(--z-page);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding: 2.8rem var(--gut);
  background: var(--abyss);
  border-top: 1px solid var(--hair);
}

/* ============ Волосяная линия, которая загорается от руки ============

   Все перечисления на странице свёрстаны строками с линией сверху.
   Красить саму границу при наведении — резко: цвет щёлкает целиком.
   Вместо этого поверх границы кладём золотую линию и раскрываем её
   от левого края. Получается жест, а не подсветка. */

.facts li,
.level,
.sphere,
.deck,
.day,
.included__cols li,
.bill__row,
.faq details { position: relative; }

.facts li::before,
.level::before,
.sphere::before,
.deck::before,
.day::before,
.included__cols li::before,
.bill__row::before,
.faq details::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--champ) 0%, var(--hair-warm) 100%);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.7s var(--ease);
  pointer-events: none;
}

.facts li:hover::before,
.level:hover::before,
.sphere:hover::before,
.deck:hover::before,
.day:hover::before,
.included__cols li:hover::before,
.bill__row:hover::before,
.faq details[open]::before,
.faq details:hover::before { transform: scaleX(1); }

/* ============ Появление ============ */

.reveal { opacity: 0; transform: translateY(24px); transition: opacity 1.1s var(--ease), transform 1.1s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }

/* если внутри блока заголовок и так поднимается по словам, второе
   движение в ту же сторону читается как задержка — оставляем только свет */
.reveal:has(.rise) { transform: none; }

.stagger > * { opacity: 0; transform: translateY(18px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.stagger.is-in > * { opacity: 1; transform: none; }
.stagger.is-in > *:nth-child(1) { transition-delay: 0.05s; }
.stagger.is-in > *:nth-child(2) { transition-delay: 0.14s; }
.stagger.is-in > *:nth-child(3) { transition-delay: 0.23s; }
.stagger.is-in > *:nth-child(4) { transition-delay: 0.32s; }
.stagger.is-in > *:nth-child(5) { transition-delay: 0.41s; }
.stagger.is-in > *:nth-child(6) { transition-delay: 0.50s; }

/* ============ Адаптив ============ */

@media (max-width: 1000px) {
  .master__photo, .master__body,
  .method__head, .levels, .method__note,
  .spheres__head, .spheres__list, .spheres__note,
  .yacht__head, .decks, .stats,
  .included__head, .included__cols,
  .faq__head, .faq__list,
  .scan__body, .sessions__body, .booking__body,
  .manifest__text { grid-column: 1 / -1; }

  .master__photo { max-width: 330px; }
  .sphere { grid-template-columns: 1fr; gap: 1.1rem; }
  .sphere .slide { grid-template-columns: 1fr; gap: 1.1rem; }
  .sphere__after { padding-top: 1.1rem; border-top: 1px solid var(--hair); }
  .level:nth-child(2), .level:nth-child(3), .level:nth-child(4) { padding-left: 0; }
  .hero__lower { grid-template-columns: 1fr; }
  .hero__offer { align-items: flex-start; }
  .included__cols { margin-top: 2rem; }
  .faq__list, .method__note, .spheres__note { margin-top: 2rem; }
}

/* На узком экране горизонтальная лента не работает: карточка шире окна
   не помещается, текст обрезается по краю, а листать вбок внутри
   вертикальной страницы неудобно. Разворачиваем дни в обычный столбец —
   всё читается сразу, ничего не срезано. */
@media (max-width: 900px) {
  .week { min-height: 0; }
  .week__viewport {
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
  .week__track {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
    width: auto;
    transform: none !important;
    /* трансформа здесь нет — снимаем и заявку на отдельный слой,
       иначе композитор до конца жизни страницы держит текстуру под
       колонкой из семи карточек, которая никогда не двигается */
    will-change: auto;
    /* лента лежит вне .wrap, поэтому поля держит сама */
    padding-inline: var(--gut);
  }
  .day {
    width: auto;
    padding: 1.3rem 0 1.5rem;
  }
  .week__progress { display: none; }
}

/* Переходы на телефоне вдвое короче.

   Переходная секция — чистый кадр без единой буквы. На большом экране
   это пауза между главами, и она читается как замысел. На телефоне шесть
   таких секций по calc(var(--vh, 1svh) * 105) давали шесть с лишним экранов подряд, где
   листаешь — и текста просто нет: почти четверть всей страницы. Именно
   это заказчик и увидел как «текста вообще нету».

   Фильм за это время проходит ровно столько же — просто быстрее, а
   кадровому движку скорость ничего не стоит. */
@media (max-width: 700px) {
  .chapter.is-move {
    min-height: calc(var(--move-h, 140) * var(--vh, 1svh));
  }
}

@media (max-width: 620px) {
  .deck { grid-template-columns: 2.6rem 1fr; }
  .facts li { grid-template-columns: 1fr; gap: 0.35rem; }
  .bill__row { grid-template-columns: 1fr; gap: 0.25rem; }
  .manifest__lines span + span { padding-left: 1.2rem; }
  .depth em { padding-left: 1.2rem; }
  .mark { top: clamp(4.5rem, calc(var(--vh, 1svh) * 10), 6rem); }
  /* судовая подпись длиннее экрана — разрешаем перенос */
  .mark .slate { white-space: normal; }
}

/* ============ Появление на телефоне ============

   Весь текст страницы по умолчанию невидим (opacity: 0) и проявляется
   больше секунды: .reveal — 1.1 с, слова заголовка — 1.15 с плюс до 0.5 с
   построчной задержки. На мониторе это работает: страницу листают
   постепенно, блок успевает проявиться, пока доходишь до него глазами.

   На телефоне листают броском. Секция влетает в экран и вылетает из него
   быстрее, чем заканчивается проявление, — и человек видит пустое место
   там, где должен быть текст. Ровно это и означает «листаю, а текста
   вообще нету»: текст на странице есть, но он не успевает появиться.

   Поэтому на пальцевых экранах проявление короткое, ступенчатых задержек
   нет, а заголовки не набираются по словам — они просто есть. */
@media (pointer: coarse) {
  .reveal {
    transform: none;
    transition: opacity 0.32s var(--ease);
  }
  .stagger > * {
    transform: none;
    transition: opacity 0.28s var(--ease);
  }
  .stagger.is-in > * { transition-delay: 0s; }

  .is-split .rise .w > i { transform: none; transition: none; }
  .is-split .rise .w { overflow: visible; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal, .stagger > * { opacity: 1; transform: none; transition: none; }
  .hint__line { animation: none; }
}

/* ============ Промо-ролик ============

   Переделано целиком. Было: огромный заголовок и маленькое видео в узкой
   колонке, вокруг пустой экран, кадр ни с чем не связан.

   Стало: заголовок и хронометраж стоят на одной линейке, как титр перед
   показом, а сам кадр занимает всю ширину полосы. По углам — метки
   видоискателя: тот же волосяной язык, что и во всей вёрстке, но здесь он
   объясняет, что перед тобой именно плёнка.

   Ролик не качается, пока на него не нажали: в разметке лежит только
   кадр-постер, <video> создаётся по клику. */

.promo__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 2rem;
  padding-bottom: clamp(1.2rem, 2.5vw, 1.8rem);
  border-bottom: 1px solid var(--hair);
}
.promo__head h2 { margin-top: 1.1rem; max-width: 18ch; }
.promo__meta { white-space: nowrap; color: var(--champ); }

.promo__frame {
  position: relative;
  margin-top: clamp(1.8rem, calc(var(--vh, 1svh) * 4), 3rem);
  background: var(--deep);
  overflow: hidden;
  cursor: pointer;
}

.promo__frame img,
.promo__frame video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform 1.2s var(--ease), filter 0.8s var(--ease);
}
.promo__frame:hover img { transform: scale(1.03); filter: brightness(1.06); }

/* Когда ролик запущен, постер обязан УЙТИ: иначе видео встаёт под ним и
   блок раздваивается — сверху неподвижный кадр, снизу играющее видео. */
.promo__frame.is-playing .promo__poster { display: none; }
.promo__frame.is-playing { cursor: default; }
.promo__frame.is-playing .promo__corner { opacity: 0; }

/* тень собирает кадр к центру, чтобы кнопка читалась на любом сюжете */
.promo__frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(58% 58% at 50% 50%,
    rgba(2, 5, 11, 0.30) 0%, rgba(2, 5, 11, 0.62) 100%);
  pointer-events: none;
  transition: opacity 0.6s var(--ease);
}
.promo__frame.is-playing::after { opacity: 0; }

/* ---- метки видоискателя по углам ---- */
.promo__corner {
  position: absolute;
  width: clamp(1.4rem, 3vw, 2.2rem);
  height: clamp(1.4rem, 3vw, 2.2rem);
  pointer-events: none;
  opacity: 0.55;
  transition: opacity 0.6s var(--ease), inset 0.6s var(--ease);
}
.promo__corner--tl { top: 1rem; left: 1rem; border-top: 1px solid var(--champ); border-left: 1px solid var(--champ); }
.promo__corner--tr { top: 1rem; right: 1rem; border-top: 1px solid var(--champ); border-right: 1px solid var(--champ); }
.promo__corner--bl { bottom: 1rem; left: 1rem; border-bottom: 1px solid var(--champ); border-left: 1px solid var(--champ); }
.promo__corner--br { bottom: 1rem; right: 1rem; border-bottom: 1px solid var(--champ); border-right: 1px solid var(--champ); }
.promo__frame:hover .promo__corner { opacity: 1; }

.promo__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  cursor: pointer;
  padding: 0;
}
.promo__frame.is-playing .promo__play { display: none; }

/* Кольцо — единственная подсказка «сюда можно нажать», поэтому оно
   заметнее прочих волосяных линий: своя заливка и мягкий ореол. */
.promo__ring {
  grid-area: 1 / 1;
  width: clamp(5rem, 10vw, 7.2rem);
  aspect-ratio: 1;
  border: 1px solid var(--champ);
  border-radius: 50%;
  background: rgba(3, 7, 15, 0.44);
  box-shadow: 0 0 0 1px rgba(216, 185, 143, 0.16),
              0 0 0 14px rgba(216, 185, 143, 0.05),
              0 12px 48px rgba(2, 5, 11, 0.55);
  transition: transform 0.7s var(--ease), background 0.5s var(--ease),
              box-shadow 0.6s var(--ease);
}
.promo__frame:hover .promo__ring,
.promo__play:focus-visible .promo__ring {
  transform: scale(1.09);
  background: rgba(216, 185, 143, 0.22);
  box-shadow: 0 0 0 1px rgba(216, 185, 143, 0.4),
              0 0 0 22px rgba(216, 185, 143, 0.07),
              0 12px 52px rgba(2, 5, 11, 0.6);
}

/* треугольник собран из бордюров: ни картинки, ни шрифта не нужно */
.promo__tri {
  grid-area: 1 / 1;
  width: 0; height: 0;
  margin-left: 0.36em;
  border-left: 1.05rem solid var(--champ-hi);
  border-top: 0.68rem solid transparent;
  border-bottom: 0.68rem solid transparent;
}

.promo__note { margin-top: 1.1rem; }

@media (max-width: 700px) {
  .promo__head { display: block; }
  .promo__meta { display: block; margin-top: 0.9rem; }
  .promo__frame { margin-top: 1.4rem; }
  .promo__corner { width: 1.1rem; height: 1.1rem; }
  .promo__corner--tl, .promo__corner--tr { top: 0.6rem; }
  .promo__corner--bl, .promo__corner--br { bottom: 0.6rem; }
  .promo__corner--tl, .promo__corner--bl { left: 0.6rem; }
  .promo__corner--tr, .promo__corner--br { right: 0.6rem; }
}

/* ---- Ответ формы ----
   Строка под кнопкой говорит правду о том, что произошло с заявкой:
   отправляем, принято или не дошло. Ложного «отправлено» больше нет. */
.book-form__say {
  margin-top: 1rem;
  font-size: var(--t-small);
  line-height: 1.5;
  min-height: 1.5em;              /* место занято заранее — кнопка не прыгает */
  color: var(--bone-dim);
  transition: color 0.4s var(--ease);
}
/* Секция брони — «кадр», а там действует .chapter.is-beat p с цветом на
   весь текст. Поднимаем вес селектора, иначе строка ответа остаётся
   обычной и не отличает «принято» от «не дошло». */
.chapter .book-form__say { color: rgba(240, 232, 218, 0.7); }
.chapter .book-form.is-sent .book-form__say { color: #f2dcb8; }
.chapter .book-form.is-failed .book-form__say { color: #e8a794; }

.book-form.is-sending button[type=submit],
.book-form.is-sent button[type=submit] { pointer-events: none; opacity: 0.72; }
.book-form.is-sent button[type=submit] { border-color: var(--champ); color: var(--champ-hi); }

/* =========================================================
   ТЕЛЕФОН: размеры, при которых страницей можно пользоваться
   Всё в этом блоке — по результатам замеров на живой странице.
   ========================================================= */

@media (max-width: 700px) {
  /* ОТЗЫВЫ. Замер: карточка выходила 240x300 px при исходнике 1000x1250 —
     уменьшение вчетверо. Семнадцать скриншотов переписки превращались в
     цветные пятна, а это единственное социальное доказательство на
     странице. Даём карточке почти всю ширину и оставляем край следующей,
     чтобы было видно: лента продолжается. */
  .carousel--reviews .slide { flex: 0 0 86%; }

  /* СФЕРЫ. Пять историй на блок, а видно было одну: следующая начиналась
     ровно за краем. Показываем её край — тогда понятно, что надо листать. */
  .carousel--spheres .slide { flex: 0 0 88%; }
}

/* Короткий экран: на 360x640 кнопка в герое уезжала на 54 px ниже сгиба, а
   подсказки «листай» не было видно вовсе — первый экран оставался без
   действия. Виноват верхний отступ: clamp брал минимум 8rem, это пятая
   часть окна. */
@media (max-height: 700px) {
  .chapter.is-beat {
    padding-block: clamp(4.5rem, calc(var(--vh, 1svh) * 14), 8rem)
                   clamp(3rem, calc(var(--vh, 1svh) * 8), 5rem);
  }
  .mark { top: clamp(3.4rem, calc(var(--vh, 1svh) * 8), 5rem); }
  .hero__lower { margin-top: clamp(1.2rem, calc(var(--vh, 1svh) * 3), 2rem); }
  .hero__cta { margin-top: 1rem; }
}

/* Кнопка возврата была 29x39 — ниже нормы касания в 44 px */
.totop { min-height: 44px; }
