/* ───────────── motion layer ─────────────
   Final-state-first: nothing in this file applies unless <html> has
   .js-ready. If JS fails to load, the page renders as designed in
   styles.css with no hidden elements. */

/* ── Lenis smooth-scroll plumbing ──
   Lenis drives scroll via its own rAF loop and needs CSS smooth-scroll
   off + a non-scrollable body so it can take over the html element. */
html.lenis,
html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }
html.lenis body { overflow-x: clip; } /* clip avoids the scroll container that `hidden` creates */
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* ── arrival initial states (Chunk 2 will animate these to visible) ── */
html.js-ready body { opacity: 0; }

html.js-ready .fog { opacity: 0; }

html.js-ready .hero-title .line-inner {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.45em) skewY(5deg);
  will-change: transform, opacity;
}

html.js-ready .hero-tagline,
html.js-ready .hero-meta,
html.js-ready .hero-address,
html.js-ready .hero-cta {
  opacity: 0;
  transform: translateY(16px);
}

/* hero-text already has a CSS fade-up animation — suspend it so the
   GSAP timeline owns the staging */
html.js-ready .hero-text { animation: none; }

/* arrival-complete: restore the always-on CSS animations and act as a
   reveal-everything fallback if the GSAP timeline never ran (CDN
   failure, JS error, or safety timeout). */
html.arrival-done body,
html.arrival-done .fog,
html.arrival-done .hero-title .line-inner,
html.arrival-done .hero-tagline,
html.arrival-done .hero-meta,
html.arrival-done .hero-address,
html.arrival-done .hero-cta {
  opacity: 1;
  transform: none;
}

/* ── reduced motion: skip all of the above, keep page static-final ── */
html.reduced-motion body,
html.reduced-motion .fog,
html.reduced-motion .hero-title .line-inner,
html.reduced-motion .hero-tagline,
html.reduced-motion .hero-meta,
html.reduced-motion .hero-address,
html.reduced-motion .hero-cta {
  opacity: 1 !important;
  transform: none !important;
}
html.reduced-motion .hero-text { animation: none !important; }

/* ───────────── living atmosphere (Chunk 3) ───────────── */

/* Embers canvas: fixed full-viewport, behind content (z:1 sits below
   the z:2 sections but above the body::before grain layer at z:1 — so
   we use z:1 with pointer-events:none and rely on z-order in source). */
.embers-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
  opacity: 0.55;
  mix-blend-mode: screen;
}
html.reduced-motion .embers-canvas { display: none; }

/* Candle flicker bleed from top-right.
   Irregular keyframe stops give an organic, non-metronome rhythm. */
.candle-flicker {
  position: fixed;
  top: 0;
  right: 0;
  width: 55vw;
  height: 55vh;
  pointer-events: none;
  z-index: 1;
  background: radial-gradient(
    ellipse 70% 60% at 100% 0%,
    rgba(196, 119, 74, 0.22) 0%,
    rgba(196, 74, 141, 0.10) 35%,
    transparent 70%
  );
  mix-blend-mode: screen;
  animation: candle-flicker 7.3s infinite;
  will-change: opacity, transform;
}
@keyframes candle-flicker {
  0%   { opacity: 0.85; transform: scale(1.00); }
  7%   { opacity: 0.92; transform: scale(1.02); }
  13%  { opacity: 0.70; transform: scale(0.98); }
  23%  { opacity: 0.95; transform: scale(1.03); }
  31%  { opacity: 0.78; transform: scale(0.99); }
  41%  { opacity: 1.00; transform: scale(1.04); }
  47%  { opacity: 0.72; transform: scale(0.97); }
  58%  { opacity: 0.88; transform: scale(1.01); }
  66%  { opacity: 0.95; transform: scale(1.02); }
  73%  { opacity: 0.65; transform: scale(0.96); }
  82%  { opacity: 0.90; transform: scale(1.03); }
  91%  { opacity: 0.80; transform: scale(0.99); }
  100% { opacity: 0.85; transform: scale(1.00); }
}
html.reduced-motion .candle-flicker { animation: none; opacity: 0.78; }


/* ───────────── scroll choreography (Chunk 4) ───────────── */

/* Initial-hidden states for scroll-revealed elements. All gated on
   .js-ready; .arrival-done in motion.js reveals them as fallback. */
html.js-ready .section-header .section-eyebrow,
html.js-ready .section-header .section-title,
html.js-ready .section-header .section-sub,
html.js-ready .visions-title,
html.js-ready .visions-sub,
html.js-ready .visions-reel {
  opacity: 0;
  transform: translateY(20px);
  will-change: transform, opacity;
}
html.js-ready .drink-card,
html.js-ready .vision-card,
html.js-ready .rsvp-card,
html.js-ready .crew-figure {
  opacity: 0;
  transform: translateY(30px);
  will-change: transform, opacity;
}
html.js-ready .about-stats .stat-number { /* count-up starts at 0 */ }
html.js-ready .scene-layer { will-change: transform; }

/* arrival-done acts as universal reveal fallback for these too */
html.arrival-done .section-header .section-eyebrow,
html.arrival-done .section-header .section-title,
html.arrival-done .section-header .section-sub,
html.arrival-done .visions-title,
html.arrival-done .visions-sub,
html.arrival-done .visions-reel,
html.arrival-done .drink-card,
html.arrival-done .vision-card,
html.arrival-done .rsvp-card,
html.arrival-done .crew-figure {
  opacity: 1;
  transform: none;
}

/* Reduced motion: skip scroll reveal initial states too */
html.reduced-motion .section-header .section-eyebrow,
html.reduced-motion .section-header .section-title,
html.reduced-motion .section-header .section-sub,
html.reduced-motion .visions-title,
html.reduced-motion .visions-sub,
html.reduced-motion .visions-reel,
html.reduced-motion .drink-card,
html.reduced-motion .vision-card,
html.reduced-motion .rsvp-card,
html.reduced-motion .crew-figure {
  opacity: 1 !important;
  transform: none !important;
}

/* Chromatic shimmer on "Raise the Dead." headline.
   Two pseudo-element clones are offset in ghoul/eye-glow and settle to
   zero offset over ~600ms when the .shimmer-active class is added. */
.rsvp h2.shimmer {
  position: relative;
  isolation: isolate;
}
.rsvp h2.shimmer::before,
.rsvp h2.shimmer::after {
  content: attr(data-text);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  pointer-events: none;
  /* match the headline's font + line breaks exactly so the layers register */
  font: inherit;
  line-height: inherit;
  text-align: inherit;
  white-space: pre;
  text-shadow: none;
  opacity: 0;
  will-change: transform, opacity;
}
.rsvp h2.shimmer::before {
  color: var(--ghoul);
  mix-blend-mode: screen;
  transform: translate(-6px, 0);
}
.rsvp h2.shimmer::after {
  color: var(--eye-glow);
  mix-blend-mode: screen;
  transform: translate(6px, 0);
}
.rsvp h2.shimmer.shimmer-active::before {
  animation: shimmer-cyan 700ms cubic-bezier(.2,.8,.2,1) forwards;
}
.rsvp h2.shimmer.shimmer-active::after {
  animation: shimmer-magenta 700ms cubic-bezier(.2,.8,.2,1) forwards;
}
@keyframes shimmer-cyan {
  0%   { opacity: 0;    transform: translate(-12px, 0); }
  20%  { opacity: 0.85; transform: translate(-10px, 0); }
  60%  { opacity: 0.55; transform: translate(-4px, 0); }
  100% { opacity: 0;    transform: translate(0, 0); }
}
@keyframes shimmer-magenta {
  0%   { opacity: 0;    transform: translate(12px, 0); }
  20%  { opacity: 0.85; transform: translate(10px, 0); }
  60%  { opacity: 0.55; transform: translate(4px, 0); }
  100% { opacity: 0;    transform: translate(0, 0); }
}
html.reduced-motion .rsvp h2.shimmer::before,
html.reduced-motion .rsvp h2.shimmer::after { display: none; }

/* About stats: reserve width so count-up doesn't wobble layout */
.about-stats .stat-number {
  font-variant-numeric: tabular-nums;
}

/* ───────────── reduced-motion: full sweep (Chunk 5) ─────────────
   Honor the user's OS preference comprehensively — kill every
   decorative loop that predates the motion layer too. */
@media (prefers-reduced-motion: reduce) {
  .hero-image,
  .hero-image::before,
  .fog-layer,
  .bat,
  .floater.spider,
  .candle-flicker {
    animation: none !important;
  }
  .embers-canvas { display: none !important; }
  /* Tombstone parallax scrub is JS-driven — guard the JS path too */
  .tombstone-svg { transform: none !important; }
}
