/* =====================================================================
 * Landing intro — full-screen takeover.
 *
 * The intro is NOT a layer over the visible landing page. It is an
 * opaque scene that fully replaces what the visitor sees until the
 * sequence finishes and crossfades out to reveal the settled page.
 *
 *   K1  Surface       — pale sky, wordmark centered, sparkle band low.
 *   K2  Submerging    — water rises through the wordmark, bubbles burst.
 *   K3  Submerged     — water covers viewport, sunrays + tagline appear.
 *   Clear             — .intro fades opacity 1 → 0 (~450ms). Nav fades
 *                       in, water/rays/sky fade out, wordmark + tagline
 *                       + sub stay locked in place (same layout tokens
 *                       as .hero), and the case cards are already sitting
 *                       below the fold ready to scroll to.
 *
 * The overlay is opaque, so anything painted inside it (wordmark,
 * tagline, sub) is what the visitor sees at the last intro frame —
 * the underlying page's identical elements sit at the same viewport
 * y and take over silently on removal.
 *
 * Motion is intro-only. motion.css and ambient.css are untouched.
 * ===================================================================== */


/* -------------------- Overlay shell --------------------
 * Anchored to the body (not to .ocean) so its width tracks body's
 * min-width: 1440 and its horizontal centering matches .page. Height
 * is one viewport since scroll is locked while priming.
 * ---------------------------------------------------------------- */

.intro {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  min-width: var(--layout-max);   /* match body min-width so wordmark centering matches hero */
  height: 100vh;
  z-index: 9999;
  overflow: hidden;
  pointer-events: auto;
  cursor: pointer;
  display: none;
  will-change: opacity;
  /* K1 sky. Pale aquarium tint that reads as "surface." When the
     overlay crossfades out, the visitor sees this fade to the page
     gradient beneath — the "dive resolving" moment.                */
  background: linear-gradient(180deg,
    #e5f3f5 0%,
    #d0e8ea 55%,
    #b8dee0 100%);
}

html.intro-priming .intro { display: block; }


/* -------------------- Water panel --------------------
 * Opaque mid-teal panel, anchored at top:100% (below viewport). JS
 * translates it upward so its top edge crosses the wordmark and
 * exits the top. The sparkle band + waterline strip ride the top
 * edge and rise with the water.
 *
 * z-index: 1 — sits above the sky but BELOW the wordmark in .scene,
 * which is z:3. That means the wordmark stays visually on top of
 * whichever bg is behind it at each y (pale sky above waterline,
 * mid-teal water below), producing the K2 split.
 * ---------------------------------------------------------------- */

.intro__water {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 220vh;
  z-index: 1;
  transform: translate3d(0, 0, 0);
  will-change: transform;
  background: linear-gradient(180deg,
    #7fc4c6 0%,
    #4a9ba4 42%,
    #2e7c90 100%);
}

/* The static SVG wave in the markup is replaced at runtime by
   canvas-drawn sin waves (see intro.js drawFrame). Hide the SVG so
   it doesn't paint alongside — the canvas overlay owns the wave now. */
.intro__wave { display: none; }


/* -------------------- Canvas overlay --------------------
 * Full-viewport canvas created + driven by intro.js. Each frame it
 * clears and redraws: the two-line sin waterline (bright top stroke
 * at sin(s*0.028 + t*1.8)*3 + softer under-stroke offset +4px), the
 * foam that spawns just below the moving surface, the one-shot burst
 * fired at the wordmark crossing, and the sparse ambient bubbles
 * that appear once fully submerged.
 *
 * Sits at z:2 — above the water panel (z:1) so waves + bubbles paint
 * on the mid-teal water, below the ambient clone (z:3) so rays paint
 * above canvas content.
 * ---------------------------------------------------------------- */

.intro__canvas {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  display: block;
}


/* -------------------- Glisten (rising sparkle band) --------------------
 * The intro fetches the REAL /assets/ambient/seabed/glisten.svg,
 * inlines it into .intro__glisten, and tags each <path id="Union_*">
 * with .intro__sparkle. Same graphics, same sizes, same colors as
 * the settled ambient — nothing invented. The two animations below
 * run on each path independently via `transform-box: fill-box`, so
 * each sparkle's transform origin is its own bbox and every path
 * pulses + rotates in place around its authored center.
 *
 * Compared with the settled .kh-seabed-glint treatment in motion.css
 * (scale 0.9↔1.15, opacity 0.55↔1, 5–7s durations), this is bolder:
 * scale 0.6↔1.6, opacity 0.4↔1, 0.8–1.7s durations. It only lasts a
 * couple of seconds so it can be more energetic than the persistent
 * settled version.
 *
 * Per-path durations and negative delays are seeded inline by JS
 * (--pulse-dur, --pulse-delay, --spin-dur, --spin-delay) so the
 * field is desynced from the first frame.
 * ---------------------------------------------------------------- */

.intro__glisten {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -50%);   /* centered on the water top edge */
  width: 108vw;
  max-width: 1620px;
  pointer-events: none;
}

.intro__glisten svg,
.intro__glisten img {
  display: block;
  width: 100%;
  height: auto;
}

.intro__sparkle {
  transform-box: fill-box;
  transform-origin: center center;
  animation:
    intro-sparkle-pulse var(--pulse-dur, 1.2s) var(--pulse-delay, 0s) ease-in-out infinite alternate,
    intro-sparkle-spin  var(--spin-dur,  2.4s) var(--spin-delay,  0s) ease-in-out infinite alternate;
  will-change: transform, opacity;
}

/* Separate individual transform properties per keyframe so pulse
   (scale) and spin (rotate) compose without stomping each other. */
@keyframes intro-sparkle-pulse {
  from { scale: 0.6; opacity: 0.4; }
  to   { scale: 1.6; opacity: 1;   }
}

@keyframes intro-sparkle-spin {
  from { rotate: -20deg; }
  to   { rotate:  20deg; }
}


/* -------------------- Ambient clone host --------------------
 * JS clones the real .ambient element into this container at intro
 * start (see cloneAmbientInto in intro.js), then inline-swaps the
 * clone's <img class="ambient__seabed"> and <img class="ambient__
 * underwater"> to SVG the same way motion.js does on the real
 * ambient, tagging paths with .kh-seabed-glint and wrapping baked
 * ray <rect>s in <g class="kh-ray">. That way the settled ambient
 * animations in motion.css apply to the clone automatically.
 *
 * The host's z-index (2) sits above intro__water (z:1) and below
 * intro__scene (z:3), matching the settled hero's stacking (rays
 * behind wordmark). Its opacity is animated 0 → 1 during K3 by JS
 * and rides the intro's own crossfade to 0 at the end. Teardown
 * removes .intro entirely, which removes this host and everything
 * inside it — no clone left animating in the background.
 * ---------------------------------------------------------------- */

.intro__ambient {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 0;                 /* clone brings its own height (4372px) */
  z-index: 3;
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
}


/* -------------------- Scene (wordmark + tagline + sub) --------------------
 * Mirrors .page + .hero layout so the wordmark, tagline, and sub-
 * line land at the exact same viewport coordinates as their settled
 * counterparts. That guarantees the crossfade at the end doesn't
 * shift them by even a pixel.
 *
 * z-index: 3 — above water. The wordmark itself sits on top of the
 * water panel; the K2 refraction visual comes from the *background*
 * behind the wordmark changing from pale sky above the waterline to
 * mid-teal water below.
 * ---------------------------------------------------------------- */

.intro__scene {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  max-width: var(--layout-max);
  margin: 0 auto;
  padding: calc(var(--nav-h) + var(--hero-pad-y)) var(--hero-pad-x) 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--hero-stack-gap);
  pointer-events: none;
}

.intro__wordmark {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-display-hero);
  letter-spacing: var(--track-wordmark);
  line-height: var(--lh-tight);
  color: var(--ink-title);
  white-space: nowrap;
  margin: 0;
}

.intro__tagline {
  display: flex;
  align-items: center;
  gap: var(--tagline-gap);
  color: var(--ink-tagline);
  white-space: nowrap;
  margin: 0;
  opacity: 0;   /* JS animates to 1 during K3 */
}

.intro__tagline-part {
  font-family: var(--font-line);
  font-weight: 400;
  font-size: var(--fs-title-l);
  line-height: var(--lh-tight);
}

.intro__tagline-chip {
  display: inline-flex;
  align-items: flex-start;
  padding: var(--tagline-chip-pad);
  border-radius: var(--radius-chip-sm);
  background: var(--surface-chip-glass);
  font-family: var(--font-rotator);
  font-weight: 400;
  font-size: var(--fs-title-l);
  line-height: var(--lh-tight);
  color: var(--ink-tagline);
}

.intro__sub {
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: var(--lh-hero-italic);
  letter-spacing: var(--track-hero-italic);
  color: var(--ink-hero-italic);
  text-align: center;
  white-space: nowrap;
  margin: 0;
  opacity: 0;   /* JS animates to var(--opacity-hero-italic) during K3 */
}


/* -------------------- Bubbles --------------------
 * Positioned inline by JS from the intro's own wordmark rect. Sit
 * above the water so bursts read on top of the waterline crossing.
 * ---------------------------------------------------------------- */

.intro__bubbles {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

.intro__bubble {
  position: absolute;
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.3);
  will-change: transform, opacity;
}


/* -------------------- Skip hint -------------------- */

.intro__skip {
  position: absolute;
  z-index: 6;
  left: 0;
  right: 0;
  bottom: 32px;
  margin: 0;
  text-align: center;
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(11, 58, 70, 0.55);
  letter-spacing: 0.4px;
  pointer-events: none;
  user-select: none;
}


/* -------------------- Scroll lock --------------------
 * Prevents the visitor from scrolling past the intro or seeing case
 * cards until the sequence finishes.
 * ---------------------------------------------------------------- */

html.intro-priming,
html.intro-priming body {
  overflow: hidden;
}


/* -------------------- Reduced motion safety net --------------------
 * The head decider already routes reduced-motion sessions to
 * .intro-done (no priming), so the overlay never shows. This is a
 * belt-and-suspenders guarantee in case the class hook is wrong.
 * ---------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .intro { display: none !important; }
  html.intro-priming,
  html.intro-priming body { overflow: auto !important; }
}
