/* ==========================================================================
   karlovyvary.info — лендинг
   Дизайн-система: «pop-up storybook diorama» (см. DESIGN.md)
   Механика сцены повторяет karlgonsalves.com: CSS 3D-колесо из спрайтов,
   вращаемое скроллом. Разбор оригинала — в README.md.
   ========================================================================== */

:root {
  /* Colors */
  --color-signal-yellow: #ffe600;
  --color-globe-azure: #007fff;
  --color-roof-coral: #ef3b2c;
  --color-charcoal-ink: #333333;
  --color-cloud-white: #ffffff;

  /* Typography */
  --font-display: 'Changa One', Impact, sans-serif; /* переопределяется из locale */
  --font-ui: Arial, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --text-caption: 12px;
  --text-body: 14px;
  --text-subheading: 20px;
  --text-heading-sm: 32px;
  --text-heading: 50px;
  --text-display: 75px;

  /* Spacing */
  --spacing-10: 10px;
  --spacing-20: 20px;
  --spacing-45: 45px;
  --section-gap: 45px;

  /* Radius — единственный радиус системы */
  --radius-full: 1440px;

  /* Геометрия сцены */
  --hotel-h: min(280px, 52vw); /* размер рисунка отеля в шапке контента */
  --wheel-radius: 50vw;   /* радиус «планеты» */
  --item-size: 20vw;      /* сторона квадрата спрайта */
  --spoke-step: 15deg;    /* 24 слота × 15° = 360° */
  --scene-scale: 1;
  /* значения без JS — десктопная композиция; на узких экранах их пересчитает
     fitScene(), иначе верхушка колеса уезжает за край */
  --tilt: 20deg;
  --tilt-lamp: 15deg;
}

/* --------------------------------------------------------------- база --- */

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background-color: var(--color-signal-yellow);
  color: var(--color-charcoal-ink);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Боковое «резиновое» качание: на телефоне страница уезжала вбок от
   горизонтального смаха, хотя прокручивать вбок нечего.

   Никакого overflow-x на html здесь быть не должно: clip лишает html роли
   скролл-контейнера и страница перестаёт прокручиваться вовсе, а hidden делает
   из него контейнер и ломает липкие секции контента. */
html, body { overscroll-behavior-x: none; }

/* Полоса прокрутки не рисуется: страница листается пальцем и колесом, а на
   иллюстрации во весь экран серая планка сбоку выглядит инородно. Прокрутка
   при этом работает как обычно. Побочная польза: без полосы 100vw совпадает с
   шириной содержимого, и фиксированный слой сцены больше не торчит за правый
   край, как это было на десктопе. */
html { scrollbar-width: none; -ms-overflow-style: none; }
::-webkit-scrollbar { width: 0; height: 0; }

img { max-width: 100%; height: auto; }

a { color: inherit; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 2000;
  padding: var(--spacing-10) var(--spacing-20);
  background: var(--color-charcoal-ink);
  color: var(--color-cloud-white);
  text-decoration: none;
}
.skip-link:focus { left: 0; }

:focus-visible {
  outline: 3px solid var(--color-charcoal-ink);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- нав --- */

.nav {
  position: fixed;
  top: 0; left: 0;
  z-index: 1000;
  display: flex;
  width: 100vw;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

.nav__link {
  padding: var(--spacing-10) var(--spacing-20);
  color: var(--color-charcoal-ink);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  font-weight: 400;
  text-decoration: none;
  text-transform: uppercase;
  border-bottom: 0 solid var(--color-charcoal-ink);
}

/* активный пункт — единственный индикатор состояния: подчёркивание 20px */
.nav__link[aria-current='true'] { position: relative; }
.nav__link[aria-current='true']::after {
  content: '';
  position: absolute;
  left: 50%; bottom: 4px;
  width: 20px; height: 2px;
  margin-left: -10px;
  background: var(--color-charcoal-ink);
}

.nav__lang {
  padding: var(--spacing-10);
  font-size: var(--text-caption);
  text-decoration: none;
  text-transform: uppercase;
}

/* ================================================================ СЦЕНА === */
/*
   Иерархия (1:1 с механикой оригинала):
   .scene   — фиксированный слой на весь экран
    └ .camera        perspective
       ├ .axis--world           синий шар, радиус 50vw, центр ниже экрана
       ├ .ring (наклон кольца)  rotateX/Y/Z — «ось планеты»
       │  └ .roll   (скролл)    rotateX(--roll × -360deg)
       │     └ .spoke           rotateX(--i × 15deg) — спица
       │        └ .item         translateY(-50vw) — спрайт стоит на поверхности
*/

.scene {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

.camera {
  position: relative;
  width: 100vw;
  height: 100vh;
  perspective: var(--persp, 75vw);
  transform: scale(var(--scene-scale));
  transform-style: preserve-3d;
}

.axis {
  position: absolute;
  top: 50vh;
  left: 0;
  width: 100vw;
  height: 100vw;
}

/* Река Тепла.
   Два кольца объектов наклонены зеркально (rotateY ±20°, rotateZ ±20°), поэтому
   их верхушки расходятся и между ними образуется долина. Дно этой долины —
   синий круг: это и есть река, по обе стороны которой стоит курортная улица. */
.axis--water {
  border-radius: var(--radius-full);
  background-color: var(--color-globe-azure);
}

/* Каменная набережная: белое кольцо ровно по краю воды, на уровне radius 50vw —
   там же, где стоят основания домов. Внутри border-box, поэтому лежит на воде. */
.axis--quay {
  border: 1.6vw solid var(--color-cloud-white);
  border-radius: var(--radius-full);
  background: transparent;
}

/* Блик на воде — второй, меньший круг. Плоская заливка, без градиента. */
.axis--water::after {
  content: '';
  position: absolute;
  left: 12%;
  top: 26%;
  width: 46%;
  height: 46%;
  border-radius: var(--radius-full);
  background-color: #1a8cff;
}

.ring {
  transform-style: preserve-3d;
}

/* Наклон колец разводит их верхушки в стороны — между ними и получается
   долина с рекой. Величина наклона больше не константа: при большом масштабе
   те же 20° уносят верхушку колеса далеко за левый край экрана, что и
   происходило на телефоне. Угол считает JS так, чтобы разнос верхушек всегда
   составлял ту же долю ширины экрана, что и на десктопе. */
.ring--left        { transform: rotateX(20deg) rotateY(calc(var(--tilt) * -1)) rotateZ(calc(var(--tilt) * -1)); }
.ring--right       { transform: rotateX(20deg) rotateY(var(--tilt))            rotateZ(var(--tilt)); }
.ring--lamps-left  { transform: rotateX(12deg) rotateY(calc(var(--tilt-lamp) * -1)) rotateZ(calc(var(--tilt-lamp) * -1)); }
.ring--lamps-right { transform: rotateX(12deg) rotateY(var(--tilt-lamp))            rotateZ(var(--tilt-lamp)); }
.ring--clouds      { transform: rotateX(-45deg) rotateY(0deg)   rotateZ(-90deg); }
.ring--pages       { transform: none; }

.roll {
  position: absolute;
  inset: 0;
  transform: rotateX(calc(var(--roll, 0) * -360deg));
  transform-style: preserve-3d;
  will-change: transform;
}

/* облака крутятся медленнее — параллакс */
.ring--clouds .roll { transform: rotateX(calc(var(--roll, 0) * -140deg)); }

.spoke {
  position: absolute;
  inset: 0;
  transform: rotateX(calc(var(--i) * var(--spoke-step)));
  transform-style: preserve-3d;
}

/* Множитель подскока объекта на гребне. Регистрируем как настоящее число,
   иначе браузер не умеет его интерполировать и вместо движения будет рывок. */
@property --pop {
  syntax: '<number>';
  inherits: false;
  initial-value: 1;
}

/* спрайт: квадрат 20vw, стоит основанием на окружности радиуса 50vw */
.item {
  position: absolute;
  top: 0;
  left: calc(var(--item-size) / -2);
  width: var(--item-size);
  height: var(--item-size);
  margin-left: 50vw;
  background-image: var(--art);
  background-position: bottom center;
  background-repeat: no-repeat;
  background-size: contain;
  transform: translateY(calc(var(--item-size) * -1)) rotateY(60deg) scale(var(--pop, 1));
  /* рост от основания. Для rotateY это безразлично — ось вертикальная и
     проходит через ту же точку, — а масштаб теперь не отрывает дом от земли. */
  transform-origin: 50% 100%;
  transform-style: preserve-3d;
  /* Спрайты повёрнуты на 60° и в какие-то моменты проходят почти рёбром к
     камере. Без этого браузер перерисовывает их обратную сторону и картинка
     мигает — особенно заметно на телефоне при прокрутке. */
  backface-visibility: hidden;
}

.item--right {
  transform: translateY(calc(var(--item-size) * -1)) rotateY(-60deg) scale(var(--pop, 1));
}

/* Объект, доехавший до верхней точки колеса, коротко подпрыгивает — здания
   как будто здороваются, когда выходят на гребень. Признак ставит JS на ту
   спицу, что сейчас наверху, и снимает, когда её сменяет следующая. */
@keyframes item-pop {
  0%   { --pop: 1; }
  30%  { --pop: 1.3; }
  62%  { --pop: 0.93; }
  82%  { --pop: 1.08; }
  100% { --pop: 1; }
}

.spoke[data-crest] .item {
  animation: item-pop 0.72s cubic-bezier(0.2, 0.85, 0.3, 1);
}

@media (prefers-reduced-motion: reduce) {
  .spoke[data-crest] .item { animation: none; }
}

.item--lamp { --item-size: 14vw; }

.item--cloud {
  --item-size: 16vw;
  left: calc(var(--item-size) / -2 + var(--x, 0vw));
  transform: translateY(-50vw) rotateX(90deg) rotateY(-45deg) rotateZ(90deg);
}

/* Текстовые экраны: плоский слой поверх сцены, вне 3D.
   Внутри preserve-3d текст растрируется в текстуру и мылится — здесь он
   рисуется обычным образом и остаётся чётким. Сменой управляет JS. */
.pages {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  display: grid;
  /* выше линии крыш: там текст пересекается с фасадами меньше всего */
  height: 40vh;
  padding: 0 var(--spacing-20) 2vh;
  align-items: end;
  justify-items: center;
  pointer-events: none;
}

/* Наплыв: текст растёт вместе с прокруткой и уходит за край — тот же эффект
   приближения, что давало 3D-кольцо, но обычным 2D-масштабом, поэтому буквы
   остаются чёткими. Значения --s и --o каждый кадр пишет JS, поэтому никаких
   transition: движение идёт ровно за пальцем. */
.page {
  grid-area: 1 / 1;
  opacity: var(--o, 0);
  transform: scale(var(--s, 1));
  transform-origin: 50% 60%;
  text-align: center;
  will-change: transform, opacity;
}

.page:not([data-active='true']) {
  visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .page { transform: none; }
}

.page__eyebrow {
  display: block;
  margin-bottom: 0.9em;
  color: var(--color-charcoal-ink);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
}

/* Текст едет над сценой и попадает то на жёлтое небо, то на светлые фасады,
   то на синюю воду — одной заливкой все три фона не перекрыть. Решение то же,
   каким нарисована вся графика: плоская заливка плюс тонкий чернильный контур.
   paint-order обязателен — без него обводка рисуется по центру глифа и съедает
   букву; со stroke first она уходит назад, и форма буквы сохраняется. */
.display {
  margin: 0;
  color: var(--color-cloud-white);
  -webkit-text-stroke-color: var(--color-charcoal-ink);
  paint-order: stroke fill;
  font-family: var(--font-display);
  font-weight: 400;
  text-wrap: balance;
}

/* Толщина задаётся на самих строках, а не на .display: em считается от
   собственного кегля элемента, а у .display он наследуется от body (14px),
   и обводка выходила в 1 пиксель вместо четырёх. */
.page .display__big { -webkit-text-stroke-width: 0.08em; }
.page .display__small { -webkit-text-stroke-width: 0.09em; }

.page__eyebrow {
  -webkit-text-stroke: 0.1em var(--color-cloud-white);
  paint-order: stroke fill;
}

.display__big {
  display: block;
  font-size: var(--text-display);
  line-height: 0.72;
}

.display__small {
  display: block;
  font-size: var(--text-heading-sm);
  line-height: 1.15;
}

/* CTA внутри сцены — единственный кликабельный элемент слоя */
.scene__cta {
  position: fixed;
  left: 50%;
  bottom: 12vh;
  z-index: 600;
  transform: translateX(-50%);
  pointer-events: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s linear;
}

.scene__cta[data-visible='true'] { opacity: 1; visibility: visible; }

/* цепочка шагов Longevity */
.chain {
  margin: 0 0 var(--spacing-45);
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.chain__item {
  position: relative;
  padding: 0 0 var(--spacing-45) 68px;
  counter-increment: step;
}

.chain__item::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: -4px;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-full);
  background: var(--color-globe-azure);
  color: var(--color-cloud-white);
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: 48px;
  text-align: center;
}

/* линия, связывающая шаги в один маршрут */
.chain__item:not(:last-child)::after {
  content: '';
  position: absolute;
  left: 23px;
  top: 52px;
  bottom: 12px;
  width: 3px;
  background: var(--color-globe-azure);
}

.chain__item h3 {
  margin: 0 0 6px;
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  font-weight: 400;
  line-height: 1;
}

.chain__item p { margin: 0; max-width: 58ch; }

.chain__note {
  max-width: 52ch;
  margin: 0 auto;
  padding-top: var(--spacing-20);
  border-top: 4px solid var(--color-charcoal-ink);
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: 1.15;
  text-align: center;
}

.scroll-hint {
  position: fixed;
  left: 50%;
  bottom: var(--spacing-20);
  z-index: 600;
  transform: translateX(-50%);
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  pointer-events: none;
  transition: opacity 0.2s linear;
}

/* Подпись объекта, доехавшего до верхней точки колеса.
   Сидит над водой, ниже линии крыш и выше подсказки прокрутки — единственная
   полоса кадра, где ничего не нарисовано. Нажатие уводит к карточке места,
   поэтому это кнопка, а не подпись: цель 44px и видимый фокус. */
.crest-label {
  position: fixed;
  left: 50%;
  bottom: 26vh;
  z-index: 590;
  transform: translateX(-50%) translateY(6px);
  max-width: min(86vw, 420px);
  min-height: 44px;
  padding: 10px 22px;
  border: 2px solid var(--color-charcoal-ink);
  border-radius: var(--radius-full);
  background-color: var(--color-cloud-white);
  color: var(--color-charcoal-ink);
  font-family: inherit;
  font-size: var(--text-body);
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transition: opacity 0.25s linear, transform 0.25s cubic-bezier(0.2, 0.85, 0.3, 1);
}

.crest-label[data-visible='true'] {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.crest-label:hover { background-color: var(--color-signal-yellow); }
.crest-label:focus-visible { outline: 3px solid var(--color-roof-coral); outline-offset: 3px; }

/* «драйвер» скролла: пустая высота, которая крутит колесо */
.scroll-driver { height: 500vh; }

/* --------------------------------------------------------------- кнопки --- */

.btn {
  display: inline-block;
  padding: 14px 28px;
  border: 3px solid var(--color-charcoal-ink);
  border-radius: 0;
  background: var(--color-cloud-white);
  color: var(--color-charcoal-ink);
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;
}

.btn:hover { background: var(--color-signal-yellow); }

.btn--coral {
  background: var(--color-roof-coral);
  color: var(--color-cloud-white);
}
.btn--coral:hover { background: var(--color-charcoal-ink); }

.btn__note {
  display: block;
  margin-top: var(--spacing-10);
  font-family: var(--font-ui);
  font-size: var(--text-caption);
  text-transform: none;
  text-align: center;
}

/* ============================================================= КОНТЕНТ === */

.content {
  position: relative;
  z-index: 10;
  background: none; /* фон живёт на самих блоках — они наезжают друг на друга */
  counter-reset: sect;
}

/* СТОПКА БЛОКОВ. Каждый блок закрепляется, следующий наезжает на него сверху,
   как новая страница поверх старой. Непрозрачный фон обязателен: без него
   закреплённый блок просвечивал бы сквозь наезжающий. */
.content > .section,
.content > .cta-band {
  position: sticky;
  top: var(--sticky-top, 0px);
  background-color: var(--color-signal-yellow);
}

/* Шапка — исключение: её верх до середины отеля прозрачен, сквозь него видна
   сцена с городом и водой, поэтому здание стоит не на глухой плашке, а среди
   панорамы. Жёсткая остановка цвета, не растяжка. */
.content > .hero {
  background-color: transparent;
  background-image: linear-gradient(
    to bottom,
    transparent calc(var(--hotel-h) / 2),
    var(--color-signal-yellow) calc(var(--hotel-h) / 2)
  );
  background-repeat: no-repeat;
}

.section {
  padding: var(--section-gap) var(--spacing-20);
}

.wrap {
  max-width: 1100px;
  margin: 0 auto;
}

/* Заголовок секции: горизонт синего шара, поднимающийся из-под текста.
   Радиус 1440px в этой системе существует, чтобы ВЫРЕЗАТЬ круг из жёлтого
   холста, а не чтобы скруглять карточку: на широком невысоком блоке он давал
   «пилюлю» — форму, которой в системе нет. Круг шире вьюпорта и прижат низом,
   поэтому в кадре видна только его верхняя дуга. */
.section__opener {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  min-height: 44vw;
  margin: 0 calc(var(--spacing-20) * -1) var(--section-gap);
  padding: 9vw var(--spacing-20) 4vw;
  overflow: hidden;
  border-radius: 0;
  background: none;
  counter-increment: sect;
  text-align: center;
}

.section__opener::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 150vw;
  height: 150vw;
  margin-left: -75vw;
  border-radius: var(--radius-full);
  background: var(--color-globe-azure);
}

/* номер секции жёлтым по синему — холст возвращается как акцент */
.section__opener::after {
  content: counter(sect, decimal-leading-zero);
  position: relative;
  order: -1;
  margin-bottom: var(--spacing-20);
  color: var(--color-signal-yellow);
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  letter-spacing: 0.28em;
  text-indent: 0.28em;
}

.section__opener h2 {
  position: relative; /* иначе ::before, как позиционированный, закроет текст */
  max-width: 15ch;
  margin: 0;
  color: var(--color-cloud-white);
  font-family: var(--font-display);
  font-size: var(--text-heading);
  font-weight: 400;
  line-height: 0.82;
  letter-spacing: -0.01em;
  text-wrap: balance; /* лечит рваный перенос в 3 строки */
}

.lead {
  max-width: 62ch;
  margin: 0 auto var(--spacing-45);
  font-size: var(--text-subheading);
  line-height: 1.45;
}

/* Шапка держится в пределах экрана и ЗАКРЕПЛЯЕТСЯ: следующий блок наезжает
   на неё сверху, как новая страница поверх старой. Липкий блок выше экрана
   обрезал бы собственный низ — часть текста стала бы недоступна, поэтому
   закрепление включается только там, где шапка гарантированно помещается. */
.hero {
  --hotel-top: -5vh;
  position: relative;
  padding-top: 0;
  padding-bottom: var(--spacing-20);
  text-align: center;
}


/* Отель на стыке сцены и контента — без подложки: рисунок лежит прямо на
   жёлтом холсте, как и вся графика системы. */
.hero__hotel {
  position: relative;
  display: block;
  width: var(--hotel-h);
  height: var(--hotel-h);
  margin: var(--hotel-top) auto var(--spacing-45);
}

.hero__art {
  position: absolute;
  inset: 0;
  background-image: var(--art);
  background-position: bottom center;
  background-repeat: no-repeat;
  background-size: contain;
  /* растём от основания: здание не должно отрываться от земли */
  transform-origin: 50% 100%;
  will-change: transform;
}

/* Лучи за зданием. Жёсткие остановки цвета в конической заливке дают плоские
   клинья, а не растяжку, — приём остаётся в системе. Лежат отдельным слоем
   под рисунком, потому что у элемента с фоном нет способа положить что-то
   позади собственного фона, не создав путаницы со стековым контекстом. */
.hero__rays {
  position: absolute;
  left: 50%;
  top: 62%;
  width: 230%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: var(--radius-full);
  background: repeating-conic-gradient(
    var(--color-roof-coral) 0deg 5deg,
    transparent 5deg 22deg
  );
  opacity: 0;
  pointer-events: none;
}

/* Выход отеля: выпрыгивает снизу, сильно перелетает нужный размер и качается
   до места — движение книжки-раскладушки. Признак вешает JS, когда здание
   поднялось на треть экрана: сработай оно раньше, приём проходил бы, пока
   рисунок ещё пролетает у нижнего края и на него никто не смотрит. */
@keyframes hotel-pop {
  0%   { transform: translateY(38%) scale(0.5) rotate(-5deg); opacity: 0; }
  38%  { transform: translateY(-5%) scale(1.22) rotate(2deg); opacity: 1; }
  58%  { transform: translateY(2%)  scale(0.88) rotate(-1.5deg); }
  76%  { transform: translateY(0)   scale(1.1)  rotate(0.6deg); }
  90%  { transform: scale(0.96); }
  100% { transform: none; }
}

@keyframes hotel-rays {
  0%   { opacity: 0; scale: 0.15; rotate: -18deg; }
  30%  { opacity: 0.9; }
  100% { opacity: 0; scale: 1.5; rotate: 10deg; }
}

.hero__hotel[data-seen='true'] .hero__art {
  animation: hotel-pop 1.4s cubic-bezier(0.2, 0.9, 0.25, 1) both;
}

.hero__hotel[data-seen='true'] .hero__rays {
  animation: hotel-rays 1.1s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

@media (prefers-reduced-motion: reduce) {
  .hero__hotel[data-seen='true'] .hero__art,
  .hero__hotel[data-seen='true'] .hero__rays { animation: none; }
  .hero__rays { display: none; }
}

.hero__eyebrow {
  margin: 0 0 var(--spacing-20);
  font-family: var(--font-ui);
  font-size: var(--text-body);
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
}

.hero__logo {
  display: block;
  width: 272px;
  max-width: 72vw;
  height: auto;
  margin: 0 auto var(--spacing-20);
}

/* Заголовок мельче: бренд уже держат логотип и надпись над ним, а строка
   длинная — на крупном кегле она разваливалась на три ряда и забивала блок. */
.hero h1 {
  max-width: 28ch;
  margin: 0 auto var(--spacing-20);
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* три программы в строку, разделены коралловой точкой */
.hero__programmes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-10) var(--spacing-20);
  margin: 0 0 var(--spacing-45);
  padding: 0;
  justify-content: center;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  line-height: 1.1;
}

.hero__programmes li { position: relative; }

.hero__programmes li:not(:last-child)::after {
  content: '';
  position: absolute;
  right: calc(var(--spacing-20) / -2 - 4px);
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: var(--radius-full);
  background: var(--color-roof-coral);
}

.hero__claims {
  max-width: 56ch;
  margin: 0 auto var(--spacing-45);
}

.hero__claims p {
  margin: 0 0 var(--spacing-10);
  padding-top: var(--spacing-10);
  border-top: 2px solid var(--color-charcoal-ink);
  font-size: var(--text-subheading);
  line-height: 1.3;
}

.hero__claims p:last-child { margin-bottom: 0; }

/* -------------------------------------------------------------- таблица --- */

.table-wrap { overflow-x: auto; margin-bottom: var(--spacing-45); }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-body);
}

caption {
  padding-bottom: var(--spacing-10);
  font-size: var(--text-caption);
  text-align: start;
}

th, td {
  padding: var(--spacing-10);
  border-bottom: 2px solid var(--color-charcoal-ink);
  text-align: start;
  vertical-align: top;
}

thead th {
  border-bottom-width: 4px;
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  font-weight: 400;
}

td.num {
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- список --- */

.objects { display: grid; gap: var(--spacing-45); }

@media (min-width: 760px) {
  .objects { grid-template-columns: repeat(2, 1fr); gap: var(--spacing-45); }
}

.object { scroll-margin-top: 80px; }

.object__fig {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 180px;
  margin: 0 0 var(--spacing-10);
  background: var(--color-globe-azure);
}

.object__fig img {
  max-height: 160px;
  width: auto;
}

/* Реальная фотография в круглом кадре. Радиус 1440px — та же фигура, что у
   шара сцены и у заголовков секций, поэтому снимок читается как часть
   системы, а не как вставка из другого проекта. */
.object__photo {
  position: relative;
  width: 100%;
  max-width: 320px;
  margin: 0 auto var(--spacing-20);
  aspect-ratio: 1;
  border-radius: var(--radius-full);
  background: var(--color-globe-azure);
}

.object__photo img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--radius-full);
  object-fit: cover;
}

/* Рисунок вместо фото. Круг залит только до середины, выше — прозрачно:
   здание поднимается над линией так же, как в сцене над водой. Заливка задана
   одноцветным градиентом как слоем нужной высоты — визуально это два плоских
   поля с жёстким краем, никакой растяжки цвета. */
.object__photo--art {
  background-color: transparent;
  background-image: linear-gradient(var(--color-globe-azure) 0 0);
  background-repeat: no-repeat;
  background-position: bottom;
  background-size: 100% 50%;
}

/* вписываем целиком и сажаем на нижний край: object-fit: cover срезал бы
   здание по краям, а нам нужен весь силуэт */
.object__photo--art img {
  object-fit: contain;
  object-position: center bottom;
  padding: 6% 8% 0;
}

/* рисованный спрайт того же объекта — меткой на краю кадра */
.object__chip {
  position: absolute;
  left: 2%;
  bottom: 2%;
  width: 32%;
  height: 32%;
  border: 3px solid var(--color-charcoal-ink);
  border-radius: var(--radius-full);
  background-color: var(--color-signal-yellow);
  background-image: var(--art);
  background-position: center 76%;
  background-repeat: no-repeat;
  background-size: 66%;
}

.object__credit {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1.9em;
  font-size: var(--text-caption);
  text-align: center;
}

.object__credit a { color: inherit; }

.objects--photo .object { padding-bottom: var(--spacing-10); }

.footer__photo-note { margin-top: var(--spacing-10); }

.object h3 {
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  font-weight: 400;
  line-height: 1;
}

.object__meta {
  margin: 0 0 var(--spacing-10);
  font-size: var(--text-caption);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.object p { margin: 0; }

/* ---------------------------------------------------------------- шаги --- */

.steps { display: grid; gap: var(--spacing-45); }

@media (min-width: 760px) {
  .steps { grid-template-columns: repeat(3, 1fr); }
}

.step h3 {
  margin: 0 0 var(--spacing-10);
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  font-weight: 400;
  line-height: 1;
}

.step p { margin: 0; }

/* ----------------------------------------------------------------- FAQ --- */

.faq { max-width: 70ch; margin: 0 auto; }

.faq__item { border-top: 2px solid var(--color-charcoal-ink); }
.faq__item:last-child { border-bottom: 2px solid var(--color-charcoal-ink); }

.faq__item summary {
  padding: var(--spacing-20) 0;
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  cursor: pointer;
  list-style: none;
}

.faq__item summary::-webkit-details-marker { display: none; }

.faq__item summary::after {
  content: '+';
  float: inline-end;
  font-size: var(--text-heading-sm);
  line-height: 0.8;
}

.faq__item[open] summary::after { content: '–'; }

.faq__item p { margin: 0 0 var(--spacing-20); }

/* --------------------------------------------------------------- футер --- */

/* Финальный блок — тот же приём, но дуга уходит вверх: круг прижат верхом,
   и полоса читается как обратный горизонт, закрывающий страницу. */
.cta-band {
  position: relative;
  padding: 12vw var(--spacing-20) 9vw;
  overflow: hidden;
  background: none;
  text-align: center;
}

.cta-band::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  width: 150vw;
  height: 150vw;
  margin-left: -75vw;
  border-radius: var(--radius-full);
  background: var(--color-globe-azure);
}

.cta-band > * { position: relative; }

.cta-band h2 {
  margin: 0 auto var(--spacing-20);
  max-width: 16ch;
  color: var(--color-cloud-white);
  font-family: var(--font-display);
  font-size: var(--text-heading);
  font-weight: 400;
  line-height: 0.82;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.cta-band p {
  max-width: 50ch;
  margin: 0 auto var(--spacing-20);
  color: var(--color-cloud-white);
  font-size: var(--text-subheading);
}

.footer {
  padding: var(--section-gap) var(--spacing-20);
  border-top: 4px solid var(--color-charcoal-ink);
  font-size: var(--text-caption);
}

.footer__grid { display: grid; gap: var(--spacing-20); }

@media (min-width: 760px) {
  .footer__grid { grid-template-columns: repeat(3, 1fr); }
}

.footer h2 {
  margin: 0 0 var(--spacing-10);
  font-family: var(--font-display);
  font-size: var(--text-subheading);
  font-weight: 400;
}

.footer ul { margin: 0; padding: 0; list-style: none; }

/* ------------------------------------------------------------ адаптив --- */

@media (max-width: 991px) {
  :root { --scene-scale: 1.25; --text-display: 60px; --text-heading: 40px; }
  .display__big { line-height: 0.75; }
}

@media (max-width: 767px) {
  :root { --scene-scale: 1.375; --text-display: 50px; --text-heading: 32px; --text-heading-sm: 26px; }
  .section__opener { min-height: 60vw; }

  /* Пять экранов прокрутки — это семь-восемь смахиваний до первого текста.
     На телефоне вступление короче: колесо успевает показать себя, но не
     превращается в препятствие перед контентом. */
  .scroll-driver { height: 300vh; }

  .crest-label { bottom: 22vh; font-size: var(--text-caption); padding: 10px 18px; }

  /* Плотность ленты домов.

     Оригинал держит в кадре под семь десятков спрайтов внахлёст, поэтому шара
     за ними почти не видно. У нас объектов всего 26 — это содержание, его не
     придумать, — и на узком экране между ними зияло пустое синее. Раз число
     домов фиксировано, расширяем каждый: лента смыкается и закрывает шар.

     Фонари при этом убираем. На телефоне они мельче спички, разрывают ленту
     светлыми промежутками и стоят четверти всей отрисовки сцены — на плавность
     прокрутки это влияет заметнее, чем на красоту. */
  :root { --item-size: 34vw; }
  .ring--lamps-left, .ring--lamps-right { display: none; }
}

@media (max-width: 479px) {
  :root { --text-display: 40px; --text-heading: 28px; --text-subheading: 17px; }
  .nav__link { padding: 8px 10px; font-size: var(--text-caption); }
}

/* --------------------------------------------- уважение к prefers-motion --- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .scroll-driver { height: 100vh; }

  /* колесо замирает в стартовом положении, страница остаётся читаемой */
  .roll { transform: none !important; }
  .scene__cta { opacity: 1; visibility: visible; }
}

/* печать: сцена не нужна, контент — нужен */
@media print {
  .scene, .scroll-driver, .nav, .scroll-hint { display: none !important; }
  body { background: #fff; }
}
