/* Sigildream — immersive scene-based experience
 *
 * Architecture:
 *   - body scrolls vertically with scroll-snap (one scene per viewport).
 *   - .bg-stage is fixed full-viewport behind everything; each scene
 *     owns a .bg-layer that fades in when body[data-scene="<id>"] matches.
 *   - For music + video scenes, .bg-img crossfades between slides driven
 *     by the active carousel slide (JS toggles .is-active on .bg-img-a/b
 *     and sets src on #ytBg for the video scene).
 *   - Carousels scroll-snap horizontally; arrows + drag + wheel.
 *
 * No vertical "long page" feel: each scene is one viewport.
 */

:root {
  --bg-0: #04040a;
  --bg-1: #06060c;
  --bg-2: #08080e;
  --accent: #cfe8ff;
  --accent-soft: rgba(207, 232, 255, 0.18);
  --line: rgba(255, 255, 255, 0.10);
  --line-strong: rgba(207, 232, 255, 0.45);
  --text: #f4f3ef;
  --muted: #9b9a93;
  --muted-dim: #6e6d66;
  --shell: min(1240px, calc(100vw - 56px));
  --shell-wide: min(1480px, calc(100vw - 56px));
  --display-font: "Inter", "Helvetica Neue", "Arial", sans-serif;
  --mono-font: "JetBrains Mono", "SF Mono", "Menlo", monospace;
  --body-font: "Inter", "Helvetica Neue", "Arial", sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  color: var(--text);
  font-family: var(--body-font);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

html { scroll-behavior: smooth; }

body {
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--bg-0);
  scroll-snap-type: y proximity;
}

a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
ol, ul { margin: 0; padding: 0; list-style: none; }
p { margin: 0; color: var(--muted); }

h1, h2, h3, h4 {
  font-family: var(--display-font);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

/* Text-stroke: a 1px hard outline + a soft halo so every line of text on the
   page stays readable on top of the dynamic background (light covers like
   "Happy New Year (DANCE)", dark sketches, busy gradients). Applied broadly
   to all foreground text via a single rule. */
.scene-h1, .scene-tagline, .scene-chapter,
.stage-overlay-title, .stage-overlay-tag, .stage-overlay-meta,
.stage-strip-eyebrow, .stage-strip-channel,
.contact-headline, .contact-sub,
.manifesto-stmt, .manifesto-exp, .manifesto-num,
.eyebrow, .contact-footer {
  text-shadow:
    -1px -1px 0 rgba(0, 0, 0, 0.55),
     1px -1px 0 rgba(0, 0, 0, 0.55),
    -1px  1px 0 rgba(0, 0, 0, 0.55),
     1px  1px 0 rgba(0, 0, 0, 0.55),
     0 0 18px rgba(0, 0, 0, 0.85);
}

/* ──────────────────────────────────────────────
   AMBIENT OVERLAYS — always-on, full viewport, fixed
   ────────────────────────────────────────────── */

.site-noise {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  opacity: 0.04;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.6'/></svg>");
  mix-blend-mode: overlay;
}

.site-vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  background: radial-gradient(ellipse at center, transparent 50%, rgba(0, 0, 0, 0.55) 100%);
}

/* ──────────────────────────────────────────────
   DYNAMIC BACKGROUND STAGE
   ────────────────────────────────────────────── */

.bg-stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.bg-layer {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1100ms cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: opacity;
}

body[data-scene="games"]   .bg-layer[data-bg="games"],
body[data-scene="music"]   .bg-layer[data-bg="music"],
body[data-scene="video"]   .bg-layer[data-bg="video"],
body[data-scene="contact"] .bg-layer[data-bg="contact"] {
  opacity: 1;
}

.bg-img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: grayscale(0.18) contrast(1.04) brightness(0.92);
  transform: scale(1.05);
  animation: bgDrift 28s ease-in-out infinite alternate;
}

@keyframes bgDrift {
  0%   { transform: scale(1.05) translate(0, 0); }
  100% { transform: scale(1.10) translate(-0.8%, -1.2%); }
}

/* ───── Games bg slideshow ─────
   Each .bg-img inside .bg-layer-slides fades in/out on a 48s cycle, with
   staggered animation-delays so only one slide is fully visible at a time.
   The bgDrift continues to apply on top (subtle scale/translate). */
.bg-layer-slides .bg-img {
  opacity: 0;
  animation:
    bgDrift 28s ease-in-out infinite alternate,
    gamesSlide 48s ease-in-out infinite;
}

@keyframes gamesSlide {
  0%   { opacity: 0; }
  4%   { opacity: 1; }
  14%  { opacity: 1; }
  19%  { opacity: 0; }
  100% { opacity: 0; }
}

.bg-layer-slides .bg-img:nth-child(1) { animation-delay: 0s,     0s;  }
.bg-layer-slides .bg-img:nth-child(2) { animation-delay: -2s,    8s;  }
.bg-layer-slides .bg-img:nth-child(3) { animation-delay: -5s,   16s;  }
.bg-layer-slides .bg-img:nth-child(4) { animation-delay: -8s,   24s;  }
.bg-layer-slides .bg-img:nth-child(5) { animation-delay: -11s,  32s;  }
.bg-layer-slides .bg-img:nth-child(6) { animation-delay: -14s,  40s;  }

/* Music scene: crossfade between two .bg-img layers as carousel changes */
.bg-layer[data-bg="music"] .bg-img,
.bg-layer[data-bg="video"] .bg-img-fallback {
  opacity: 0;
  transition: opacity 900ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.bg-layer[data-bg="music"] .bg-img.is-active,
.bg-layer[data-bg="video"] .bg-img-fallback.is-active {
  opacity: 1;
}

/* Video scene: YouTube iframe stretched to cover */
.bg-yt-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 1;
}

.bg-yt-wrap iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  /* Cover: fill the viewport entirely, even if the 16:9 video gets
     cropped on portrait. User explicitly preferred fullscreen over
     letterboxed captions/controls. */
  width: 100vw;
  height: 56.25vw;
  min-width: 177.78vh;
  min-height: 100vh;
  transform: translate(-50%, -50%);
  border: 0;
  /* Allow direct interaction with YouTube's own controls (play/pause,
     seek, fullscreen). Site overlay + strip live at z 4+ inside the
     scene, so they catch clicks first; the iframe gets clicks only on
     the uncovered video area. */
  pointer-events: auto;
  filter: grayscale(0.10) contrast(1.05) brightness(0.85);
}

/* Veils on top of bg-img */
.bg-veil {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.bg-veil-deep {
  background:
    linear-gradient(180deg, rgba(4, 4, 10, 0.70) 0%, rgba(4, 4, 10, 0.85) 100%),
    linear-gradient(90deg, rgba(4, 4, 10, 0.55) 0%, rgba(4, 4, 10, 0.15) 70%);
}

.bg-veil-cinema {
  background:
    linear-gradient(96deg,
      rgba(4, 4, 10, 0.90) 0%,
      rgba(4, 4, 10, 0.65) 40%,
      rgba(4, 4, 10, 0.35) 75%,
      rgba(4, 4, 10, 0.18) 100%),
    linear-gradient(180deg, rgba(4, 4, 10, 0.28) 0%, rgba(4, 4, 10, 0.72) 100%);
}

/* ──────────────────────────────────────────────
   HEADER — sticky, transparent over bg
   ────────────────────────────────────────────── */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 36px 14px;
  /* Backdrop is on a pseudo-element so we can grow/shrink it horizontally
     without affecting the brandmark/nav layout above. */
}

.site-header::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  background: linear-gradient(180deg, rgba(4, 4, 8, 0.55), rgba(4, 4, 8, 0.05));
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  z-index: -1;
  pointer-events: none;
  transition: width 720ms cubic-bezier(0.22, 0.61, 0.36, 1),
              border-bottom-left-radius 720ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* On the hero scene, narrow the backdrop band to roughly the nav area so
   the video's top edge is visible. As soon as the user leaves hero (the
   brandmark has fully formed at top-left) the band expands back to
   full-width with a smooth slide from the right. */
body[data-scene="hero"] .site-header::before {
  width: 360px;
  max-width: 60%;
  border-bottom-left-radius: 26px;
}

.brandmark {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-transform: uppercase;
}

.brandmark-logo {
  width: 36px;
  height: 36px;
  object-fit: contain;
  filter: drop-shadow(0 0 14px rgba(207, 232, 255, 0.30));
  animation: logoBreath 6s ease-in-out infinite;
}

@keyframes logoBreath {
  0%, 100% { filter: drop-shadow(0 0 12px rgba(207, 232, 255, 0.22)); }
  50%      { filter: drop-shadow(0 0 24px rgba(207, 232, 255, 0.55)); }
}

.brandmark-copy {
  display: inline-flex;
  flex-direction: column;
  line-height: 1.05;
}

.brandmark-copy strong {
  font-family: var(--display-font);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.22em;
}

.brandmark-copy small {
  font-family: var(--mono-font);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  color: var(--muted-dim);
  margin-top: 2px;
}

.main-nav {
  display: inline-flex;
  align-items: center;
  gap: 28px;
  font-family: var(--mono-font);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.nav-sound {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  transition: color 240ms ease, transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.nav-sound svg { width: 18px; height: 18px; }
.nav-sound:hover { color: var(--text); transform: scale(1.06); }
.nav-sound .nav-sound-off { display: none; }
body.audio-muted .nav-sound { color: var(--muted-dim); }
body.audio-muted .nav-sound .nav-sound-on  { display: none; }
body.audio-muted .nav-sound .nav-sound-off { display: inline-block; }

.main-nav a {
  position: relative;
  color: var(--muted);
  padding-bottom: 4px;
  transition: color 240ms ease;
}

.main-nav a::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width 280ms ease, left 280ms ease;
}

.main-nav a:hover { color: var(--text); }
.main-nav a.is-active { color: var(--text); }
.main-nav a:hover::after,
.main-nav a.is-active::after { width: 100%; left: 0; }

/* ──────────────────────────────────────────────
   SCENE STAGE
   ────────────────────────────────────────────── */

.scenes {
  position: relative;
  z-index: 2;
}

.scene {
  position: relative;
  min-height: 100vh;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: flex;
  align-items: center;
  padding: 90px 36px 60px;
}

.scene-inner {
  position: relative;
  z-index: 2;
  width: var(--shell);
  margin: 0 auto;
  max-width: 100%;
}

.scene-inner-wide {
  width: var(--shell-wide);
}

.scene-inner-center {
  text-align: center;
}

/* ──────────────────────────────────────────────
   TYPOGRAPHY HELPERS
   ────────────────────────────────────────────── */

.eyebrow {
  display: inline-block;
  margin: 0 0 22px;
  font-family: var(--mono-font);
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-dim);
}

.eyebrow.is-accent { color: var(--accent); }

.scene-chapter {
  display: inline-flex;
  align-items: baseline;
  gap: 0;
  font-family: var(--mono-font);
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-dim);
  margin-bottom: 28px;
}

.scene-chapter > span:first-child { color: var(--accent); }

/* ──────────────────────────────────────────────
   HERO SCENE — scroll-scrubbed video intro
   The scene is 200vh tall; the inner .hero-video-stage is sticky for the
   first viewport while the user scrolls through the 100vh spacer below.
   JS maps scroll position → video.currentTime, so dragging through the
   first viewport plays the intro forward (frame 0 → final brand burst).
   ────────────────────────────────────────────── */

.scene-hero {
  /* 100vh scrub + 50vh hold (paused on last frame) + 50vh fade.
     No sticky element — .hero-video-stage is position:fixed. */
  min-height: 200vh;
  display: block;
  align-items: stretch;
  padding: 0;
  position: relative;
  scroll-snap-align: start;
  scroll-snap-stop: normal;
}

.hero-video-stage {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  z-index: 5;
  pointer-events: none;
  transition: opacity 320ms ease;
}

/* Hide the hero video stage once the user has left the hero scene
   (avoids it covering games / video / music scenes). */
body:not([data-scene="hero"]) .hero-video-stage {
  opacity: 0;
}

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  background: var(--bg-0);
  /* Filter brightness is driven by JS — ramps from 0.55 to 1.0 over the
     first 20% of the scrub so the video reveals at full clarity quickly.
     Initial value here is just the first-paint state. */
  filter: brightness(0.55) contrast(1.06);
  /* Black areas of the burst become transparent during the fade — the
     games bg below shows through the dark parts as the video dissolves. */
  mix-blend-mode: screen;
  will-change: opacity, filter;
}

.hero-veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(ellipse at 50% 38%, rgba(207, 232, 255, 0.05), transparent 50%),
    linear-gradient(180deg, rgba(4, 4, 10, 0.20) 0%, rgba(4, 4, 10, 0.40) 60%, rgba(4, 4, 10, 0.78) 100%);
  pointer-events: none;
}

.hero-content {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;     /* pin to bottom of viewport */
  align-items: center;           /* keep horizontally centered */
  text-align: center;
  padding: 36px 36px 64px;       /* 64px bottom = matches .stage-overlay */
  /* Opacity is driven by JS as the user scrolls — inverse to .brandmark. */
}

/* Mission line — single row between the tagline and the scroll hint.
   Slightly smaller + dimmer than the tagline so it reads as a footnote
   to the brand line above. */
.hero-content .scene-mission {
  margin: 0 0 64px;
  font-size: clamp(0.78rem, 1vw, 0.92rem);
  line-height: 1.4;
  font-weight: 400;
  letter-spacing: 0.005em;
  color: var(--muted);
  max-width: none;
  white-space: nowrap;       /* fits on one line on desktop */
}

/* Hero text — hard outline + a breathing DARK halo (an inverse glow) so
   the letters carve a soft pocket of shadow into the bright background
   instead of glowing accent. Overrides the global .stroked rule. */
.hero-content .scene-h1,
.hero-content .scene-tagline,
.hero-content .scene-mission,
.hero-content .scene-scrollhint > span:not(.scrollhint-line) {
  text-shadow:
    -1px -1px 0 rgba(0, 0, 0, 0.95),
     1px -1px 0 rgba(0, 0, 0, 0.95),
    -1px  1px 0 rgba(0, 0, 0, 0.95),
     1px  1px 0 rgba(0, 0, 0, 0.95),
     0 0 18px rgba(0, 0, 0, 0.95),
     0 0 44px rgba(0, 0, 0, 0.65);
  animation: heroTextGlow 3.6s ease-in-out infinite alternate;
}

@keyframes heroTextGlow {
  0% {
    text-shadow:
      -1px -1px 0 rgba(0, 0, 0, 0.95),
       1px -1px 0 rgba(0, 0, 0, 0.95),
      -1px  1px 0 rgba(0, 0, 0, 0.95),
       1px  1px 0 rgba(0, 0, 0, 0.95),
       0 0 16px rgba(0, 0, 0, 0.95),
       0 0 36px rgba(0, 0, 0, 0.50);
  }
  100% {
    text-shadow:
      -1px -1px 0 rgba(0, 0, 0, 0.95),
       1px -1px 0 rgba(0, 0, 0, 0.95),
      -1px  1px 0 rgba(0, 0, 0, 0.95),
       1px  1px 0 rgba(0, 0, 0, 0.95),
       0 0 26px rgba(0, 0, 0, 1.0),
       0 0 64px rgba(0, 0, 0, 0.85);
  }
}

.hero-scrub-spacer {
  width: 100%;
  height: 100vh;
  pointer-events: none;
}

.hero-hold-spacer,
.hero-fade-spacer {
  width: 100%;
  height: 50vh;
  pointer-events: none;
}

/* No separate "settle logo" anymore. The <video> itself fades out across
   the fade spacer (JS sets opacity each frame), and `mix-blend-mode:
   screen` on the video makes the black background of the brand burst
   become transparent, so the games bg-layer behind shows through the
   dark parts during the fade.

   The hero scene has no bg-layer — the <video> is the visual. */

.hero-video {
  /* opacity is driven by JS during the fade phase */
}

/* Brandmark (logo + Sigildream + Innovation Studio) crossfades with the
   hero text — JS sets opacity continuously from scrubProgress so the
   two are perfectly inverse. CSS just provides the default invisible
   state for first paint before JS runs. */
.brandmark {
  opacity: 0;
  will-change: opacity;
}

/* Reveal the next scene's background immediately when the settle starts —
   the games bg should already be visible behind the (now screen-blended,
   so partially transparent) shrinking captured frame. Quick fade-in
   over the very first portion of the settle for a less abrupt entry. */
body.is-settling-active .bg-layer[data-bg="games"] {
  opacity: 1;
  transition: opacity 320ms ease;
}

/* Shared transition declarations for elements that participate in the
   video-idle slide-out (the actual transform overrides live AFTER the
   stage-entrance rules below, so they win the specificity tie). */

.site-header,
.scene-rail,
.stage-overlay,
.stage-strip,
.brandmark,
.main-nav,
.site-header::before,
.bg-layer .bg-veil {
  transition: transform 700ms cubic-bezier(0.22, 0.61, 0.36, 1),
              opacity   500ms ease;
}

/* ───── Next-scene entrance: when the user lands past the hero (body
   data-scene = games or further), the .scene-stage content slides
   subtly up + fades in, drawing the eye from top-left brandmark toward
   the centered art / overlay. Single shot on each entry. */

.scene-stage > .stage-overlay,
.scene-stage > .stage-strip {
  transform: translateY(28px);
  opacity: 0;
  transition: transform 720ms cubic-bezier(0.16, 1, 0.3, 1),
              opacity 520ms ease;
}

body[data-scene="games"]   .scene-games .stage-overlay,
body[data-scene="games"]   .scene-games .stage-strip,
body[data-scene="video"]   .scene-video .stage-overlay,
body[data-scene="video"]   .scene-video .stage-strip,
body[data-scene="music"]   .scene-music .stage-overlay,
body[data-scene="music"]   .scene-music .stage-strip {
  transform: translateY(0);
  opacity: 1;
}

/* Tiny entrance delay on the strip so the eye reads the overlay first. */
body[data-scene="games"]   .scene-games .stage-strip,
body[data-scene="video"]   .scene-video .stage-strip,
body[data-scene="music"]   .scene-music .stage-strip {
  transition-delay: 140ms;
}

/* ───── Video scene idle mode (must come AFTER the entrance rules to
   win the specificity tie). After ~2.5s of no interaction on the Video
   scene, body.video-idle slides surrounding UI off the edges so only
   the playing YouTube embed remains fullscreen + un-darkened. Any
   wheel/touch/move/key resets. */

body.video-idle .brandmark { transform: translateX(-180%); }
body.video-idle .main-nav  { transform: translateX(180%); }
body.video-idle .site-header::before { opacity: 0; }

body.video-idle .scene-video .stage-overlay { transform: translateX(-110%); }
body.video-idle .scene-video .stage-strip   { transform: translateX(110%); }

body.video-idle .scene-rail { transform: translate(180%, -50%); }

/* Un-darken the playing video — fade out the cinema veil. */
body.video-idle .bg-layer[data-bg="video"] .bg-veil { opacity: 0; }

.scene-h1 {
  font-family: var(--display-font);
  font-size: clamp(3rem, 8vw, 6.4rem);
  font-weight: 700;
  letter-spacing: 0.09em;
  line-height: 0.94;
  text-transform: uppercase;
  margin: 0 0 18px;
}

/* Override the generic dark heroTextGlow on SIGILDREAM with a warmer
   accent breathing aura. Hard 4-corner outline stays for legibility. */
.hero-content .scene-h1 {
  animation:
    titleEnter 1100ms cubic-bezier(0.22, 0.61, 0.36, 1) 200ms both,
    heroH1Aura    5s ease-in-out infinite alternate 1.3s;
}

@keyframes heroH1Aura {
  0% {
    text-shadow:
      -1px -1px 0 rgba(0, 0, 0, 0.95),
       1px -1px 0 rgba(0, 0, 0, 0.95),
      -1px  1px 0 rgba(0, 0, 0, 0.95),
       1px  1px 0 rgba(0, 0, 0, 0.95),
       0 0 18px rgba(0, 0, 0, 0.95),
       0 0 22px rgba(207, 232, 255, 0.18),
       0 0 44px rgba(207, 232, 255, 0.05);
  }
  100% {
    text-shadow:
      -1px -1px 0 rgba(0, 0, 0, 0.95),
       1px -1px 0 rgba(0, 0, 0, 0.95),
      -1px  1px 0 rgba(0, 0, 0, 0.95),
       1px  1px 0 rgba(0, 0, 0, 0.95),
       0 0 22px rgba(0, 0, 0, 1.0),
       0 0 38px rgba(207, 232, 255, 0.55),
       0 0 78px rgba(207, 232, 255, 0.30);
  }
}

@keyframes titleEnter {
  0%   { opacity: 0; transform: translateY(28px); letter-spacing: 0.02em; }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: translateY(0); letter-spacing: 0.09em; }
}

.scene-tagline {
  font-family: var(--mono-font);
  font-size: clamp(0.95rem, 1.4vw, 1.15rem);
  font-weight: 400;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1.4;
  text-shadow: 0 0 24px rgba(207, 232, 255, 0.35);
  animation: fadeUp 900ms ease-out 500ms both;
  margin: 0 0 18px;        /* tight gap to mission, matches SIGILDREAM→tagline */
}

@keyframes fadeUp {
  0%   { opacity: 0; transform: translateY(16px); }
  100% { opacity: 1; transform: translateY(0); }
}

.scene-scrollhint {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: var(--mono-font);
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
  animation: fadeUp 900ms ease-out 1100ms both;
}

.scrollhint-line {
  display: inline-block;
  width: 36px;
  height: 1px;
  background: var(--accent);
  animation: scrollHint 2.4s ease-in-out infinite;
  transform-origin: left;
}

@keyframes scrollHint {
  0%, 100% { transform: scaleX(0.3); opacity: 0.35; }
  50%      { transform: scaleX(1);   opacity: 1; }
}

/* ──────────────────────────────────────────────
   MANIFESTO — base list (used by .manifesto-compact in outro)
   ────────────────────────────────────────────── */

.manifesto-stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.manifesto-stack li {
  display: grid;
  grid-template-columns: 80px 1fr;
  row-gap: 4px;
  column-gap: 28px;
  padding: 18px 0;
  border-top: 1px solid var(--line);
  transition: border-color 320ms ease;
}

.manifesto-stack li:first-child { border-top: none; }
.manifesto-stack li:hover { border-color: var(--line-strong); }

.manifesto-num {
  grid-row: span 2;
  font-family: var(--mono-font);
  font-size: 1.1rem;
  letter-spacing: 0.2em;
  color: var(--muted-dim);
  align-self: start;
  padding-top: 4px;
}

.manifesto-stmt {
  font-family: var(--display-font);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 400;
  letter-spacing: -0.005em;
  color: var(--text);
}

.manifesto-exp {
  font-size: 0.96rem;
  line-height: 1.65;
  color: var(--muted);
  max-width: 56ch;
}

/* ──────────────────────────────────────────────
   STAGE SCENES (Games / Video / Music) — Netflix-style
   Background does the work (cover, video, art) and the foreground is
   a tight overlay in the bottom-left + a small thumbnail strip in the
   bottom-right (only for multi-item Music + Video).
   ────────────────────────────────────────────── */

.scene-stage {
  position: relative;
  width: 100%;
  flex: 1;
  min-height: calc(100vh - 96px);
  z-index: 2;
  /* Transparent to clicks in empty areas so clicks fall through to the
     YouTube iframe (z 1, in the bg-layer behind). Children explicitly
     re-enable pointer-events below. */
  pointer-events: none;
}

/* Re-enable interaction on every meaningful child of .scene-stage. */
.stage-overlay,
.stage-strip,
.scene-chapter,
.stage-nav {
  pointer-events: auto;
}

/* Stage nav handles (mobile only). Floating circular buttons on the
   left and right edges that step through the strip-tiles. Hidden on
   desktop where the strip itself is the primary navigation. */
.stage-nav {
  position: absolute;
  top: 50%;
  z-index: 6;
  width: 48px;
  height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(4, 4, 10, 0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--text);
  display: none;        /* shown on mobile via media query */
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  transform: translateY(-50%);
  transition: background 240ms ease, color 240ms ease, transform 320ms ease;
}

.stage-nav svg { width: 22px; height: 22px; }
.stage-nav-prev { left: 14px; }
.stage-nav-next { right: 14px; }
.stage-nav:hover {
  background: var(--accent);
  color: #050507;
}
.stage-nav:hover.stage-nav-prev { transform: translate(-3px, -50%); }
.stage-nav:hover.stage-nav-next { transform: translate(3px, -50%); }
.stage-nav:active { transform: translateY(-50%) scale(0.96); }

.scene-games, .scene-music, .scene-video {
  padding: 0;
  align-items: stretch;
}

.dream-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.dream-status .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted-dim);
}

.dream-status.is-live { color: var(--accent); }
.dream-status.is-live .dot {
  background: var(--accent);
  box-shadow: 0 0 14px var(--accent);
  animation: liveDot 2.2s ease-in-out infinite;
}

@keyframes liveDot {
  0%, 100% { opacity: 0.5; transform: scale(0.85); }
  50%      { opacity: 1;   transform: scale(1.2); }
}

/* ───── Bottom-left overlay (title + meta + CTA) ───── */

.stage-overlay {
  position: absolute;
  left: 56px;
  bottom: 64px;
  z-index: 4;
  max-width: 640px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.stage-overlay .scene-chapter {
  margin-bottom: 18px;
}

.stage-overlay-meta {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 18px;
  font-family: var(--mono-font);
  font-size: 0.66rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 16px;
}

.stage-overlay-meta > span { display: inline-flex; align-items: center; gap: 10px; }

.stage-overlay-title {
  font-family: var(--display-font);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  line-height: 0.98;
  color: var(--text);
  margin: 0 0 18px;
  font-size: clamp(2rem, 3.6vw, 3rem);
  max-width: 14ch;
}

.stage-overlay-title.is-hero {
  font-size: clamp(3rem, 6vw, 4.8rem);
  letter-spacing: 0.04em;
  max-width: 12ch;
}

.stage-overlay-tag {
  font-size: 1rem;
  line-height: 1.55;
  color: var(--text);
  max-width: 44ch;
  margin: 0 0 26px;
}

.stage-overlay-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 14px 26px;
  background: var(--accent);
  color: #050507;
  border-radius: 999px;
  font-family: var(--mono-font);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-shadow: none;
  transition: background 240ms ease, transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1),
              box-shadow 320ms ease;
}

.stage-overlay-cta .arrow {
  transition: transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.stage-overlay-cta:hover {
  background: #fff;
  transform: translateY(-2px);
  box-shadow: 0 14px 36px -16px rgba(207, 232, 255, 0.55);
}

.stage-overlay-cta:hover .arrow { transform: translateX(4px); }

/* ───── Music miniplayer ─────
   Dead-center of the Music scene. A hidden YouTube iframe handles the
   actual audio playback (controlled via postMessage on the JS API);
   the visible component is a canvas with a synthetic animated waveform
   + periodic particle bursts, plus a transport control row. */

/* Full-stage galaxy canvas behind the miniplayer — orbital particles +
 * constellation lines + central sigil + periodic ritual bursts. */
.music-galaxy {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity 800ms ease;
}

body[data-scene="music"] .music-galaxy { opacity: 1; }

/* Minimal floating transport controls — no glass card. The constellation
 * canvas is the centrepiece; controls just sit at the bottom of the scene. */
.music-player {
  position: absolute;
  left: 50%;
  bottom: 56px;
  transform: translateX(-50%);
  z-index: 5;
  width: min(520px, calc(100vw - 36px));
  padding: 0;
  background: none;
  border: none;
  box-shadow: none;
  pointer-events: auto;
}

.music-audio-iframe {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
  left: -9999px;
}

.music-particles {
  position: absolute;
  inset: -50%;
  pointer-events: none;
  z-index: -1;
}

.music-particles span {
  position: absolute;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 14px rgba(207, 232, 255, 0.85);
  pointer-events: none;
  animation: mpParticle 1400ms ease-out forwards;
}

@keyframes mpParticle {
  0%   { opacity: 0; transform: translate(0,0) scale(0.4); }
  20%  { opacity: 1; }
  100% { opacity: 0;
         transform:
           translate(var(--p-dx, 0px), var(--p-dy, 0px))
           scale(0.8); }
}

.music-controls {
  display: flex;
  align-items: center;
  gap: 14px;
}

.mp-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(4, 4, 10, 0.5);
  color: var(--text);
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: background 200ms ease, color 200ms ease, transform 200ms ease;
}

.mp-btn:hover { background: var(--accent); color: #050507; transform: scale(1.06); }
.mp-btn svg   { width: 18px; height: 18px; fill: currentColor; }

.mp-play .mp-pause-icon { display: none; }
.music-player.is-playing .mp-play  .mp-play-icon  { display: none; }
.music-player.is-playing .mp-play  .mp-pause-icon { display: inline-block; }

.music-seek {
  flex: 1 1 auto;
  height: 4px;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 2px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.music-seek-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 0%;
  background: linear-gradient(90deg, var(--accent), rgba(207, 232, 255, 0.6));
  transition: width 220ms ease;
}

.music-time {
  font-family: var(--mono-font);
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  color: var(--muted);
  white-space: nowrap;
  min-width: 76px;
  text-align: right;
}

@media (max-width: 720px) {
  .music-player {
    width: calc(100vw - 24px);
    bottom: 28px;
  }
  .mp-btn { width: 36px; height: 36px; }
  .mp-btn svg { width: 16px; height: 16px; }
  .music-controls { gap: 10px; }
  .music-time { font-size: 0.58rem; min-width: 68px; }
}

/* ───── Bottom-right thumbnail strip ───── */

.stage-strip {
  position: absolute;
  right: 56px;
  bottom: 64px;
  z-index: 4;
  width: min(46%, 640px);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.stage-strip-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--mono-font);
  font-size: 0.6rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

.stage-strip-eyebrow { color: var(--muted-dim); }

.stage-strip-channel {
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: color 240ms ease;
}
.stage-strip-channel:hover { color: #fff; }
.stage-strip-channel .arrow {
  transition: transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.stage-strip-channel:hover .arrow { transform: translateX(3px); }

.stage-strip-track {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding: 6px 2px 8px;
}
.stage-strip-track::-webkit-scrollbar { display: none; }
.stage-strip-track:focus { outline: none; }
.stage-strip-track:focus-visible { outline: 1px solid var(--accent-soft); outline-offset: 4px; }

.strip-tile {
  flex: 0 0 148px;
  height: 92px;
  position: relative;
  background: var(--bg-1);
  border: 1px solid var(--line);
  cursor: pointer;
  overflow: hidden;
  padding: 0;
  scroll-snap-align: start;
  transition: border-color 320ms ease, transform 360ms cubic-bezier(0.22, 0.61, 0.36, 1),
              box-shadow 320ms ease;
}

.strip-poster {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  filter: grayscale(0.35) brightness(0.78);
  transition: filter 360ms ease, transform 700ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.strip-tile:hover .strip-poster {
  filter: grayscale(0.18) brightness(0.92);
  transform: scale(1.04);
}

.strip-tile.is-active {
  border-color: var(--accent);
  transform: translateY(-4px);
  box-shadow: 0 14px 36px -16px rgba(207, 232, 255, 0.40);
}

.strip-tile.is-active .strip-poster {
  filter: grayscale(0) brightness(1);
  transform: scale(1.04);
}

.strip-label {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 18px 8px 6px;
  background: linear-gradient(180deg, transparent, rgba(4, 4, 10, 0.94));
  color: var(--text);
  font-family: var(--mono-font);
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: left;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.85);
  pointer-events: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ──────────────────────────────────────────────
   OUTRO SCENE — manifesto + contact + footer
   Three-row grid: manifesto top, contact centered,
   footer pinned at the very bottom of the viewport.
   ────────────────────────────────────────────── */

.scene-outro { align-items: stretch; padding: 96px 36px 32px; }
.scene-outro .scene-inner {
  width: var(--shell-wide);
  max-width: 100%;
}

/* 2-column grid: contact LEFT, manifesto timeline RIGHT.
   Each column's max-width is tight and the gap between is narrow, so the
   two halves feel like one balanced composition (not two distant blocks).
   Footer spans both, pinned to the bottom row.                          */
.outro-inner {
  position: relative;
  min-height: calc(100vh - 128px);
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: 1fr auto;
  grid-template-areas:
    "contact   manifesto"
    "footer    footer";
  column-gap: 56px;
  row-gap: 36px;
  align-items: center;
}

.outro-contact {
  grid-area: contact;
  text-align: center;          /* eyebrow + headline + CTA + sub all centered */
  max-width: 440px;
  align-self: center;
  justify-self: end;           /* sit close to the divider, not far left */
  display: flex;
  flex-direction: column;
  align-items: center;
}

.outro-manifesto {
  grid-area: manifesto;
  text-align: left;
  max-width: 520px;
  align-self: center;
  justify-self: start;         /* sit close to the divider, not far right */
}

/* Manifesto timeline inside the outro: 4 rows + descriptions, fitted to
   a single viewport. */
.outro-manifesto .manifesto-stack { gap: 0; }
.outro-manifesto .manifesto-stack li {
  grid-template-columns: 56px 1fr;
  column-gap: 22px;
  padding: 14px 0;
}
.outro-manifesto .manifesto-num {
  font-size: 0.92rem;
  padding-top: 6px;
}
.outro-manifesto .manifesto-stmt {
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  font-weight: 500;
  margin-bottom: 2px;
}
.outro-manifesto .manifesto-exp {
  font-size: 0.86rem;
  line-height: 1.55;
  max-width: 46ch;
}

.contact-headline {
  font-family: var(--display-font);
  font-size: clamp(2rem, 3.6vw, 2.9rem);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.05;
  color: var(--text);
  margin: 0 0 32px;
  text-shadow: 0 2px 28px rgba(0, 0, 0, 0.6);
}

.contact-cta {
  display: inline-flex;
  align-items: center;
  align-self: center;
  gap: 14px;
  padding: 16px 32px;
  background: var(--accent);
  color: #050507;
  border: none;
  border-radius: 999px;
  font-family: var(--mono-font);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  cursor: pointer;
  margin: 0 0 22px;
  text-shadow: none;        /* pill has its own dark text on light bg */
  transition: background 240ms ease, transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1),
              box-shadow 320ms ease;
}

.contact-cta:hover {
  background: #fff;
  transform: translateY(-2px);
  box-shadow: 0 14px 36px -16px rgba(207, 232, 255, 0.55);
}

.contact-cta-arrow {
  display: inline-flex;
  align-items: center;
  font-family: var(--mono-font);
  font-size: 1.1rem;
  font-weight: 400;
  transition: transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.contact-cta:hover .contact-cta-arrow { transform: translate(4px, -4px); }

.contact-sub {
  font-family: var(--mono-font);
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

.contact-footer {
  grid-area: footer;
  width: 100%;
  display: flex;
  justify-content: center;
  border-top: 1px solid var(--line);
  padding-top: 22px;
  font-family: var(--mono-font);
  font-size: 0.62rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-dim);
}

/* ──────────────────────────────────────────────
   SCENE RAIL — right-side fixed scene navigation
   ────────────────────────────────────────────── */

.scene-rail {
  position: fixed;
  top: 50%;
  right: 22px;
  z-index: 25;
  display: flex;
  flex-direction: column;
  gap: 14px;
  transform: translateY(-50%);
}

.scene-rail a {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--mono-font);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: transparent;
  transition: color 320ms ease;
  padding: 2px 0;
}

.rail-dot {
  display: inline-block;
  width: 18px;
  height: 1px;
  background: rgba(255, 255, 255, 0.25);
  transition: background 320ms ease, width 320ms ease;
}

.rail-label {
  opacity: 0;
  transform: translateX(8px);
  transition: opacity 320ms ease, transform 320ms ease;
}

.scene-rail a:hover .rail-label { opacity: 0.8; transform: translateX(0); color: var(--text); }
.scene-rail a:hover { color: var(--text); }
.scene-rail a:hover .rail-dot { background: var(--accent); width: 28px; }

.scene-rail a.is-active .rail-dot { background: var(--accent); width: 28px; }
.scene-rail a.is-active .rail-label { opacity: 1; transform: translateX(0); color: var(--accent); }
.scene-rail a.is-active { color: var(--accent); }

/* ──────────────────────────────────────────────
   REDUCED MOTION
   ────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    transition-duration: 0.001s !important;
  }
  body { scroll-snap-type: none; }
  .bg-img { animation: none; transform: scale(1.05); }
}

/* ──────────────────────────────────────────────
   RESPONSIVE
   ────────────────────────────────────────────── */

@media (max-width: 1100px) {
  .scene { padding: 100px 24px 50px; }
  .scene-rail { display: none; }

  /* Tighten stage paddings + give the overlay more horizontal room when
     the strip stays alongside (still 2-col layout, but tighter). */
  .scene-games, .scene-music, .scene-video { padding: 0; }
  .stage-overlay { left: 36px; bottom: 44px; max-width: 56vw; }
  .stage-strip   { right: 36px; bottom: 44px; width: min(48%, 480px); }
  .stage-overlay-title { font-size: clamp(1.8rem, 3vw, 2.4rem); }
  .stage-overlay-title.is-hero { font-size: clamp(2.6rem, 5vw, 3.8rem); }
  .strip-tile { flex-basis: 124px; height: 78px; }
}

@media (max-width: 720px) {
  .site-header { padding: 14px 14px 12px; }
  .main-nav { gap: 14px; font-size: 0.58rem; letter-spacing: 0.18em; }
  .brandmark-logo { width: 30px; height: 30px; }
  .brandmark-copy strong { font-size: 0.82rem; letter-spacing: 0.18em; }
  .brandmark-copy small { font-size: 0.54rem; letter-spacing: 0.16em; }

  .scene { padding: 90px 20px 40px; }
  .scene-h1 { font-size: clamp(2.6rem, 13vw, 4.2rem); letter-spacing: 0.06em; }
  .scene-tagline { letter-spacing: 0.18em; }

  .manifesto-stack li { grid-template-columns: 56px 1fr; gap: 6px; padding: 12px 0; }
  .manifesto-num { font-size: 0.8rem; }

  /* Stage scenes on mobile: drop the bottom-left + bottom-right placement;
     stack overlay then strip, both centered. The fullscreen bg keeps its
     role as protagonist behind. */
  .scene-games, .scene-music, .scene-video { padding: 0; }
  .scene-stage {
    min-height: 100vh;
    display: block;
    padding: 0;
  }

  /* Overlay (chapter + meta + title + tag + CTA) pinned to the BOTTOM
     of the viewport, centered horizontally. On music scene the player
     transport sits below at bottom: 28px; bump the overlay above. */
  .stage-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 24px;
    max-width: 100%;
    padding: 0 24px;
    text-align: center;
    align-items: center;
  }
  .scene-music .stage-overlay { bottom: 92px; }
  .stage-overlay-title { font-size: clamp(1.6rem, 7vw, 2.2rem); max-width: none; margin-bottom: 12px; }
  .stage-overlay-title.is-hero { font-size: clamp(2.2rem, 10vw, 3rem); }
  .stage-overlay-meta { justify-content: center; margin-bottom: 10px; }
  .stage-overlay-tag { margin-bottom: 16px; }
  .stage-overlay-cta { align-self: center; }

  /* Hide the thumbnail strip — replaced by the prev/next handles. */
  .stage-strip { display: none; }

  /* Show the floating prev/next handles on mobile. */
  .stage-nav { display: inline-flex; }

  .contact-headline { font-size: clamp(1.8rem, 9vw, 2.4rem); margin-bottom: 28px; }
  .contact-cta { padding: 14px 24px; font-size: 0.72rem; letter-spacing: 0.22em; }
  .contact-footer { font-size: 0.58rem; padding-top: 18px; }

  /* Mobile outro: stack contact above manifesto. Both centered so the two
     blocks share the same axis instead of competing (centered vs. left). */
  .outro-inner {
    grid-template-columns: 1fr;
    grid-template-areas:
      "contact"
      "manifesto"
      "footer";
    row-gap: 32px;
    max-width: none;
  }
  .outro-contact { justify-self: center; max-width: 100%; }
  .outro-manifesto {
    justify-self: center;
    max-width: 100%;
    text-align: center;
  }
  /* On mobile, drop the 2-col (number | text) row layout: stack number
     above title above description, all centered. */
  .outro-manifesto .manifesto-stack { gap: 4px; }
  .outro-manifesto .manifesto-stack li {
    grid-template-columns: 1fr;
    column-gap: 0;
    padding: 14px 0;
    justify-items: center;
  }
  .outro-manifesto .manifesto-num {
    padding-top: 0;
    margin-bottom: 4px;
    font-size: 0.7rem;
    letter-spacing: 0.32em;
  }
  .outro-manifesto .manifesto-stmt { font-size: 1.1rem; }
  .outro-manifesto .manifesto-exp {
    font-size: 0.82rem;
    line-height: 1.55;
    max-width: 38ch;
    margin: 0 auto;
  }

}
