/* =========================================================
   БАЗА

   Родство с лендингом ретрита намеренное: те же две гарнитуры,
   та же рваная шкала кеглей, та же логика «текст лежит НА кадре,
   а не на плашке». Это один бренд, и страницы должны читаться
   как две главы одной книги.

   Разошлись в цвете. У яхты палитра снята с закатных кадров —
   шампань, бирюза лагуны, ночная синь. Здесь основа — ИНДИГО:
   это цвет самого Павла, и страница держится на нём целиком.
   Индиго ушёл не в один акцент, а в саму материю: в подложку, в
   затемнение поля, в вуаль, в волосяные линии. Поэтому даже на
   золотом экране цены страница остаётся индиговой — тёплое пятно
   лежит на холодной основе, а не наоборот.

   Золото осталось ровно на одном: на действии. Кнопка «Записаться»,
   акцент в заголовке, цифра цены. Два цвета, и у каждого своя
   работа — иначе интерфейс дерётся с фоном на каждом экране.
   ========================================================= */

:root {
  /* — поверхности: индиго, а не нейтральная чернота — */
  --void:       #06051c;
  --deep:       #100c38;
  --glass:      rgba(6, 5, 28, 0.72);
  /* Тон, которым притушен весь кадр. Живёт здесь, а не числами по
     файлам: его читают и слои поля, и подложки секций. */
  --ink:        #04031a;

  /* — текст —
     Кость чуть холоднее, чем у яхты: на индиго тёплая бумага
     уходит в грязно-розовый. */
  --bone:       #ece9f6;
  --bone-mid:   rgba(236, 233, 246, 0.86);
  --bone-dim:   rgba(236, 233, 246, 0.80);

  /* — акценты —
     Индиго — структура: линии, рамки, номера, свет вокруг кадров.
     Золото — действие: кнопка, акцент в заголовке, цифра цены.
     Третьего цвета в интерфейсе нет; всё остальное приносит поле. */
  --indigo:     #6c5ce8;
  --indigo-hi:  #a294ff;
  --indigo-dim: rgba(140, 124, 255, 0.34);

  --gold:       #e0b475;
  --gold-hi:    #f7ddb4;
  --bronze:     #9d7345;

  --hair:       rgba(150, 138, 255, 0.17);
  --hair-warm:  rgba(224, 180, 117, 0.30);

  /* — шрифты — */
  --display: "Prata", "Georgia", "Times New Roman", serif;
  --ui:      "Onest", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* — шкала: намеренно рваная, без «средних» размеров — */
  --t-display: clamp(2.5rem, 1.05rem + 5.2vw, 7rem);
  --t-beat:    clamp(2.1rem, 1rem + 4vw, 5.2rem);
  --t-h2:      clamp(1.9rem, 1.1rem + 2.6vw, 3.6rem);
  --t-h3:      clamp(1.12rem, 1rem + 0.55vw, 1.45rem);
  /* Верхние границы подняты. На мониторе 1900 точек колонка в 1240
     занимала две трети экрана, а кегль упирался в потолок 17 px: текст
     выглядел мелким островком посреди фона, и фон забирал внимание
     просто потому, что его было больше. Нижние границы не тронуты —
     на телефоне всё осталось как было. */
  --t-body:    clamp(0.98rem, 0.92rem + 0.3vw, 1.16rem);
  --t-small:   clamp(0.95rem, 0.88rem + 0.36vw, 1.08rem);
  /* 13.1px на телефоне вместо 11.66. Этим кеглем набраны все метки
     разделов, подписи недель и подписи КНОПОК — прописными и с
     разрядкой, то есть на грани разборчивости. */
  --t-label:   clamp(0.82rem, 0.74rem + 0.2vw, 0.86rem);

  /* — ритм — */
  --gut:      clamp(1.4rem, 5vw, 4.5rem);
  /* Было до 9rem сверху и снизу у каждой секции — 288 точек воздуха
     между блоками. На длинной странице это не воздух, а провалы:
     пролистывая, попадаешь на экран, где нет ничего. */
  --pad:      clamp(4rem, 3rem + 4vw, 6.5rem);
  --max:      1420px;
  --max-read: 720px;

  /* — движение — */
  --ease:  cubic-bezier(0.16, 1, 0.3, 1);
  --slow:  cubic-bezier(0.33, 0, 0.12, 1);

  /* — слои — */
  --z-field: 0;
  --z-page:  1;
  --z-rail:  40;
  --z-head:  50;
  --z-load:  90;

  /* Высота шапки нигде не задана числом — её распирает изнутри кнопка.
     Но знать её надо: на эту высоту опускаются переходы по ссылкам,
     иначе кнопка «Записаться» приводит человека под шапку. */
  --btn-h:  46px;
  --head-h: calc(1rem + var(--btn-h) + 1rem);
}

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  /* плавность даёт scroll.js — нативный smooth дрался бы с ним */
  scroll-behavior: auto;
  background: var(--void);
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100%;
  background: transparent;
  /* браузер сам подкручивает позицию, когда содержимое над экраном
     меняет размер, — на длинной странице это читается как «сайт плавает» */
  overflow-anchor: none;
  color: var(--bone);
  font-family: var(--ui);
  font-size: var(--t-body);
  font-weight: 300;
  line-height: 1.68;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video, canvas { display: block; max-width: 100%; }

/* height: auto обязателен, и это не косметика.

   У картинок в разметке проставлены ширина и высота — без них браузер не
   знает, сколько места занять, и страница дёргается при загрузке. Но
   атрибут height приходит в стили как настоящее значение высоты, и тогда
   aspect-ratio не срабатывает вовсе: он подставляет только НЕДОСТАЮЩИЙ
   размер. Портрет получал ширину колонки и полную высоту файла — 380x1250
   вместо 380x475, — а наложения поверх него считались по aspect-ratio и
   обрывались посреди фотографии видимым швом. */
img { height: auto; }

/* ============ Типографика ============ */

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.012em;
  /* Мера в знаках обязательна. Русские слова длинные, и без ограничения
     заголовок на широком мониторе растягивается на всю ширину — глаз
     теряет начало следующей строки. */
  max-width: 19ch;
  text-wrap: balance;
}

h1 { font-size: var(--t-display); }
h2 { font-size: var(--t-h2); max-width: 17ch; }
h3 { font-family: var(--ui); font-size: var(--t-h3); font-weight: 500; line-height: 1.3; max-width: none; }

h1 em, h2 em, .beat em {
  font-style: normal;
  color: var(--gold);
}

p { max-width: 62ch; }

.lead {
  font-size: clamp(1.06rem, 0.98rem + 0.5vw, 1.32rem);
  line-height: 1.58;
  color: var(--bone-mid);
  max-width: 46ch;
}

.small { font-size: var(--t-small); color: var(--bone-dim); }

/* Метка-надпись. Прописные, разрядка, тонкая — работает как подпись
   на архивной фотографии, а не как ярлык. */
.label,
.slate {
  display: inline-block;
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--bone-dim);
}

.slate { color: rgba(239, 234, 244, 0.55); letter-spacing: 0.2em; }

.label--gold { color: var(--gold); }

/* ИМЯ НЕ ЛОМАЕТСЯ ПЕРЕНОСОМ.

   Заказчик 24.08.2026: при любом масштабе в мобильном браузере «Павел»
   не должен оставаться на строке, а «Андреев» уезжать на следующую.
   Масштаб задаёт человек, подобрать под него ширину нельзя — поэтому
   запрет переноса, а не вёрстка на глаз. Вешать на всё подряд не надо:
   длинная строка в nowrap вылезет за экран. Только имена и короткие
   неразрывные пары. */
.nowrap { white-space: nowrap; }

.hair {
  display: block;
  height: 1px;
  background: linear-gradient(90deg, var(--indigo-dim), transparent);
}

/* Выделение текста тоже индиговое: на странице, где всё держится на
   одном цвете, системная синева выглядит чужой заплатой. */
::selection { background: rgba(108, 92, 232, 0.4); color: var(--bone); }

/* ============ Кнопка ============ */

.btn {
  --btn-ink: var(--bone);
  display: inline-flex;
  align-items: center;
  gap: 0.85em;
  min-height: var(--btn-h);
  padding: 0 1.5em;
  border: 1px solid var(--indigo-dim);
  border-radius: 999px;
  background: rgba(6, 5, 28, 0.38);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  color: var(--btn-ink);
  /* главная кнопка страницы: свой кегль, крупнее меток */
  font-size: clamp(0.86rem, 0.8rem + 0.2vw, 0.9rem);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease),
              transform 0.4s var(--ease);
}

/* Заливка выезжает из-под левого края, а не появляется целиком:
   кнопка «наполняется», как индикатор заряда. Это единственная
   анимация наведения на странице, и она про смысл продукта. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, var(--gold), var(--gold-hi));
  transform: translateX(-101%);
  transition: transform 0.55s var(--ease);
}

.btn > * { position: relative; z-index: 1; }

.btn__arrow {
  width: 1.5em;
  height: 1px;
  background: currentColor;
  position: relative;
  transition: width 0.45s var(--ease);
}
.btn__arrow::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  border-top: 1px solid currentColor;
  border-right: 1px solid currentColor;
  transform: translateY(-50%) rotate(45deg);
}

@media (hover: hover) {
  .btn:hover { color: #17110a; border-color: var(--gold); }
  .btn:hover::before { transform: translateX(0); }
  .btn:hover .btn__arrow { width: 2.1em; }
}

.btn:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

/* ГЛАВНОЕ ДЕЙСТВИЕ ЗАЛИТО ВСЕГДА.

   Сначала заливка включалась только там, где нет мыши: на телефоне
   кнопка золотая, на мониторе — рамка, которая наполняется при
   наведении. Но на движущемся поле прозрачная рамка не читается как
   кнопка вообще: рядом с ней всё время что-то светится. Самый важный
   элемент страницы выглядел необязательным ровно там, где на него
   смотрят дольше всего.

   Теперь золотом залиты три кнопки — первый экран, цена и отправка
   заявки. Ghost-вариант остаётся у шапки: она висит поверх кадра всю
   страницу, и вторая золотая плашка на экране была бы лишней. */
.btn--solid { color: #17110a; border-color: var(--gold); }
.btn--solid::before { transform: translateX(0); }

@media (hover: hover) {
  .btn--solid:hover { border-color: var(--gold-hi); }
  .btn--solid:hover::before { filter: brightness(1.07); }
}

/* ============ Появление ============ */

/* Всё, что размечено этими классами, по умолчанию невидимо и
   проявляется скриптом. Страховка от упавшего скрипта — в <head>
   и в <noscript>: см. index.html. */
.reveal {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity 1s var(--ease), transform 1.1s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }

.stagger > * {
  opacity: 0;
  transform: translate3d(0, 22px, 0);
  transition: opacity 0.85s var(--ease), transform 0.95s var(--ease);
}
.stagger.is-in > * { opacity: 1; transform: none; }
.stagger.is-in > *:nth-child(1) { transition-delay: 0.04s; }
.stagger.is-in > *:nth-child(2) { transition-delay: 0.12s; }
.stagger.is-in > *:nth-child(3) { transition-delay: 0.2s; }
.stagger.is-in > *:nth-child(4) { transition-delay: 0.28s; }
.stagger.is-in > *:nth-child(5) { transition-delay: 0.36s; }
.stagger.is-in > *:nth-child(6) { transition-delay: 0.44s; }
.stagger.is-in > *:nth-child(7) { transition-delay: 0.52s; }
.stagger.is-in > *:nth-child(8) { transition-delay: 0.6s; }

/* Заголовок выходит по словам из-под маски. Маска на .w, движение на i —
   иначе overflow резал бы подстрочные элементы букв. */
.is-split .rise .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  /* маска режет по строчной высоте, поэтому строке нужен запас снизу */
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}
.is-split .rise .w > i {
  display: inline-block;
  font-style: inherit;
  transform: translate3d(0, 105%, 0);
  transition: transform 1s var(--slow);
  transition-delay: var(--line-delay, 0s);
}

/* НА ТЕЛЕФОНЕ ПОЯВЛЕНИЕ ДОЛЖНО БЫТЬ КОРОТКИМ.

   Взято с ретрита, где это чинили по жалобе «листаю, а текста вообще
   нет». Пальцем экран проходят за доли секунды, а секундная анимация с
   лесенкой задержек до 0.6 с не успевает: человек долистывает до
   середины блока раньше, чем проявилась первая строка. На широком
   экране колесо идёт медленнее и лесенка читается как задумано.

   Страница стала длиннее (тридцать шесть экранов на телефоне), так что
   быстрых пролистываний будет больше, а не меньше. */
@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; }
}
.is-split .rise.is-in .w > i { transform: none; }

/* Сторож из <head>: если скрипт не поднялся, показываем всё как есть. */
.is-bare .reveal,
.is-bare .stagger > *,
.is-bare .rise .w > i { opacity: 1 !important; transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .stagger > * { opacity: 1; transform: none; transition: none; }
  .btn::before { transition: none; }
}

/* ============ Заставка ============ */

/* Полторы самые дорогие секунды внимания: человек только что нажал на
   рекламу и ещё не знает, куда попал. Поэтому здесь не проценты
   загрузки, а название и суть одной строкой — даже если человек уйдёт,
   он уйдёт, зная, что это было. */
.loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-load);
  display: grid;
  place-content: center;
  gap: 1.1rem;
  justify-items: center;
  background: var(--void);
  transition: opacity 0.9s var(--ease), visibility 0.9s;
}

.loader__name {
  font-family: var(--display);
  font-size: clamp(1.5rem, 1rem + 2.2vw, 2.6rem);
  letter-spacing: 0.01em;
  text-align: center;
}

.loader .slate { text-align: center; }

.loader__bar {
  width: min(220px, 46vw);
  height: 1px;
  background: var(--hair);
  overflow: hidden;
}
.loader__fill {
  display: block;
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--indigo), var(--gold-hi));
  transition: width 0.4s linear;
}

.is-loaded .loader { opacity: 0; visibility: hidden; pointer-events: none; }

/* ============ Шапка ============ */

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-head);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem var(--gut);
  /* Подложка нарочно тает книзу — шапка не должна резать кадр. Но
     верхнюю треть держим плотной: на узком экране под шапку заезжает
     крупный заголовок, и на просвет читались оба слоя разом. */
  background: linear-gradient(180deg,
    rgba(6, 5, 28, 0.92) 0%,
    rgba(6, 5, 28, 0.74) 46%,
    rgba(6, 5, 28, 0) 100%);
  opacity: 0;
  transform: translate3d(0, -100%, 0);
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
  pointer-events: none;
}
.is-header-on .header { opacity: 1; transform: none; pointer-events: auto; }

.header__mark {
  font-family: var(--display);
  font-size: clamp(0.92rem, 0.85rem + 0.4vw, 1.16rem);
  line-height: 1.2;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.header__mark em { font-style: normal; color: var(--gold); }

/* На узком экране кнопка важнее названия: марку прячем, а не жмём. */
@media (max-width: 560px) {
  .header__mark { display: none; }
  .header { justify-content: flex-end; }
}

/* ============ Возврат в начало ============ */

/* Стеклянная пилюля, а не голая надпись. Кнопка висит поверх страницы
   и на длинных главах ложилась прямо на строку текста — читались оба
   слоя сразу и ни один до конца. Подложка отделяет её от содержимого
   как элемент интерфейса. */
.totop {
  position: fixed;
  left: var(--gut);
  bottom: 1.4rem;
  z-index: var(--z-head);
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.6rem 1.05rem 0.6rem 0.8rem;
  border: 1px solid var(--hair);
  border-radius: 999px;
  /* Непрозрачная: на полупрозрачной сквозь кнопку проступал текст,
     и она читалась как брак вёрстки. */
  background: #06051c;
  min-height: 44px;
  font-size: var(--t-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--bone-dim);
  text-decoration: none;
  opacity: 0;
  transform: translate3d(0, 10px, 0);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease), color 0.3s;
  pointer-events: none;
}
.is-deep .totop { opacity: 1; transform: none; pointer-events: auto; }
.totop:hover { color: var(--gold); border-color: var(--hair-warm); }

.totop__arrow {
  width: 1px;
  height: 18px;
  background: currentColor;
  position: relative;
}
.totop__arrow::after {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 6px;
  height: 6px;
  border-top: 1px solid currentColor;
  border-left: 1px solid currentColor;
  transform: translateX(-50%) rotate(45deg);
}

/* Рельс глав и кнопка возврата стоят у одного края и на узком экране
   налезали друг на друга. */
@media (max-width: 900px) {
  /* СПРАВА, А НЕ СЛЕВА. Слева она ложилась ровно на начало каждой
     строки и забирала нажатие себе: под ней оказывался то вопрос
     из списка, то абзац. Подпись не прячем — без неё цель нажатия
     выходит 33px при норме 44. */
  .totop {
    left: auto;
    right: 1rem;
    bottom: 1rem;
    padding: 0.7rem 0.9rem;
    letter-spacing: 0.14em;
  }
}

/* ============ Рельс глав ============ */

.rail {
  position: fixed;
  right: calc(var(--gut) * 0.55);
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  align-items: flex-end;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
  pointer-events: none;
}
.is-past-hero .rail { opacity: 1; pointer-events: auto; }

.rail__item {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  background: none;
  border: 0;
  padding: 0.2rem 0;
  cursor: pointer;
  font-family: var(--ui);
  color: var(--bone-dim);
}

.rail__label {
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateX(6px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
  white-space: nowrap;
}

.rail__tick {
  width: 18px;
  height: 1px;
  background: currentColor;
  opacity: 0.4;
  transition: width 0.4s var(--ease), opacity 0.4s var(--ease), background 0.4s;
}

.rail__item[aria-current="true"] { color: var(--gold); }
.rail__item[aria-current="true"] .rail__tick { width: 30px; opacity: 1; }
.rail__item[aria-current="true"] .rail__label { opacity: 1; transform: none; }

@media (hover: hover) {
  .rail__item:hover .rail__label { opacity: 1; transform: none; }
  .rail__item:hover .rail__tick { width: 30px; opacity: 0.9; }
}

/* Рельс — украшение с пользой, но на узком экране он отнимает поле
   у текста и попадает под большой палец. */
@media (max-width: 900px) {
  .rail { display: none; }
}

/* ============ Служебное ============ */

/* Подпись, которую видит только программа чтения с экрана. Поля формы
   опознаются по плейсхолдеру, а плейсхолдер исчезает при вводе — для
   человека это нормально, для скринридера означает поле без имени. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Сброс * { margin: 0; padding: 0 } рамку у fieldset не снимает. */
fieldset { border: 0; min-width: 0; }
