/* ============================================================================
   site/intro.css — заставка входа на главной (механика — site/intro.js).

   Три класса на <html>, все ставит синхронный скрипт в шапке, до первой
   отрисовки (иначе на долю секунды мелькнула бы страница):
     intro-show   — заставка на экране;
     intro-on     — страница заперта: колесо и палец её не двигают;
     intro-reveal — герой в «исходной» позе, из которой он проявится.
   intro.js добавляет intro-go (поехали) и снимает всё по окончании.

   Прокрутку запираем overflow:hidden, а место полосы прокрутки держим
   scrollbar-gutter — иначе на снятии замка вся страница съехала бы вбок на
   ширину полосы.

   Движение только transform/opacity/clip-path: в эти секунды главный поток
   занят сборкой страницы, а такие переходы видеокарта ведёт сама.
   ========================================================================== */

.intro{ display:none }
html.intro-on{ overflow:hidden; scrollbar-gutter:stable }
html.intro-on body{ overflow:hidden }

.intro-show .intro{
  --q:0;
  position:fixed; inset:0; z-index:300;
  display:grid;
  grid-template-columns:1fr auto;
  grid-template-rows:auto minmax(0,1fr) auto;
  grid-template-areas:"brand brand" "van van" "num say";
  align-items:end; column-gap:24px;
  padding:clamp(16px,2.2vw,30px) clamp(18px,3.2vw,52px) clamp(20px,3.4vw,46px);
  background:var(--bg,#0E1A16);
  color:var(--ink,#EAF3EF);
  /* Эллипс, висящий от верхней кромки: по ширине 100 %, по высоте с
     запасом на нижние углы. Уход — высота в ноль: низ занавеса поднимается
     дугой, середина отстаёт от краёв (приём меню landonorris.com). */
  clip-path:ellipse(100% 132% at 50% 0%);
  pointer-events:auto;
}

.intro-brand{
  grid-area:brand; align-self:start; justify-self:start;
  display:flex; align-items:center; gap:10px; margin:0;
  font:800 17px/1 Unbounded, system-ui, sans-serif; letter-spacing:.02em;
}
.intro-brand img{ width:44px; height:auto; display:block }

/* Фургон: ширина — по экрану, но не выше свободной середины (на широком
   и низком окне каркас иначе упирался бы в счётчик). 2.126 — пропорция
   картинки 1280 × 602. */
.intro-van{
  grid-area:van; place-self:center; position:relative;
  width:min(84vw, 1180px, calc((100svh - 230px) * 2.126));
  aspect-ratio:1280 / 602;
}
.intro-van img{ position:absolute; inset:0; width:100%; height:100%; display:block }
/* Весь силуэт намёком с первого кадра — сканер «проявляет» то, что уже
   угадывается, а не рисует из пустоты. */
.intro-ghost{ opacity:.09 }

/* Проявление и луч — ТОЛЬКО transform с переходом. Долю --q intro.js ставит
   раз в ~100 мс, а едет её видеокарта: в эти секунды главный поток занят
   сборкой страницы (стена поставщиков заливает текстуры), и луч, который
   двигал бы скрипт каждый кадр, дёргался бы вместе с ним.
   Окно — коробка, уехавшая влево на (1 − q), и картинка в ней, уехавшая
   на столько же вправо: вместе картинка стоит на месте, а край окна идёт. */
.intro-box,
.intro-scan{
  position:absolute; inset:0;
  transform:translateX(calc((var(--q, 0) - 1) * 100%));
  transition:transform .3s linear; will-change:transform;
}
.intro-box{ overflow:hidden }
.intro-wire{
  transform:translateX(calc((1 - var(--q, 0)) * 100%));
  transition:transform .3s linear; will-change:transform;
}

/* Луч сканера — правая кромка окна — и мягкий шлейф за ним. */
.intro-scan{ top:-5%; bottom:-5%; pointer-events:none }
.intro-scan::after{
  content:""; position:absolute; top:0; bottom:0; right:-1px; width:2px;
  background:linear-gradient(to bottom, transparent, var(--blue,#8FE3C4) 16%, var(--blue,#8FE3C4) 84%, transparent);
  box-shadow:0 0 16px 1px rgba(143,227,196,.55), 0 0 56px 6px rgba(143,227,196,.16);
}
.intro-scan::before{
  content:""; position:absolute; top:5%; bottom:5%; right:1px;
  width:clamp(36px,7vw,130px);
  background:linear-gradient(to left, rgba(143,227,196,.14), transparent);
}

.intro-n{
  grid-area:num; margin:0;
  font:700 clamp(54px,8.6vw,144px)/.84 Unbounded, system-ui, sans-serif;
  letter-spacing:-.045em; font-variant-numeric:tabular-nums;
}
.intro-n i{ font-style:normal; font-size:.32em; letter-spacing:0;
  color:var(--blue,#8FE3C4); margin-left:.14em; vertical-align:top }

.intro-say{
  grid-area:say; justify-self:end; margin:0 0 .5em; max-width:30ch; text-align:right;
  font:600 12px/1.5 Manrope, system-ui, sans-serif; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted,#A7BCB4);
}
.intro-say [lang]{ display:none }
html:not([data-intro-lang]) .intro-say [lang="ru"],
html[data-intro-lang="ru"] .intro-say [lang="ru"],
html[data-intro-lang="uz"] .intro-say [lang="uz"],
html[data-intro-lang="en"] .intro-say [lang="en"]{ display:inline }

/* ── уход ──────────────────────────────────────────────────────────────── */
.intro.is-done .intro-scan{ opacity:0; transition:opacity .3s }
.intro.is-done .intro-van{
  scale:1.04; opacity:0;
  transition:scale 1s cubic-bezier(.165,.84,.44,1), opacity .55s .12s;
}
.intro.is-done .intro-n,
.intro.is-done .intro-say,
.intro.is-done .intro-brand{
  translate:0 14px; opacity:0;
  transition:translate .45s cubic-bezier(.55,.055,.675,.19), opacity .35s;
}
.intro.is-out{
  clip-path:ellipse(100% 0% at 50% 0%);
  transition:clip-path 1s cubic-bezier(.645,.045,.355,1);
  pointer-events:none;
}

/* ── герой проявляется из-под занавеса ───────────────────────────────────
   Кадр наезжает с 1.12 до 1, реплика поднимается строками, пункты шапки
   спускаются по очереди. Отдельные свойства scale/translate: transform у
   этих узлов ведут другие (film.js — реплику, main.js — шапку). */
.intro-reveal .film-poster,
.intro-reveal .film-canvas{ scale:1.12 }
.intro-reveal .beat-1 .beat-copy > *{ opacity:0; translate:0 34px }
.intro-reveal .hdr-in > *{ opacity:0; translate:0 -14px }

.intro-go .film-poster,
.intro-go .film-canvas{ scale:1; transition:scale 1.6s cubic-bezier(.165,.84,.44,1) }
.intro-go .beat-1 .beat-copy > *{
  opacity:1; translate:0 0;
  transition:opacity .8s cubic-bezier(.215,.61,.355,1), translate 1.1s cubic-bezier(.165,.84,.44,1);
}
.intro-go .beat-1 .beat-copy > :nth-child(1){ transition-delay:.28s }
.intro-go .beat-1 .beat-copy > :nth-child(2){ transition-delay:.38s }
.intro-go .beat-1 .beat-copy > :nth-child(3){ transition-delay:.5s }
.intro-go .hdr-in > *{
  opacity:1; translate:0 0;
  transition:opacity .6s cubic-bezier(.215,.61,.355,1), translate .8s cubic-bezier(.165,.84,.44,1);
}
.intro-go .hdr-in > :nth-child(1){ transition-delay:.35s }
.intro-go .hdr-in > :nth-child(2){ transition-delay:.42s }
.intro-go .hdr-in > :nth-child(3){ transition-delay:.49s }
.intro-go .hdr-in > :nth-child(4){ transition-delay:.56s }
/* Пятый — язык: между кнопкой и языком теперь стоит «Меню» телефона
   (на мониторе оно скрыто, но место в очереди занимает). */
.intro-go .hdr-in > :nth-child(5){ transition-delay:.63s }

@media (max-width:640px){
  .intro-show .intro{
    grid-template-columns:1fr;
    grid-template-areas:"brand" "van" "say" "num";
    grid-template-rows:auto minmax(0,1fr) auto auto;
    row-gap:14px;
  }
  .intro-van{ width:min(92vw, calc((100svh - 260px) * 2.126)) }
  .intro-say{ justify-self:start; text-align:left; margin:0 }
}

/* Для тех, кто просил меньше движения, заставки нет (её не ставит шапка);
   правило — страховка, если класс всё же оказался на месте. */
@media (prefers-reduced-motion: reduce){
  .intro-show .intro{ display:none }
  html.intro-on, html.intro-on body{ overflow:visible }
}
@media print{ .intro-show .intro{ display:none } }
