/* ─────────────────────────────────────────────────────────────
   APE CITY — opening sequence (from Apereveal)
   A CRT-scanline backdrop over the map: ". . . LOADING . . ." types on and pulses while the city is built,
   the Hood ape fades in, the APE CITY title writes on and wipes off (Lottie), the ape returns to centre and
   waits there over "Tap to enter", and on that tap the whole overlay fades away to the city seen from straight above, as the camera swings down into the
   default view (bag-map.js). Driven by js/intro.js.
   ───────────────────────────────────────────────────────────── */
#ape-intro {
  --bg: #07040d;
  --paint: #ccff00;
  --glow: 157, 77, 255;
  --phosphor: 196, 156, 255;
  /* The one glow shared by the title, the ape logo and "Loading": a faint lime halo hugging the shape,
     a purple glow, and a wide light spill. */
  --neon-glow:
    drop-shadow(0 0 3px rgba(204, 255, 0, 0.35))
    drop-shadow(0 0 10px rgba(var(--glow), 0.38))
    drop-shadow(0 0 30px rgba(var(--glow), 0.24))
    drop-shadow(0 0 90px rgba(var(--glow), 0.26));

  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: radial-gradient(ellipse 90% 80% at 50% 46%, #150926 0%, #10071d 45%, var(--bg) 100%);
}
#ape-intro *, #ape-intro *::before, #ape-intro *::after { box-sizing: border-box; }

/* Exit: the scanline backdrop and everything on it fade away to reveal the city underneath
   (the ape logo fades a touch faster, see .is-exiting .hood-ape below). */
#ape-intro.is-exiting {
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.6s ease-in-out 0.25s;
}

/* ---- CRT scanline backdrop --------------------------------------------- */
#ape-intro .crt,
#ape-intro .crt > * {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
#ape-intro .crt { overflow: hidden; }

/* 3px raster: a faint phosphor line, a gap, a dark line. Strongest in the lit centre, fading out toward the edges. */
#ape-intro .crt__lines {
  background: repeating-linear-gradient(
    to bottom,
    rgba(var(--phosphor), 0.06) 0 1px,
    transparent 1px 2px,
    rgba(0, 0, 0, 0.34) 2px 3px
  );
  -webkit-mask-image: radial-gradient(ellipse 80% 75% at 50% 46%, #000 0%, rgba(0, 0, 0, 0.6) 55%, rgba(0, 0, 0, 0.2) 100%);
  mask-image: radial-gradient(ellipse 80% 75% at 50% 46%, #000 0%, rgba(0, 0, 0, 0.6) 55%, rgba(0, 0, 0, 0.2) 100%);
  animation: ape-phosphor 7s ease-in-out infinite;
}

/* A slow refresh beam rolling down the screen: a soft wash with a thin bright leading edge. */
#ape-intro .crt__sweep {
  inset: auto 0 auto 0;
  top: 0;
  height: 42vh;
  background:
    linear-gradient(to bottom, transparent 90%, rgba(var(--phosphor), 0.14) 90%, rgba(var(--phosphor), 0.14) calc(90% + 1px), transparent calc(90% + 1px)),
    linear-gradient(to bottom, rgba(var(--glow), 0) 0%, rgba(var(--glow), 0.03) 55%, rgba(var(--phosphor), 0.07) 90%, rgba(var(--phosphor), 0) 100%);
  mix-blend-mode: screen;
  filter: blur(0.6px);
  transform: translate3d(0, -40vh, 0);
  will-change: transform;
  animation: ape-sweep 9s cubic-bezier(0.45, 0, 0.4, 1) infinite;
}

/* Fine film grain, jittered so it shimmers instead of sitting still. */
#ape-intro .crt__grain {
  inset: -50%;
  opacity: 0.07;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  will-change: transform;
  animation: ape-grain 0.9s steps(6) infinite;
}

#ape-intro .crt__vignette {
  background:
    radial-gradient(ellipse 90% 85% at 50% 46%, transparent 55%, rgba(2, 1, 6, 0.75) 100%),
    linear-gradient(to bottom, rgba(2, 1, 6, 0.35), transparent 14%, transparent 86%, rgba(2, 1, 6, 0.35));
}

@keyframes ape-sweep {
  0%        { transform: translate3d(0, -40vh, 0); }
  62%, 100% { transform: translate3d(0, 104vh, 0); }
}
@keyframes ape-phosphor {
  0%, 100% { opacity: 1; }
  48%      { opacity: 0.86; }
  52%      { opacity: 0.94; }
}
@keyframes ape-grain {
  0%   { transform: translate3d(0, 0, 0); }
  17%  { transform: translate3d(-4%, 3%, 0); }
  33%  { transform: translate3d(3%, -5%, 0); }
  50%  { transform: translate3d(-6%, -2%, 0); }
  67%  { transform: translate3d(5%, 4%, 0); }
  83%  { transform: translate3d(-2%, 6%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* ---- Lockup ------------------------------------------------------------ */
/* The 1920x1080 comp is mostly empty margin (the title is ~62% of its width), so the stage is sized by what
   the title needs: 1100px on desktop; 134vw on narrow screens (the title fills ~83% of the width, the empty
   comp margins overflow off-screen harmlessly); never more than 204vh (the lockup stays on screen). */
#ape-intro .canvas-viewport {
  position: relative;
  flex: none;
  width: min(1100px, 134vw, 204vh);
  aspect-ratio: 16 / 9;
  container-type: inline-size;
}

#ape-intro #lottie-stage {
  width: 100%;
  height: 100%;
  transform: translate3d(0, 0, 0);
  will-change: transform;
  /* The glow comes from the revealed pixels, so it builds up as the title is written and fades as it's erased. */
  filter: var(--neon-glow);
}
#ape-intro #lottie-stage svg {
  display: block;
  overflow: visible;
}

/* Choreography (driven by js/intro.js). The ape logo and "Loading" are their own layers, moved only with
   transform/opacity so the motion runs on the GPU and stays smooth while the city is being built.
   Offsets are in cqw (1cqw = 1% of the stage width), set from JS.
     start         "Loading" alone, just below the middle
     .show-hood    the ape logo fades in right above it
     .is-open      the ape glides up and stays; "Loading" drifts down and fades
     .is-centered  once the title has wiped off, the ape returns to centre */
#ape-intro .hood-slot {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: translate3d(0, var(--hood-drop, 0), 0);
  transition: transform 1.2s cubic-bezier(0.65, 0, 0.35, 1);
  will-change: transform;
}
#ape-intro .is-open .hood-slot { transform: translate3d(0, 0, 0); }
#ape-intro .is-centered .hood-slot { transform: translate3d(0, var(--hood-center, 0), 0); }

#ape-intro .hood-ape {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transform: scale(0.95);
  transform-origin: 50% var(--hood-origin-y, 50%);
  transition:
    opacity 1s ease-out,
    transform 1.4s cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: transform, opacity;
  filter: var(--neon-glow);
}
#ape-intro .show-hood .hood-ape { opacity: 1; transform: none; }
#ape-intro.is-exiting .hood-ape {
  opacity: 0;
  transform: scale(1.04);
  transition:
    opacity 1s ease-in,
    transform 1.4s ease-in;
}

#ape-intro .loading {
  position: absolute;
  left: 0;
  right: 0;
  top: 80%;
  margin: 0;
  transform: translate3d(0, calc(-50% + var(--loading-lift, 0)), 0);
  transition:
    transform 1.2s cubic-bezier(0.65, 0, 0.35, 1),
    opacity 0.9s ease-in 0.15s;
  will-change: transform, opacity;
  text-align: center;
  white-space: pre;
  /* The "THE HOOD" heading font, with the same glow as the art. */
  font-family: "Teko", system-ui, sans-serif;
  font-weight: 600;
  font-size: 5cqw;
  line-height: 1;
  letter-spacing: 0.1em;
  color: var(--paint);
  filter: var(--neon-glow);
}
/* Gentle pulse while the city is built (opacity only, so it keeps running smoothly while that work is busy). */
#ape-intro .loading.is-waiting { animation: ape-breathe 1.6s ease-in-out infinite; }
@keyframes ape-breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}
#ape-intro .is-open .loading { transform: translate3d(0, -50%, 0); opacity: 0; }
#ape-intro .loading span { visibility: hidden; }
#ape-intro .loading span.is-on { visibility: visible; }

/* ---- Tap to enter: under the centred ape, in the Loading line's type, breathing until it is pressed ---- */
#ape-intro.is-awaiting { cursor: pointer; }
#ape-intro .enter {
  position: absolute;
  left: 50%;
  top: 72%;
  transform: translate3d(-50%, 0.6cqw, 0);
  margin: 0;
  padding: 0.6cqw 1.6cqw;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: "Teko", system-ui, sans-serif;
  font-weight: 600;
  font-size: 3.2cqw;
  line-height: 1;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--paint);
  filter: var(--neon-glow);
  opacity: 0;
  transition: opacity 0.9s ease-out, transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: transform, opacity;
}
#ape-intro .enter.is-on { opacity: 1; transform: translate3d(-50%, 0, 0); animation: ape-breathe 2s ease-in-out 0.9s infinite; }
#ape-intro .enter:focus { outline: none; }
#ape-intro .enter:focus-visible { outline: 1px solid rgba(204, 255, 0, 0.6); outline-offset: 0.4cqw; }
/* narrow screens: the stage is wider than the screen, so keep the prompt a readable size */
@media (max-width: 700px) { #ape-intro .enter { font-size: max(3.2cqw, 22px); } }

/* ---- The map's own HUD waits for the camera to come down, then fades in ---- */
body.intro-chrome-off > :not(#map):not(#ape-intro):not(script):not(svg[width="0"]) {
  opacity: 0 !important;
  pointer-events: none !important;
}
body.intro-chrome-in > :not(#map):not(#ape-intro):not(script):not(svg[width="0"]) {
  transition: opacity 1.4s ease !important;
}

@media (prefers-reduced-motion: reduce) {
  #ape-intro .crt__lines,
  #ape-intro .crt__grain { animation: none; }
  #ape-intro .hood-slot,
  #ape-intro .hood-ape,
  #ape-intro .loading,
  #ape-intro .enter { transition-duration: 0.01s; }
  #ape-intro .enter.is-on { animation: none; }
  #ape-intro .loading.is-waiting { animation: none; }
  #ape-intro .crt__sweep { display: none; }
}
