/* ==========================================================================
   Intro — the verse, the ember and the fire that uncovers the landing page

   Ported from `intro-prototype.html`, PART 2 only. PART 1 of that file is a
   stand-in copy of an older front page and is not used: the fire uncovers the
   real landing page underneath.

   Every rule is scoped to #intro / #intro-fire, both of which intro.js creates
   and then removes. Nothing here selects an existing app element, and no app
   rule is overridden -- except `html.intro-lock`, which holds the page still
   while the intro plays and is dropped the moment the fire finishes.

   Stacking: the intro owns z 1000-1001, above everything the app and Ember use
   (Ember 90-96, Bridge modal 200), so it really is in front of the page.
   ========================================================================== */

/* The page behind does not scroll while the intro is up, and the dark ground
   is in place from the very first paint.

   intro.js runs from <head>, so it sets `intro-lock` before the browser has
   painted anything, but it can only build the overlay once <body> exists. In
   that window the page is held invisible -- otherwise the landing page paints
   and flashes (measured: first paint 964 ms, intro script 2270 ms, on a CPU
   throttled 8x). `intro-ready` is set the moment the overlay is in the DOM, and
   a 3 s safety timer sets it anyway, so a failure can never leave a blank page. */
html.intro-lock { overflow: hidden; background: #05030a; }
html.intro-lock:not(.intro-ready) body { visibility: hidden; }
/* once the fire starts, the page's own background must show through the burn */
html.intro-lock.intro-fire { background: none; }

#intro {
  /* Text palette. Gold ink, and the flash that runs through the glowing words
     is RED, so the verse looks lit from within by the fire that is coming. */
  --iv-ink: #e7bd52;                 /* gold leaf */
  --iv-ink-dim: #b98f36;             /* gold in shadow, for the fall-in */
  --iv-flash: #ff3a1e;               /* colour a glowing word flashes to */
  --iv-flash-glow: 255, 64, 26;      /* rgb of that flash's halo */
  --iv-halo: 255, 170, 70;           /* rgb of the halo when a letter is touched */
  --iv-heat: #ffa447;                /* colour a letter turns as the fire reaches it */
  --iv-mote: #ffdf9a;                /* drifting dust */
  /* Cardo is already loaded by the app and is an old-style serif; the
     prototype's IM Fell is not available here and is not worth another
     web-font request for six seconds of animation. */
  --iv-serif: 'Cardo', 'Palatino Linotype', Palatino, 'Iowan Old Style', Georgia, serif;

  position: fixed;
  inset: 0;
  z-index: 1000;
  overflow: hidden;
  isolation: isolate;
  color: var(--iv-ink);
  font-family: var(--iv-serif);

  /* the scene's ground: a light source above, everything below it dark */
  background:
    radial-gradient(circle at 50% 8%, rgba(255,105,24,.15), transparent 32%),
    radial-gradient(circle at 50% 0%, rgba(255,205,115,.10), transparent 18%),
    #05030a;
}

/* the soft glow along the top edge, drawn by script */
.intro__atmosphere {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

/* the shaft of light the verse falls through, brightened as each line lands */
.intro__shaft {
  position: absolute;
  left: 50%;
  top: -6vh;
  width: min(120vw, 1400px);
  height: 72vh;
  transform: translateX(-50%);
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(60% 100% at 50% 0%, rgba(255, 216, 140, .16), rgba(255, 170, 70, .05) 45%, transparent 72%);
}

/* ---------- dust falling from above ---------- */
.intro__motes {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}
.intro-mote {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 50%;
  background: var(--iv-mote);
  box-shadow: 0 0 10px 2px var(--iv-mote);
  opacity: 0;
  will-change: transform, opacity;
}

/* ---------- verse + the space the ember stands in ---------- */
.intro__content {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 6vh 6vw 8vh;
}

.intro__verse {
  margin: 0;
  font-weight: 400;
  font-size: clamp(1.6rem, .9rem + 3.7vw, 4.6rem);
  line-height: 1.3;
  letter-spacing: .01em;
  text-align: center;
  visibility: hidden;          /* revealed by the script once the letters are staged */
}

.intro-line { display: block; text-wrap: balance; }
.intro-line + .intro-line { margin-top: .2em; }

.intro-word { display: inline-block; white-space: nowrap; }

.intro-char {
  --shine: 0;   /* 0 -> 1 : the red flash on the glowing words (GSAP)        */
  --spark: 0;   /* 0 -> 1 : halo when a letter is touched (GSAP)             */
  --heat: 0;    /* 0 -> 1 : the fire is about to reach this letter (script)  */
  display: inline-block;
  color: var(--iv-ink);
  color: color-mix(in oklab, var(--iv-heat) calc(var(--heat) * 100%),
           color-mix(in oklab, var(--iv-flash) calc(var(--shine) * 100%), var(--iv-ink)));
  translate: 0 calc(var(--heat) * -9px);
  scale: calc(1 + var(--heat) * .06);
  text-shadow:
    0 0 calc(var(--shine) * 20px) rgba(var(--iv-flash-glow), calc(var(--shine) * .9)),
    0 0 calc(var(--spark) * 22px) rgba(var(--iv-halo), calc(var(--spark) * .9)),
    0 0 calc(var(--heat) * 22px) rgba(255, 96, 20, calc(var(--heat) * .95));
}

/* reserved for the ember, so the verse does not move when the ember appears */
.intro__slot {
  position: relative;
  flex: none;
  width: 100%;
  height: clamp(170px, 26vh, 250px);
  margin-bottom: clamp(12px, 3vh, 32px);
}

/* short screens (a phone held sideways): tighten so verse and ember fit */
@media (max-height: 520px) {
  .intro__content { padding: 4vh 6vw 12vh; }
  .intro__verse { font-size: clamp(1.3rem, .7rem + 3vw, 2.6rem); }
  .intro__slot { height: 140px; margin-bottom: 8px; }
}

/* ---------- the ember (the dormant flame from ember-flame-v6) ---------- */
.intro-ember-glow {
  position: absolute;
  z-index: 4;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
}

.intro-ember-sprite {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
  transform-origin: 50% 100%;
}
.intro-ember-sprite img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}
.intro-ember-particle {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  will-change: transform, opacity;
  z-index: 6;
}

/* invisible button over the flame: mouse, touch and keyboard all land here */
.intro-ember-hit {
  position: absolute;
  z-index: 7;
  padding: 0;
  border: 0;
  border-radius: 14px;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.intro-ember-hit:disabled { pointer-events: none; cursor: default; }
.intro-ember-hit:focus-visible { outline: 2px solid rgba(255, 213, 170, .75); outline-offset: 4px; }

/* ---------- the fire canvas sits above the intro and the landing page ---------- */
#intro-fire {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1001;
  pointer-events: none;
}

@media print {
  #intro, #intro-fire { display: none !important; }
}
