/* ============================================================
   ZIRYVO — intro curtain
   A word at a time, cut hard, slowing just enough at the end to
   land — then the lockup, which flies into the navigation's brand
   slot and takes the curtain with it.

   The rhythm lives in js/intro.js: an easing curve cannot slow
   down a step, so the timing is written rather than animated.
   ============================================================ */

.intro {
  position: fixed;
  inset: 0;
  /* Above the navigation (90) and everything else on the page. */
  z-index: 200;
  display: grid;
  place-items: center;
  background: var(--bg);
  color: var(--fg);
}
.intro[hidden] { display: none; }

/* While the curtain is up the page behind it must not scroll: the hero
   should be where the visitor expects it when the curtain lifts. */
html.is-intro { overflow: hidden; }

/* The real brand in the navigation stays invisible until the flying
   lockup lands on it, so the swap reads as one continuous object. */
html.is-intro .brand { opacity: 0; }
.brand { transition: opacity 0.3s ease; }

/* ---------------------------------------------------------- the words */
.intro__word {
  grid-area: 1 / 1;
  margin: 0;
  max-width: 90vw;
  text-align: center;
  font-size: clamp(1.8rem, 5.2vw, 3.5rem);
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 1.25;
}
.intro__word.is-gone {
  opacity: 0;
  transform: translateY(-10px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}

/* ---------------------------------------------------------- lockup
   Built to the same proportions as .brand in the navigation — mark
   25px, gap 11px, word 1rem — from one length. That is what makes the
   flight a plain uniform scale rather than a guess. */
.intro__lockup {
  grid-area: 1 / 1;
  --mark: clamp(46px, 5vw, 68px);
  display: inline-flex;
  align-items: center;
  gap: calc(var(--mark) * 11 / 25);
  opacity: 0;
  will-change: transform, opacity;
  /* The flight's transition has to exist BEFORE the transform changes,
     or the browser has no starting value and the lockup teleports into
     the navigation instead of travelling there. --ease arrives too
     abruptly for a move of this size; this curve leaves and lands with
     the same weight. */
  transition: transform 0.95s cubic-bezier(0.45, 0, 0.15, 1), opacity 0.5s ease;
}
.intro__lockup.is-in { animation: intro-lock 0.75s var(--ease) forwards; }

.intro__mark { height: var(--mark); width: auto; display: block; }

.intro__name {
  font-size: calc(var(--mark) * 16 / 25);
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
}

@keyframes intro-lock {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------- exit */
/* The handover is the one moment the visitor is asked to watch rather
   than read, so it is the slowest thing here: the lockup travels into
   the navigation's slot, and only once it has landed does the curtain
   dissolve. js/intro.js writes the transform, having first pinned the
   entrance's end state as the starting point. */
.intro.is-flying .intro__lockup { animation: none; opacity: 1; }

.intro { transition: opacity 0.75s cubic-bezier(0.4, 0, 0.2, 1); }
.intro.is-lifting { opacity: 0; }
.intro.is-lifting .intro__lockup { opacity: 0; }

/* Skipped intro (already seen this session, or a deep link): no motion,
   no curtain, nothing to wait for. */
.intro.is-instant, .intro.is-instant * { animation: none !important; transition: none !important; }

/* ---------------------------------------------------------- failsafe
   If the script never runs the curtain must still go away. This fires
   well after the normal exit and only matters when something broke. */
.intro { animation: intro-failsafe 0s linear 6s forwards; }
@keyframes intro-failsafe {
  to { opacity: 0; visibility: hidden; pointer-events: none; }
}

/* ---------------------------------------------------------- motion
   Flashing words are exactly what a reduced-motion setting is asking us
   not to do: the name appears, and that is the whole curtain. */
@media (prefers-reduced-motion: reduce) {
  .intro__word { display: none; }
  .intro__lockup { opacity: 1; animation: none; }
  .intro.is-flying .intro__lockup { transition: none; transform: none; }
  .intro.is-lifting { transition: opacity 0.2s linear; }
}
