/* ═══════════════════════════════════════════════════════════════════════════
   CINEMATIC PUSH · WOW first-paint entrance for hero 31 (variant 31-wow-push)
   ---------------------------------------------------------------------------
   Adds three decorative WARM-LIGHT layers inside .plate (which is
   overflow:hidden, so they are clipped to the photograph) plus a focus
   vignette. They rest INVISIBLE. A GSAP master timeline (wow-cinematic-push.js)
   pushes the frame in toward the one lit window (~64% x / 45% y), ignites the
   light with a single bloom, parallax-focuses the field, and staggers the copy
   in on the light's beat.

   DEGRADE CONTRACT
   - Reduced motion: the JS bails (matchMedia guard) AND the base hero.css
     @media (prefers-reduced-motion: reduce) block kills every animation. These
     layers stay opacity:0 (decorative only). The photo, copy and signup are all
     shown by the base stylesheet — nothing is ever hidden.
   - No JS / GSAP blocked: these layers stay opacity:0 (harmless) and the base
     hero.css keyframe entrance (pl-plate / pl-copy) plays as the fallback.
   - GSAP active: the script adds .pl--gsap, which switches OFF the base keyframe
     entrance so GSAP alone authors the opening (no double-play).
   Warm accent only: amber / gold / terracotta sampled from the lit pane.
   ═════════════════════════════════════════════════════════════════════════ */

/* The warm layers + vignette. Absolute over the img, clipped by .plate. Copy
   lives in a separate grid cell at z-index:3, so it always paints above these. */
.pl .pl-vignette,
.pl .pl-glow,
.pl .pl-shaft {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;               /* rest state · JS/GSAP ignites, else stays dark   */
}

/* Focus vignette · darkens the far field so the eye lands on the light.
   Transparent hole sits exactly on the lit window. */
.pl .pl-vignette {
  z-index: 1;
  background: radial-gradient(125% 95% at 64% 45%,
    rgba(7, 32, 30, 0) 38%,
    rgba(7, 32, 30, 0.42) 74%,
    rgba(7, 32, 30, 0.66) 100%);
}

/* The bloom · a warm amber halo centred on the pane. Screen blend so it reads
   as emitted light, not paint. */
.pl .pl-glow {
  z-index: 2;
  transform-origin: 64% 45%;
  background: radial-gradient(38% 34% at 64% 45%,
    rgba(248, 220, 182, 0.90) 0%,
    rgba(242, 193, 132, 0.60) 24%,
    rgba(197, 108, 71, 0.28) 48%,
    rgba(197, 108, 71, 0) 72%);
  mix-blend-mode: screen;
}

/* The spill · a soft warm shaft that grows downward from the window, as if the
   light were falling past the sill. */
.pl .pl-shaft {
  z-index: 3;
  transform-origin: 63% 40%;
  background: radial-gradient(26% 62% at 63% 56%,
    rgba(242, 193, 132, 0.42) 0%,
    rgba(242, 193, 132, 0.12) 46%,
    rgba(242, 193, 132, 0) 74%);
  mix-blend-mode: screen;
}

/* ── When GSAP owns the opening ───────────────────────────────────────────── */
/* Switch OFF the base hero.css keyframe entrance so the two never play at once,
   and hint the compositor on the elements GSAP actually moves. */
.pl--gsap .plate img { animation: none; }
.pl--gsap .h1,
.pl--gsap .lede,
.pl--gsap .act { animation: none; }

.pl--gsap .plate img,
.pl--gsap .pl-glow,
.pl--gsap .pl-shaft,
.pl--gsap .pl-vignette { will-change: transform, opacity; }

/* Belt-and-braces: if reduced motion is on, force every layer back to its calm
   static state even should a class linger. Content is never touched here. */
@media (prefers-reduced-motion: reduce) {
  .pl .pl-vignette,
  .pl .pl-glow,
  .pl .pl-shaft { opacity: 0 !important; animation: none !important; }
  .pl--gsap .plate img { animation: none; transform: none !important; }
  .pl--gsap .h1,
  .pl--gsap .lede,
  .pl--gsap .act { opacity: 1 !important; transform: none !important; }
}
