/* ============================================================
   PARK RESIDENCES — сценарий начала страницы
   Подключается только там, где в разметке есть .intro — это три
   главные страницы ru/en/az. Внутренние страницы файл не тянут.

     .intro
       ├── .hero          «прибитый» экран с роликом
       ├── .intro__reveal следующий экран, наезжает поверх ролика
       │                  ровным горизонтальным краем и тоже прибивается
       └── .intro__rail   пустая рельса: её высота = длина, на
                          которой «окно» раскрывается в полный кадр

   Порядок кадров при прокрутке:
     0 … 1 экран   — .intro__reveal поднимается снизу и закрывает ролик
     далее (rail)  — вертикальное окно разъезжается на весь экран
                     сразу по двум осям, подпись уезжает вверх
     конец rail    — .intro отпускает прокрутку, снизу приходят «Проекты»

   Всё движение — одно свойство clip-path на окне и transform на
   картинке: раскладка при этом не пересчитывается ни разу.
   ============================================================ */

/* Файл подключается только на страницах со сценарием, поэтому токены
   можно держать в :root. */
:root {
  /* высота прибитой шапки после сжатия (.header.is-scrolled = 76px):
     экраны липнут именно к ней, иначе между шапкой и кадром
     появлялась бы белая щель в 16px, как только шапка ужмётся */
  --intro-top: 76px;
}

.intro { position: relative; }

/* ---------- Экран 1: ролик ---------- */
.intro .hero {
  position: sticky;
  top: var(--intro-top);
  z-index: 0;
  /* ровно один экран под шапкой: сюда же прибивается второй экран */
  height: calc(100svh - var(--intro-top));
  min-height: 0;
  /* в покое кадр начинается под полной, ещё не сжатой шапкой */
  margin-top: var(--header-h);
}

/* Подсказка «крутите вниз» — у нижнего края кадра. */
.intro__cue {
  position: absolute; left: 50%; bottom: clamp(18px, 3.4vh, 40px);
  transform: translateX(-50%);
  z-index: 2; pointer-events: none;
  display: flex; flex-direction: column; align-items: center; gap: .7rem;
  color: rgba(255, 255, 255, .92);
  font-family: var(--font-h); font-stretch: var(--hdr-wdth);
  font-size: .62rem; font-weight: 500; letter-spacing: .34em; text-transform: uppercase;
  text-shadow: 0 2px 14px rgba(11, 30, 42, .55);
  opacity: 0; animation: introCueIn 1s var(--ease) 1.6s both;
}
.intro__cue-line {
  position: relative; width: 1px; height: clamp(34px, 5vh, 54px);
  background: rgba(255, 255, 255, .35); overflow: hidden;
}
.intro__cue-line::after {
  content: ""; position: absolute; inset: 0;
  background: #fff; transform-origin: top;
  animation: introCueRun 2.2s var(--ease) infinite;
}
@keyframes introCueIn { to { opacity: 1; } }
@keyframes introCueRun {
  0%   { transform: scaleY(0); transform-origin: top; }
  45%  { transform: scaleY(1); transform-origin: top; }
  55%  { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* ---------- Экран 2: окно ----------
   Ни clip-path, ни overflow на самом sticky-элементе: Chrome в этой
   связке перестаёт перерисовывать слой, как только блок отлипает от
   шапки, и кадр пропадает. Край здесь и так прямой, обрезать нечего. */
.intro__reveal {
  position: sticky;
  top: var(--intro-top);
  z-index: 1;
  /* мост между светлым роликом сверху и тёмной секцией «Проекты» снизу */
  background: linear-gradient(180deg, #b7d3e2 0%, #4a7690 40%, #16323f 76%, var(--ink) 100%);
}
.intro__frame {
  position: relative;
  height: calc(100svh - var(--intro-top));
}

/* ── Окно в проект ───────────────────────────────────────────
   Вертикальный кадр со слегка скруглёнными углами, смещённый вправо:
   слева остаётся чистая колонка под подпись. По мере прокрутки
   раскрывается сразу по двум осям — до полного экрана.
   Стартовые доли продублированы в js/intro.js (WIN_*).

   Два правила, из-за нарушения которых кадр мигал:

   1. Размер меняется настоящими left/top/width/height, а НЕ clip-path.
      clip-path на потомке прибитого блока Chrome местами перестаёт
      перерисовывать — оставался один фон.
   2. У картинки ФИКСИРОВАННЫЙ размер — во весь экран, а не 100% окна.
      Пока она была размером с окно, каждое изменение окна меняло и её
      габариты, и Chrome заново растрировал картинку; на быстрой
      прокрутке он не успевал, и в кадре проступала тёмная подложка.
      Теперь габариты картинки не меняются никогда, а на месте её держит
      transform — это работа композитора, растр остаётся прежним.

   Блок вынесен из потока, внутри одна картинка — пересчёт стоит доли
   миллисекунды. В CSS описано ЗАКРЫТОЕ состояние: не отработает
   скрипт — останется аккуратное окно, а не пустой экран. */
.intro__capsule {
  position: absolute;
  left: 41%; top: 9.5%; width: 35%; height: 81%;
  overflow: hidden;
  border-radius: 12px;
  /* подложка в тон ночного рендера: если кадр на миг не отрисуется,
     подмена не читается как вспышка */
  background: #16242e;
}
.intro__capsule img {
  position: absolute; left: 0; top: 0;
  /* размеры ставит js/intro.js — во весь кадр экрана и больше не трогает;
     100% здесь на случай, если скрипт не отработал */
  width: 100%; height: 100%;
  max-width: none;
  object-fit: cover; object-position: center;
  /* will-change здесь намеренно нет: отдельный слой этой картинке не
     нужен, а лишнее продвижение внутри прибитого блока Chrome отрисовывает
     нестабильно — уже ловили пропадающий кадр. */
}
/* вуаль слева, чтобы подпись читалась поверх раскрывшегося кадра.
   Прозрачность ведёт JS одним числом — без класса и transition,
   иначе на границе срабатывания она моргала при прокрутке вверх. */
.intro__capsule::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(11, 30, 42, .5) 0%, rgba(11, 30, 42, 0) 52%);
  opacity: var(--scrim, 0);
}

/* Постоянная вуаль слева — под подписью, поверх градиента и под окном.
   Нужна, чтобы текст читался, пока окно ещё маленькое. Статичная:
   ни одного пересчёта за кадр. */
.intro__reveal::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(11, 30, 42, .34) 0%, rgba(11, 30, 42, 0) 46%);
}

/* Подпись.
   Здесь НЕ должно быть ни text-shadow с большим размытием, ни
   will-change: раньше стояла тень 30px, и каждый кадр (у подписи
   меняются сдвиг и прозрачность) Chrome заново растрировал текст
   вместе с размытым ореолом. На прокрутке вверх-вниз этот ореол
   над буквами и мерцал. Читаемость теперь держат две вуали:
   .intro__reveal::before поверх градиента и --scrim поверх кадра. */
.intro__caption {
  position: absolute; z-index: 2;
  left: var(--gutter); top: 50%;
  transform: translateY(-50%);
  max-width: min(34vw, 520px);
  color: #fff;
}
.intro__caption-eyebrow {
  display: block; margin-bottom: clamp(.9rem, 1.6vw, 1.5rem);
  font-family: var(--font-h); font-stretch: var(--hdr-wdth);
  font-size: .68rem; font-weight: 600; letter-spacing: .3em; text-transform: uppercase;
  color: rgba(255, 255, 255, .78);
}
.intro__caption-title {
  font-family: var(--font-d);
  font-weight: 300;
  font-size: clamp(2.1rem, 3.9vw, 4.6rem);
  line-height: 1.03;
  letter-spacing: -.01em;
}
.intro__caption-note {
  margin-top: clamp(1rem, 1.8vw, 1.8rem);
  max-width: 30ch;
  font-size: clamp(.9rem, 1.02vw, 1.05rem);
  font-weight: 300;
  color: rgba(255, 255, 255, .82);
}

/* Рельса: не видна и не кликается, нужна только как запас прокрутки,
   на котором раскрывается окно. */
.intro__rail {
  position: relative;
  height: 160svh;
  pointer-events: none;
}

/* «Проекты» приходят поверх раскрытого кадра — своим фоном, ровным
   краем и без щели. */
.intro + .phases {
  position: relative;
  z-index: 2;
  background: var(--ink);
}

/* Низкое окно (ноутбук 13", открытая консоль): подпись центрируется по
   высоте кадра, и на 650px «хвост» примечания уезжал за нижний край. */
@media (max-height: 780px) and (min-width: 981px) {
  .intro__caption-title { font-size: clamp(1.9rem, 3.2vw, 3rem); }
  .intro__caption-note { font-size: .92rem; max-width: 28ch; }
  .intro__caption-eyebrow { margin-bottom: .7rem; }
}

/* ---------- Узкие экраны ----------
   Ролик на телефоне и так не грузится (см. initHeroVideo), а прибитые
   экраны на тач-прокрутке дают дрожание. Поэтому весь сценарий
   выключается: получаются два обычных блока подряд. */
@media (max-width: 980px) {
  .intro .hero {
    position: relative; top: auto; height: auto;
    min-height: min(74svh, 620px);
  }
  .intro__cue { display: none; }
  .intro__reveal {
    position: relative; top: auto;
    padding-block: var(--sect-y);
  }
  .intro__frame {
    height: auto;
    display: flex; flex-direction: column; gap: clamp(1.8rem, 5vw, 3rem);
    padding-inline: var(--gutter);
  }
  /* без сценария раскрытие не нужно: остаётся один обычный кадр */
  .intro__capsule {
    position: relative;
    left: auto; top: auto; width: auto; height: auto;
    order: 2;
    aspect-ratio: 4 / 5;
    border-radius: var(--r);
  }
  .intro__capsule::after { display: none; }
  .intro__reveal::before { display: none; }
  /* вуалей на телефоне нет, а верх градиента светлый — текст тёмный */
  .intro__caption {
    position: relative; left: auto; top: auto; transform: none;
    max-width: none;
    order: 1;
    color: var(--ink);
  }
  .intro__caption-eyebrow { color: var(--tide); }
  .intro__caption-note { color: var(--text-mut); }
  .intro__rail { display: none; }
}

/* ---------- «Уменьшить движение» ----------
   Ни прибивания, ни раскрытия: статичный кадр и подпись. */
@media (prefers-reduced-motion: reduce) {
  .intro .hero { position: relative; top: auto; height: auto; min-height: min(74svh, 620px); }
  .intro__cue { display: none; }
  .intro__reveal { position: relative; top: auto; }
  .intro__reveal::before { display: none; }
  .intro__capsule { left: 0; top: 0; width: 100%; height: 100%; border-radius: 0; }
  .intro__rail { display: none; }
}
