/* ═══════════════════════════════════════════════════════════════════════
   AMBIENT — cinematic section-aware background system
   JS drives all color/opacity changes via direct inline styles.
   CSS only handles structure, drift animation, and blend modes.

   Key design decisions:
   - NO contain/isolation on .ambient-stage → mix-blend-mode works correctly
     against external section backgrounds
   - mix-blend-mode: screen → warm glow pools on dark sections
   - filter: blur(55px) on .ambient-orbs → soft pool-of-light appearance
   - All colors/opacities set by ambient.js per rAF frame (reliable vs CSS vars)
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Stage ─────────────────────────────────────────────────────────────
   Fixed, above section backgrounds (z-index 2) so mix-blend-mode screen
   composites the warm glow against dark section backgrounds.
   All section CONTENT is at z-index 3+, so it renders above the ambient —
   the glow is always behind text, images and interactive elements.
   NO: contain, isolation, will-change on the stage —
       these create stacking contexts that break mix-blend-mode.
─────────────────────────────────────────────────────────────────────── */
.ambient-stage {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  overflow: hidden;
  mix-blend-mode: screen;
}

/* ── Orbs — blurred radial light pools ─────────────────────────────────
   filter: blur(55px) is essential — makes hard gradients into soft glow.
   background and opacity are set directly by JS each rAF frame.
   will-change: transform scoped only here, not on stage.
─────────────────────────────────────────────────────────────────────── */
.ambient-orbs {
  position: absolute;
  inset: -10%;
  filter: blur(55px);
  animation: ambOrbitDrift 64s ease-in-out infinite;
  will-change: transform;
}

@keyframes ambOrbitDrift {
  0%   { transform: translate3d(  0px,   0px, 0) scale(1.00); }
  14%  { transform: translate3d(-22px,  10px, 0) scale(1.02); }
  28%  { transform: translate3d( 14px,  22px, 0) scale(1.04); }
  42%  { transform: translate3d( 24px,  -4px, 0) scale(1.03); }
  57%  { transform: translate3d(  6px, -20px, 0) scale(1.01); }
  71%  { transform: translate3d(-16px, -10px, 0) scale(1.03); }
  85%  { transform: translate3d(-24px,  16px, 0) scale(1.02); }
  100% { transform: translate3d(  0px,   0px, 0) scale(1.00); }
}

/* ── Grain — fine static film texture ──────────────────────────────────
   overlay blend adds texture without shifting luminance.
   opacity set by JS.
─────────────────────────────────────────────────────────────────────── */
.ambient-grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' seed='12'/%3E%3CfeColorMatrix values='0 0 0 0 0.94 0 0 0 0 0.89 0 0 0 0 0.80 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* ── Vignette — edge depth ──────────────────────────────────────────────
   Normal blend. background set by JS.
─────────────────────────────────────────────────────────────────────── */
.ambient-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ── Reduced motion ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ambient-orbs { animation: none; }
}

/* ── Mobile ─────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .ambient-grain { display: none; }
  /* Kill orb keyframe animation on phones — saves continuous compositor
     work on a 64s loop. Static blurred glow is still atmospheric. */
  .ambient-orbs  { animation: none; filter: blur(32px); }
  /* Static grain canvas is decorative — hide entirely on phones */
  #grain { display: none !important; }
}

