/* =====================================================================
   ELENA & DANIEL — A DIGITAL INVITATION
   Design system continued from the opening film:
   champagne · blush · dusty rose · antique gold foil
   ===================================================================== */

:root {
  /* ── Palette (sampled from the intro film) ── */
  --cream:        #F4E9DD;
  --cream-deep:   #EAD9C7;
  --blush:        #E7C7BE;
  --blush-soft:   #F0D8CF;
  --rose:         #D6A89C;
  --rose-deep:    #C0857A;
  --wax:          #B16E60;
  --ink:          #6E5147;   /* warm brown text */
  --ink-soft:     #7A594C;   /* darkened for contrast on blush backgrounds */
  --ink-faint:    rgba(94,68,58,.72);
  --shadow:       rgba(99,64,52,.18);

  /* ── Gold foil ── */
  --gold-1:       #9A7B33;
  --gold-2:       #C9A24B;
  --gold-3:       #F1DBA0;
  --gold-4:       #B88A3C;
  --gold-hi:      #FBF1CF;

  /* ── Type ── */
  --serif:  "Cormorant Garamond", "Times New Roman", serif;
  --script: "Pinyon Script", cursive;
  --sans:   "Jost", system-ui, sans-serif;

  /* ── Motion ── */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  --vh: 1vh;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--cream);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Lenis */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

::selection { background: var(--rose); color: var(--cream); }

/* =====================================================================
   ATMOSPHERE — global texture overlays
   ===================================================================== */

/* Soft warm radial wash + film grain that sits over everything */
.atmosphere {
  position: fixed; inset: 0; pointer-events: none; z-index: 60;
}
.atmosphere .vignette {
  position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 50% 35%,
              transparent 40%, rgba(120,78,62,.10) 78%, rgba(95,58,44,.26) 100%);
  mix-blend-mode: multiply;
}
.grain {
  position: fixed; inset: -50%; pointer-events: none; z-index: 61;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grainShift 6s steps(6) infinite;
}
@keyframes grainShift {
  0%{transform:translate(0,0)} 16%{transform:translate(-4%,2%)}
  33%{transform:translate(3%,-3%)} 50%{transform:translate(-3%,4%)}
  66%{transform:translate(4%,2%)} 83%{transform:translate(-2%,-4%)} 100%{transform:translate(0,0)}
}

/* Damask corner flourishes (repeatable filigree) */
.damask {
  position: absolute; width: 240px; height: 240px; pointer-events: none;
  opacity: .22; color: var(--gold-4);
  background-repeat: no-repeat; background-size: contain;
}

/* =====================================================================
   GOLD FOIL TEXT
   ===================================================================== */
/* Rich antique gold. The travelling highlight stays a warm champagne —
   never white — so the lettering keeps its contrast on light backgrounds
   at every point of the sweep. */
.foil {
  background: linear-gradient(100deg,
      #8A6524 0%, #B08432 18%, var(--gold-2) 34%,
      #E8CC86 48%, var(--gold-2) 62%, #A87C2E 80%, #8A6524 100%);
  background-size: 210% auto;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 1px 1px rgba(96,64,26,.34));
  animation: foilSweep 11s ease-in-out infinite;
}
@keyframes foilSweep {
  0%,100% { background-position: 12% center; }
  50%     { background-position: 88% center; }
}
/* On dark scenes the foil may run brighter without losing legibility.
   NB: the `background` shorthand resets background-clip, so it must be
   re-declared here or the gradient paints the whole box instead of the text. */
.on-dark .foil, .finale-inner .foil, .hero-type .foil {
  /* Against dark footage the deep bronze stops read as muddy, so this
     variant stays in the luminous champagne range end-to-end — the sweep
     shifts warmth, never brightness, keeping contrast constant. */
  background-image: linear-gradient(100deg,
      #D6B166 0%, #E7CD8E 22%, #F7EBC6 46%,
      #FFF6DC 52%, #F2DFAA 62%, #E0BE74 82%, #D6B166 100%);
  background-size: 210% auto;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.7)) drop-shadow(0 3px 14px rgba(0,0,0,.55));
}

/* =====================================================================
   TYPOGRAPHIC PRIMITIVES
   ===================================================================== */
.eyebrow {
  font-family: var(--sans);
  font-weight: 300;
  letter-spacing: .42em;
  text-transform: uppercase;
  font-size: clamp(.58rem, 2.6vw, .72rem);
  color: var(--ink-soft);
}
.serif-caps {
  font-family: var(--serif);
  font-weight: 500;
  letter-spacing: .34em;
  text-transform: uppercase;
}
.script {
  font-family: var(--script);
  font-weight: 400;
  /* Pinyon Script's swashes overshoot the text box on every side. Because
     `background-clip: text` only paints the gradient inside that box, any
     overshoot rendered transparent — letters looked sliced. Padding grows
     the paint area so whole glyphs are always filled. */
  line-height: 1.2;
  /* Horizontal padding must clear the SWASH OVERHANG, not just the advance
     width. Measured with TextMetrics, Pinyon's terminal letters (the P in
     RSVP) overhang their advance by ~0.24em; anything less leaves the tail
     outside the painted box, where background-clip:text renders it invisible. */
  padding: .18em .3em .2em;
}
.divider {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .8rem; color: var(--gold-4); opacity: .85;
}
.divider::before, .divider::after {
  content: ""; height: 1px; width: clamp(36px, 12vw, 80px);
  background: linear-gradient(90deg, transparent, var(--gold-4), transparent);
}

/* =====================================================================
   SECTION SCAFFOLD
   ===================================================================== */
.stage {
  position: relative;
  width: 100%;
  /* Sections breathe but hug their content — the gradient background belongs
     to the section itself, so it always fills exactly, with no dead space. */
  min-height: 62svh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding: clamp(3rem, 8vh, 4.6rem) clamp(1.5rem, 6vw, 4rem);
  overflow: hidden;
}
.stage > .inner { max-width: 560px; width: 100%; position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center; gap: clamp(.45rem, 1.4vh, .8rem); }
/* Section headings sit tight to the eyebrow above them */
.stage .script { margin-top: -.1rem !important; }

/* =====================================================================
   CARD SURFACE — one shared, elegant panel used across the sections so
   the whole invitation reads as a single stationery set.
   ===================================================================== */
.hotel-card, .detail-card, .gift-card, .countdown-wrap, .program-card, .dress-img {
  background: linear-gradient(168deg, rgba(255,252,248,.94), rgba(252,244,236,.86));
  border: 1px solid rgba(184,138,60,.28);
  border-radius: 12px;
  box-shadow: 0 1px 0 rgba(255,255,255,.75) inset,
              0 18px 40px -28px rgba(90,58,44,.55),
              0 3px 10px -6px rgba(90,58,44,.18);
  backdrop-filter: blur(3px);
}
/* A hairline gold keyline just inside the edge — letterpress feel */
.hotel-card, .gift-card, .program-card { position: relative; }
.hotel-card::after, .gift-card::after, .program-card::after {
  content: ""; position: absolute; inset: 5px; border-radius: 8px;
  border: 1px solid rgba(201,162,75,.16); pointer-events: none;
}
.hotel-card { transition: transform .5s var(--ease), box-shadow .5s var(--ease); }
.hotel-card:hover { transform: translateY(-3px);
  box-shadow: 0 1px 0 rgba(255,255,255,.8) inset, 0 26px 50px -28px rgba(90,58,44,.6); }

/* Botanical rose line-art framing each scene (injected by JS) — fine,
   engraved, and quiet enough to sit behind the typography. */
.floral { position: absolute; z-index: 0; pointer-events: none; color: var(--rose-deep);
  width: clamp(104px, 30vw, 190px); opacity: .3; }
.floral svg { width: 100%; height: auto; display: block; }
.floral-tl { top: -14px; left: -26px; transform: rotate(-8deg); }
.floral-br { bottom: -14px; right: -26px; transform: rotate(172deg); }
@media (max-width: 480px) { .floral { opacity: .24; width: clamp(92px, 27vw, 140px); } }

/* Layered warm backgrounds. Each scene is built from three passes — a soft
   light bloom from above, a warm floor tone, and a faint blush corner wash —
   so the page reads like tinted paper catching light, not a flat fill. */
.bg-cream  { background:
  radial-gradient(88% 58% at 50% 6%,  rgba(255,252,247,.95) 0%, rgba(255,252,247,0) 62%),
  radial-gradient(120% 80% at 12% 100%, rgba(231,199,190,.34) 0%, rgba(231,199,190,0) 60%),
  linear-gradient(180deg, var(--cream) 0%, #F7EEE3 42%, var(--cream-deep) 100%); }
.bg-blush  { background:
  radial-gradient(85% 55% at 50% 4%,  rgba(255,247,242,.85) 0%, rgba(255,247,242,0) 60%),
  radial-gradient(110% 75% at 88% 96%, rgba(214,168,156,.40) 0%, rgba(214,168,156,0) 62%),
  linear-gradient(180deg, var(--blush-soft) 0%, var(--blush) 58%, #E0BAB0 100%); }
.bg-rose   { background:
  radial-gradient(90% 60% at 50% 8%, rgba(255,240,234,.55) 0%, rgba(255,240,234,0) 62%),
  linear-gradient(180deg, var(--blush) 0%, var(--rose) 62%, var(--rose-deep) 100%); }
.bg-deep   { background:
  radial-gradient(100% 70% at 50% 10%, rgba(255,236,228,.32) 0%, rgba(255,236,228,0) 60%),
  linear-gradient(180deg, var(--rose) 0%, var(--rose-deep) 55%, var(--wax) 100%); }

/* A woven linen tooth over every scene — texture you feel more than see. */
.stage::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  opacity: .5; mix-blend-mode: multiply;
  background-image:
    repeating-linear-gradient(90deg, rgba(150,110,92,.045) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg,  rgba(150,110,92,.035) 0 1px, transparent 1px 3px);
}
/* Feathered seams so neighbouring scenes melt together instead of banding */
.stage::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: clamp(48px, 9vh, 96px);
  z-index: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,250,244,0), rgba(255,250,244,.5));
}
.bg-blush::after { background: linear-gradient(180deg, rgba(240,216,207,0), rgba(244,233,221,.55)); }
.bg-cream + .bg-cream::after { opacity: .6; }

/* =====================================================================
   PARTICLES (gold dust / bokeh)
   ===================================================================== */
.particles { position: absolute; inset: 0; pointer-events: none; z-index: 1; overflow: hidden; }
.particle {
  position: absolute; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--gold-hi), rgba(201,162,75,.0) 70%);
  opacity: 0; will-change: transform, opacity;
}

/* =====================================================================
   OPENING — tap to open, then it plays out. One full-screen scene: the
   envelope card waits for a tap, plays, dissolves into Video 1, holds its
   final frame, the text animates in, then the page unlocks.
   ===================================================================== */
.opening-scene { position: relative; height: 100svh; height: 100dvh; overflow: hidden;
  background: #1a0f0c; z-index: 1; cursor: pointer; }
.opening-sticky { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden;
  display: flex; align-items: center; justify-content: center; }
.opening-video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  pointer-events: none; background: #1a0f0c; will-change: opacity;
}
#video1 { z-index: 1; }                                   /* couple film, beneath */
#introVideo.card-video { z-index: 2; transition: opacity 1.6s cubic-bezier(.4,0,.3,1); }
#introVideo.card-video.faded { opacity: 0; }              /* card cross-dissolves → Video 1 */
.opening-scene.is-playing .film-cue { opacity: 0; transform: translate(-50%,-50%) scale(.94); }
.film-cue { transition: opacity .9s var(--ease), transform .9s var(--ease); }

/* =====================================================================
   LOADING VEIL — shown until the films can play through at full quality.
   Reads as part of the stationery, not as a technical spinner.
   ===================================================================== */
.loader {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background:
    radial-gradient(90% 60% at 50% 34%, #FBF3E9 0%, #F4E9DD 46%, #E9D8C8 100%);
  transition: opacity 1.1s var(--ease), visibility 1.1s var(--ease);
}
.loader.is-done { opacity: 0; visibility: hidden; }
.loader-inner { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; padding: 2rem; }

.loader-mono {
  font-size: clamp(3.2rem, 12vw, 4.6rem); line-height: 1;
  animation: monoBreathe 3.6s ease-in-out infinite;
}
@keyframes monoBreathe { 0%,100% { opacity: .78; } 50% { opacity: 1; } }

/* A hairline that fills with real buffering progress — honest feedback
   without looking like a download manager. */
.loader-track {
  width: clamp(140px, 42vw, 230px); height: 1px;
  background: rgba(110,81,71,.16); overflow: hidden; border-radius: 2px;
}
.loader-track span {
  display: block; height: 100%; width: 100%;
  transform: scaleX(0); transform-origin: left center;
  background: linear-gradient(90deg, var(--gold-4), var(--gold-2) 55%, var(--gold-3));
  box-shadow: 0 0 8px rgba(201,162,75,.65);
  transition: transform .5s var(--ease);
}
.loader-word {
  font-family: var(--sans); font-weight: 300; font-size: .58rem;
  letter-spacing: .34em; text-transform: uppercase; text-indent: .34em;
  color: var(--ink-soft);
  transition: opacity .5s var(--ease);
}
/* Slow connections: reassure rather than look stalled */
.loader.is-slow .loader-word { opacity: .85; }

@media (prefers-reduced-motion: reduce) {
  .loader-mono { animation: none; }
}

/* Lock the page while the intro plays */
html.intro-lock, html.intro-lock body { overflow: hidden !important; height: 100%;
  touch-action: none; overscroll-behavior: none; }

/* Scroll cue — invites the gesture, no button */
.film-cue {
  position: absolute; left: 50%; bottom: clamp(24px, 6vh, 46px); transform: translateX(-50%);
  z-index: 4; display: flex; flex-direction: column; align-items: center; gap: .6rem;
  color: rgba(244,233,221,.85); transition: opacity .6s var(--ease);
}
.film-cue .label {
  font-family: var(--sans); font-weight: 300; font-size: .6rem;
  letter-spacing: .34em; text-transform: uppercase;
}
.film-cue .line {
  width: 1px; height: 42px; position: relative; overflow: hidden;
  background: linear-gradient(rgba(244,233,221,.7), transparent);
}
.film-cue .line::after {
  content: ""; position: absolute; top: -40%; left: 0; width: 100%; height: 40%;
  background: var(--gold-3); animation: cueDrop 2.2s var(--ease) infinite;
}
/* Tap prompt — the card artwork behind it is pale cream, so light text
   vanished. A deep wax-toned pill guarantees contrast on any frame. */
/* The prompt only becomes visible and clickable once the films are genuinely
   playable. start() re-checks the flag too — CSS alone is not the gate. */
.tap-cue { bottom: clamp(56px, 12vh, 100px); top: auto; transform: translateX(-50%);
  opacity: 0; pointer-events: none; }
.opening-scene.is-ready .tap-cue { opacity: 1; pointer-events: auto; }
/* Once the film is running the prompt must go, even though .is-ready is still
   set. Both classes are present at that moment and the two rules have equal
   specificity, so this one needs the extra class to win outright — relying on
   source order alone is what left the prompt stuck on screen. */
.opening-scene.is-ready.is-playing .tap-cue { opacity: 0; pointer-events: none; }
.tap-cue .label {
  font-size: .66rem; letter-spacing: .38em; text-indent: .38em;
  color: #FCF3E4; padding: .82rem 1.65rem;
  background: linear-gradient(180deg, rgba(78,40,30,.82), rgba(52,25,18,.88));
  border: 1px solid rgba(241,219,160,.55); border-radius: 999px;
  box-shadow: 0 10px 30px -12px rgba(40,18,12,.7), 0 0 0 6px rgba(255,246,225,.10);
  backdrop-filter: blur(3px);
  animation: tapBreathe 3s ease-in-out infinite;
}
@keyframes tapBreathe {
  0%,100% { box-shadow: 0 10px 30px -12px rgba(40,18,12,.7), 0 0 0 6px rgba(255,246,225,.10); }
  50%     { box-shadow: 0 10px 30px -12px rgba(40,18,12,.7), 0 0 0 15px rgba(255,246,225,0); }
}

/* Soft edge darkening over the opening films (keeps text legible) */
.hero-vignette { position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: radial-gradient(120% 92% at 50% 42%, transparent 62%, rgba(30,16,11,.34) 100%); }

/* Invitation typography over Video 1's final frame — top group and bottom
   group frame the couple; gold script + gold flourishes, legible via soft
   glyph shadows (no dark box). */
.hero-type { position: absolute; inset: 0; z-index: 5; pointer-events: none;
  display: flex; flex-direction: column; justify-content: space-between; align-items: center;
  text-align: center; padding: clamp(2.6rem, 9vh, 5rem) 1.3rem clamp(2.4rem, 8vh, 4.5rem); }
.hero-type[hidden] { display: none; }
/* Slow, cinematic entrance for each line (JS only flips the end state —
   without this the lines snapped in instantly). */
.hero-type [data-r] {
  transition: opacity 1.05s var(--ease), transform 1.25s var(--ease), filter 1.05s var(--ease);
  will-change: opacity, transform, filter;
}
.ht-top, .ht-bottom { display: flex; flex-direction: column; align-items: center;
  gap: clamp(.5rem, 1.7vh, .95rem); }

.ht-eyebrow { font-family: var(--sans); font-weight: 300; letter-spacing: .34em; text-transform: uppercase;
  font-size: clamp(.6rem, 2.9vw, .8rem); line-height: 1.65; color: rgba(248,239,228,.96);
  text-shadow: 0 1px 4px rgba(0,0,0,.6); }

.ht-invited { font-family: var(--script); font-size: clamp(3.2rem, 17vw, 5.4rem); line-height: .8;
  filter: drop-shadow(0 2px 10px rgba(0,0,0,.5)); }

.ht-names { display: flex; flex-direction: column; align-items: center; line-height: .78; }
.ht-name { font-family: var(--script); font-size: clamp(3.4rem, 19vw, 5.8rem); color: #fdf7ee;
  text-shadow: 0 2px 16px rgba(0,0,0,.6), 0 1px 3px rgba(0,0,0,.55); }
.ht-amp { font-family: var(--script); font-size: clamp(1.9rem, 9vw, 3rem); line-height: 1; margin: -.12em 0;
  filter: drop-shadow(0 2px 8px rgba(0,0,0,.5)); }

/* small gold flourish divider */
.ht-orn { display: inline-flex; align-items: center; justify-content: center; gap: .55rem; color: var(--gold-3); }
.ht-orn::before, .ht-orn::after { content: ""; width: clamp(24px, 9vw, 42px); height: 1px; }
.ht-orn::before { background: linear-gradient(90deg, transparent, var(--gold-3)); }
.ht-orn::after  { background: linear-gradient(90deg, var(--gold-3), transparent); }
.ht-orn i { width: 5px; height: 5px; background: var(--gold-3); transform: rotate(45deg);
  box-shadow: 0 0 6px rgba(201,162,75,.7); }

/* =====================================================================
   TWO BECOME ONE — gold rings emblem (lightweight SVG, no WebGL)
   ===================================================================== */
.rings-title {
  font-family: var(--serif); font-weight: 500; letter-spacing: .16em;
  font-size: clamp(1.6rem, 6.5vw, 2.4rem); text-transform: none;
}
.rings-sub {
  font-family: var(--serif); font-style: italic;
  font-size: clamp(.98rem, 3.8vw, 1.18rem); letter-spacing: .02em;
}
.ring-emblem {
  width: min(60vw, 250px); height: auto; display: block; margin: .4rem auto .6rem;
  overflow: visible; animation: emblemGlow 4.5s ease-in-out infinite;
}
.ring-emblem .ring {
  stroke-linecap: round; stroke-dasharray: 315; stroke-dashoffset: 315;
  transform-box: fill-box; transform-origin: center;
}
/* Draw the rings in when the scene enters view (buildScenes adds .in-view) */
.in-view .ring-emblem .ring { animation: ringDraw 2.2s var(--ease) forwards; }
.in-view .ring-emblem .ring-b { animation-delay: .45s; }
@keyframes ringDraw { to { stroke-dashoffset: 0; } }
@keyframes emblemGlow {
  0%, 100% { filter: drop-shadow(0 0 10px rgba(201,162,75,.35)); }
  50%      { filter: drop-shadow(0 0 22px rgba(241,219,160,.7)); }
}

/* Scroll-cue drop animation (shared by the opening film cue) */
@keyframes cueDrop { 0%{top:-40%} 60%,100%{top:100%} }

/* =====================================================================
   REVEAL PRIMITIVES (driven by GSAP, but safe defaults)
   ===================================================================== */
/* Reveal items: hidden until an IntersectionObserver adds `.in`. Pure CSS
   transitions guarantee completion (no animation-engine edge cases). The
   intro overlay covers the page during boot so the hidden start never flashes;
   `.no-js` / reduced-motion fall back to fully visible. */
/* A restrained rise — slower and softer than a standard fade-up, with the
   transform easing longer than the opacity so it settles rather than stops. */
.reveal {
  opacity: 0; transform: translateY(18px); filter: blur(4px);
  transition: opacity 1.4s var(--ease), transform 1.7s var(--ease), filter 1.4s var(--ease);
  will-change: opacity, transform, filter;
}
.reveal.in { opacity: 1; transform: none; filter: blur(0); }
.line-mask { overflow: hidden; display: block; }
.line-mask > * { display: block; will-change: transform; }

/* Big display names */
.names {
  font-family: var(--serif); font-weight: 500;
  font-size: clamp(3.2rem, 17vw, 6rem); line-height: .98; letter-spacing: .02em;
}
.names .amp { font-family: var(--script); font-size: .8em; display: inline-block;
  padding: 0 .12em; vertical-align: -.06em; }

/* Date display */
.date-grid { display: flex; align-items: center; justify-content: center; gap: clamp(1rem,5vw,2.2rem); }
.date-grid .num { font-family: var(--serif); font-weight: 500; font-size: clamp(4rem, 26vw, 9rem); line-height: .8; }
.date-grid .stack { display: flex; flex-direction: column; gap: .4rem; }
.date-grid .stack span { font-family: var(--serif); letter-spacing:.2em; text-transform: uppercase;
  font-size: clamp(.9rem, 4.4vw, 1.3rem); }

/* Countdown */
.countdown { display:flex; gap: clamp(.8rem,4vw,1.6rem); justify-content:center; }
.countdown .unit { display:flex; flex-direction:column; align-items:center; min-width: 54px; }
.countdown .unit b { font-family: var(--serif); font-weight: 500; font-size: clamp(1.6rem,8vw,2.4rem); line-height:1; }
.countdown .unit span { font-size:.52rem; letter-spacing:.28em; text-transform:uppercase; color: var(--ink-soft); margin-top:.5rem; }

/* Soft light panel behind the timer */
.countdown-wrap {
  position: relative; margin: 1.4rem auto 0; padding: 1.25rem clamp(1.1rem, 4vw, 1.7rem);
  overflow: hidden; display: inline-flex;
}
.countdown-bg {                                    /* soft blush floral wash */
  position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .5;
  background: radial-gradient(90% 120% at 15% 0%, rgba(231,199,190,.5), transparent 55%),
              radial-gradient(90% 120% at 85% 100%, rgba(214,168,156,.4), transparent 55%);
}
.countdown-wrap .countdown { position: relative; z-index: 1; }
.countdown .unit b { color: var(--ink); }          /* dark digits on the light panel */

/* =====================================================================
   SECTION 5 — TIMELINE
   ===================================================================== */
.timeline { position: relative; width: 100%; max-width: 460px; margin: 2rem auto 0; text-align: left; }
.timeline .spine { position:absolute; left: 16px; top: 8px; bottom: 8px; width: 1px;
  background: linear-gradient(var(--gold-4), rgba(184,138,60,.15)); }
.tl-item { position: relative; padding: 0 0 2.6rem 48px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-dot { position:absolute; left: 9px; top: 6px; width: 15px; height: 15px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--gold-hi), var(--gold-4));
  box-shadow: 0 0 0 4px rgba(244,233,221,.7), 0 0 14px rgba(201,162,75,.6); }
.tl-year { font-family: var(--serif); font-style: italic; color: var(--rose-deep); letter-spacing:.1em; font-size: 1.05rem; }
.tl-title { font-family: var(--serif); font-weight:600; letter-spacing:.06em; font-size: 1.3rem; margin: .15rem 0 .4rem; }
.tl-text { font-weight: 300; line-height: 1.65; color: var(--ink-soft); font-size: .92rem; }

/* =====================================================================
   SECTION 6 — DETAILS
   ===================================================================== */
.detail-cards { display: grid; gap: 1rem; width: 100%; max-width: 460px; margin: 1.6rem auto 0; }
.detail-card { position: relative; padding: 1.6rem 1.4rem; text-align: center; }
.detail-card .dc-label { font-family: var(--serif); font-style: italic; color: var(--rose-deep); font-size: 1rem; letter-spacing:.08em; }
.detail-card .dc-venue { font-family: var(--serif); font-weight: 600; font-size: 1.35rem; margin: .3rem 0; letter-spacing:.04em; }
.detail-card .dc-meta { font-weight: 300; font-size: .82rem; color: var(--ink-soft); line-height: 1.5; }
.map-frame { width: 100%; max-width: 460px; margin: 1.2rem auto 0; border-radius: 6px; overflow: hidden;
  border: 1px solid rgba(184,138,60,.35); box-shadow: 0 20px 50px -28px var(--shadow); aspect-ratio: 16/10;
  filter: sepia(.18) saturate(.9) contrast(.96); }
.map-frame iframe { width:100%; height:100%; border:0; display:block; }

/* Buttons */
/* Solid warm-ink pill. The old translucent cream button all but vanished on
   the blush sections, so the primary action didn't read as an action at all. */
.btn-foil {
  display:inline-flex; align-items:center; gap:.6rem;
  font-family: var(--sans); font-weight:500; letter-spacing:.22em; text-transform:uppercase; font-size:.7rem;
  padding: 1rem 2.1rem; border-radius: 999px; cursor:pointer;
  color: #FDF6EA;
  background: linear-gradient(180deg, #7C4C3E, #5C3428);
  border: 1px solid rgba(241,219,160,.5);
  box-shadow: 0 12px 28px -14px rgba(70,38,28,.75), inset 0 1px 0 rgba(255,232,200,.22);
  transition: transform .45s var(--ease), box-shadow .45s var(--ease), letter-spacing .45s var(--ease);
}
.btn-foil:hover {
  letter-spacing:.28em; transform: translateY(-2px); border-color: var(--gold-3);
  box-shadow: 0 18px 36px -14px rgba(70,38,28,.82), inset 0 1px 0 rgba(255,232,200,.3);
}
.btn-foil:active { transform: translateY(0); }

/* =====================================================================
   SECTION 7 — GALLERY
   ===================================================================== */
.gallery-grid { display:grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; width:100%; max-width: 520px; margin: 1.6rem auto 0; }
.gal {
  position: relative; overflow: hidden; border-radius: 4px; aspect-ratio: .72;
  box-shadow: 0 22px 44px -26px var(--shadow); border: 1px solid rgba(184,138,60,.28);
}
.gal:nth-child(3n) { grid-column: span 2; aspect-ratio: 1.5; }
.gal img { width:100%; height:100%; object-fit: cover; display:block; transform: scale(1.06);
  transition: transform 1.4s var(--ease), filter 1.4s var(--ease);
  filter: sepia(.16) saturate(.92) brightness(1.02); will-change: transform; }
.gal:hover img { transform: scale(1.0); filter: sepia(.05) saturate(1); }
.gal .cap { position:absolute; left:0; right:0; bottom:0; padding: 1.4rem .9rem .8rem; text-align:left;
  font-family: var(--serif); font-style: italic; font-size: .92rem; color: #fff;
  background: linear-gradient(transparent, rgba(90,55,42,.6)); letter-spacing:.04em;
  opacity:0; transform: translateY(8px); transition: all .6s var(--ease); }
.gal:hover .cap { opacity:1; transform: translateY(0); }

/* =====================================================================
   SECTION 8 — RSVP
   ===================================================================== */
.rsvp-form { width:100%; max-width: 440px; margin: 1.6rem auto 0; display:flex; flex-direction:column; gap: 1.1rem; text-align:left; }
.field { position: relative; }
.field input, .field select, .field textarea {
  width:100%; background: transparent; border:0; border-bottom: 1px solid rgba(110,81,71,.3);
  padding: .7rem .2rem; font-family: var(--sans); font-weight:300; font-size: .95rem; color: var(--ink);
  outline: none; transition: border-color .4s var(--ease);
}
.field textarea { resize: none; min-height: 64px; }
.field label {
  position:absolute; left: .2rem; top: .7rem; pointer-events:none; color: var(--ink-faint);
  font-weight:300; letter-spacing:.04em; transition: all .35s var(--ease);
}
.field input:focus ~ label, .field input:not(:placeholder-shown) ~ label,
.field textarea:focus ~ label, .field textarea:not(:placeholder-shown) ~ label,
.field.filled label {
  top: -.7rem; font-size: .6rem; letter-spacing: .26em; text-transform: uppercase; color: var(--rose-deep);
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--gold-2); }
.field select { color: var(--ink); }
.seg { display:flex; gap:.6rem; }
.seg .opt { flex:1; text-align:center; padding:.8rem; border:1px solid rgba(110,81,71,.3); border-radius:4px;
  cursor:pointer; font-size:.72rem; letter-spacing:.18em; text-transform:uppercase; color: var(--ink-soft);
  transition: all .4s var(--ease); }
.seg .opt.active { border-color: var(--gold-2); color: var(--wax); background: rgba(244,233,221,.35); }

/* --- Legibility on the blush sections ------------------------------------
   Rose-tinted small caps on a rose background were washing out; deepen the
   labels and field text so every word is readable on the pink. */
.bg-blush .field input, .bg-blush .field select, .bg-blush .field textarea { color: #4E332A; }
.bg-blush .field label { color: rgba(78,51,42,.72); }
.bg-blush .field input, .bg-blush .field select, .bg-blush .field textarea {
  border-bottom-color: rgba(78,51,42,.38);
}
.bg-blush .seg .opt { color: #5E3F34; border-color: rgba(78,51,42,.34); }
.bg-blush .seg .opt.active { color: #4A2A20; background: rgba(255,250,244,.55); border-color: var(--gold-4); }
/* the small uppercase captions above the controls */
.bg-blush [style*="--rose-deep"], .bg-blush .eyebrow { color: #8A4F42 !important; }
.bg-blush [data-deadline] { color: #5E3F34 !important; }
.rsvp-success { text-align:center; }

/* =====================================================================
   SECTION 9 — FAREWELL
   ===================================================================== */
.farewell .quote { font-family: var(--serif); font-style: italic; font-size: clamp(1.3rem, 6vw, 1.9rem);
  line-height: 1.5; color: var(--ink); }
.farewell .sign { font-family: var(--script); font-size: clamp(2.6rem, 13vw, 4rem); color: var(--gold-4); }

/* =====================================================================
   SCROLL PROGRESS — a slim gold line along the bottom edge
   ===================================================================== */
.scroll-prog { position: fixed; left: 0; right: 0; bottom: 0; height: 2px; z-index: 70;
  background: rgba(110,81,71,.10); pointer-events: none; }
.scroll-prog span { display: block; height: 100%; transform-origin: left center; transform: scaleX(0);
  background: linear-gradient(90deg, var(--gold-4), var(--gold-2) 50%, var(--gold-3));
  box-shadow: 0 0 10px rgba(201,162,75,.6); }

/* =====================================================================
   CINEMATIC PHOTOGRAPHIC SCENES  (Phase 5)
   The scene background belongs to the SECTION and fills it edge to edge:
   position:absolute; inset:0; object-fit:cover. A slight scale gives the
   parallax (set in JS) headroom so the image always covers — the page
   background is never exposed above or below.
   ===================================================================== */
.scene-bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.scene-bg img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center;
  display: block; filter: sepia(.20) saturate(.92) contrast(1.02) brightness(.97);
  transform: scale(1.12); will-change: transform; backface-visibility: hidden;
}
.scene-bg::after { content: ""; position: absolute; inset: 0; }

/* Every content section is photo-forward: the wedding image stays clearly
   visible, with a graded scrim that keeps light text legible on top. */
.cine .scene-bg img { opacity: 1; }
.cine-dark .scene-bg::after {
  background:
    radial-gradient(120% 92% at 50% 40%, rgba(28,15,11,.14) 0%, rgba(24,13,10,.46) 66%, rgba(16,8,6,.72) 100%),
    linear-gradient(180deg, rgba(20,11,8,.5), rgba(20,11,8,.2) 44%, rgba(14,7,5,.66));
}
.cine > .inner { position: relative; z-index: 3; }
.cine > .particles, .cine > .rays { z-index: 2; }

/* Legibility — relight inline warm-ink text so it reads over photography */
.cine-dark { color: var(--cream); }
.cine-dark .inner { text-shadow: 0 2px 26px rgba(14,7,5,.7); }
.cine-dark .eyebrow,
.cine-dark .serif-caps,
.cine-dark [data-invsub],
.cine-dark [data-hashtag],
.cine-dark [data-weekday],
.cine-dark [data-time],
.cine-dark [data-month],
.cine-dark [data-year],
.cine-dark [data-dress],
.cine-dark .tl-title,
.cine-dark .quote,
.cine-dark p:not(.foil) { color: rgba(246,237,226,.94) !important; }
.cine-dark .tl-year { color: var(--gold-3) !important; }
.cine-dark .divider { color: var(--gold-3) !important; opacity: 1; }
.cine-dark .countdown .unit b { color: var(--cream); }
.cine-dark .countdown .unit span { color: rgba(246,237,226,.72); }

/* RSVP form over photography — light fields, gold focus */
.cine-dark .field input, .cine-dark .field select, .cine-dark .field textarea {
  color: var(--cream); border-bottom-color: rgba(244,233,221,.4);
}
.cine-dark .field label { color: rgba(244,233,221,.62); }
.cine-dark .field select option { color: var(--ink); }
.cine-dark .seg .opt { color: rgba(246,237,226,.85); border-color: rgba(244,233,221,.32); }
.cine-dark .seg .opt.active { color: var(--gold-hi); border-color: var(--gold-2); background: rgba(244,233,221,.12); }
/* Detail cards get a translucent dark surface so they sit on the photo */
.cine-dark .detail-card {
  background: linear-gradient(180deg, rgba(30,17,12,.5), rgba(20,11,8,.42));
  border-color: rgba(201,162,75,.4);
}
.cine-dark .detail-card .dc-venue { color: var(--cream); }
.cine-dark .detail-card .dc-label, .cine-dark .detail-card .dc-meta { color: rgba(246,237,226,.85); }

/* =====================================================================
   LIGHT RAYS — soft volumetric god-rays that bloom in on reveal
   ===================================================================== */
.rays { position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  opacity: 0; transition: opacity 2s var(--ease); mix-blend-mode: screen; }
.cine.in-view .rays { opacity: .55; }
.rays span {
  position: absolute; top: -60%; left: var(--x, 50%); width: var(--w, 38%); height: 200%;
  background: linear-gradient(180deg, rgba(255,239,201,.30), rgba(255,239,201,0) 72%);
  transform-origin: top center; transform: translateX(-50%) rotate(var(--r, 0deg));
  filter: blur(10px); animation: rayBreathe 9s ease-in-out infinite alternate;
}
@keyframes rayBreathe { 0%{opacity:.4} 100%{opacity:.9} }

/* =====================================================================
   FLOATING PETALS — drifting rose petals across the whole experience
   (canvas drawn in JS; this just positions the fixed layer)
   ===================================================================== */
#petalDrift { position: fixed; inset: 0; z-index: 58; pointer-events: none; }

/* =====================================================================
   OUR STORY — photos slide in from the sides, alternating
   ===================================================================== */
.story-list { display: flex; flex-direction: column; gap: clamp(1.6rem, 5vh, 2.8rem); width: 100%; margin-top: .4rem; }
.story-item { display: flex; align-items: center; gap: clamp(1rem, 4vw, 1.7rem); text-align: left;
  opacity: 0; transition: opacity .9s var(--ease), transform .9s var(--ease); will-change: opacity, transform; }
.story-item.from-left  { transform: translateX(-9%); }
.story-item.from-right { transform: translateX(9%); flex-direction: row-reverse; text-align: right; }
.story-item.in { opacity: 1; transform: none; }
.story-photo { flex: 0 0 44%; max-width: 44%; border-radius: 8px; overflow: hidden; aspect-ratio: 4 / 3;
  box-shadow: 0 22px 46px -26px var(--shadow); border: 1px solid rgba(184,138,60,.3); }
.story-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.story-copy { flex: 1; }
.story-chapter { font-family: var(--serif); font-weight: 600; font-style: italic; color: var(--rose-deep);
  font-size: clamp(1.05rem, 4.4vw, 1.4rem); letter-spacing: .02em; margin-bottom: .3rem; }
.story-text { font-weight: 400; line-height: 1.6; color: #6A4B40; font-size: clamp(.85rem, 3.4vw, .95rem); }

/* =====================================================================
   DAY PROGRAMME — slim gold-spine schedule
   ===================================================================== */
.program-card { width: 100%; max-width: 460px; margin: .5rem auto 0; padding: 1.5rem 1.4rem 1.4rem; }
.program { position: relative; width: 100%; text-align: left; }
.program::before { content: ""; position: absolute; left: 70px; top: 10px; bottom: 12px; width: 1px;
  background: linear-gradient(var(--gold-4), rgba(184,138,60,.15)); }
.prog-item { position: relative; display: grid; grid-template-columns: 62px 1fr; column-gap: 1.4rem; padding: 0 0 1.5rem; }
.prog-item:last-child { padding-bottom: 0; }
.prog-time { font-family: var(--serif); font-weight: 600; color: var(--wax); font-size: .82rem; text-align: right; padding-top: 2px; }
.prog-dot { position: absolute; left: 66px; top: 5px; width: 9px; height: 9px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--gold-hi), var(--gold-4));
  box-shadow: 0 0 0 3px rgba(244,233,221,.85), 0 0 10px rgba(201,162,75,.5); }
.prog-title { font-family: var(--serif); font-weight: 600; font-size: 1.06rem; letter-spacing: .04em; color: var(--ink); }
.prog-text { font-weight: 300; line-height: 1.5; color: var(--ink-soft); font-size: .84rem; margin-top: .1rem; }

/* =====================================================================
   DRESS CODE — inspiration image + colour palette
   ===================================================================== */
.dress-img { width: 100%; max-width: 520px; margin: 1rem auto .2rem; overflow: hidden; padding: 8px; }
.dress-img img { width: 100%; height: auto; display: block; border-radius: 7px; }
/* =====================================================================
   SHARE YOUR PHOTOS — guests contribute their own shots of the day
   ===================================================================== */
.share-card {
  width: 100%; max-width: 440px; margin: 1rem auto 0; padding: 2rem 1.7rem 1.7rem;
  display: flex; flex-direction: column; align-items: center; gap: .9rem;
  background: linear-gradient(168deg, rgba(255,252,248,.94), rgba(252,244,236,.86));
  border: 1px solid rgba(184,138,60,.28); border-radius: 12px; position: relative;
  box-shadow: 0 1px 0 rgba(255,255,255,.75) inset, 0 18px 40px -28px rgba(90,58,44,.55);
}
.share-card::after {
  content: ""; position: absolute; inset: 5px; border-radius: 8px;
  border: 1px solid rgba(201,162,75,.16); pointer-events: none;
}
.share-icon { width: 52px; height: auto; color: var(--gold-4); opacity: .9; }
.share-note { font-weight: 300; line-height: 1.62; color: var(--ink-soft); font-size: .9rem; }
.share-btn { margin-top: .2rem; text-decoration: none; }
.share-tag { font-size: .58rem; letter-spacing: .2em; text-transform: uppercase; color: var(--ink-faint); }
.share-tag b { font-weight: 500; color: var(--rose-deep); letter-spacing: .16em; }

/* =====================================================================
   ACCOMMODATION — hotel cards
   ===================================================================== */
.hotels { display: grid; gap: .9rem; width: 100%; max-width: 460px; margin: .4rem auto 0; text-align: left; }
.hotel-card { padding: 1.15rem 1.35rem; }
.hotel-top { display: flex; align-items: center; justify-content: space-between; gap: .8rem; margin-bottom: .3rem; }
.hotel-tag { font-size: .55rem; letter-spacing: .24em; text-transform: uppercase; color: var(--rose-deep); }
.stars { font-size: .74rem; letter-spacing: .1em; color: var(--gold-2); white-space: nowrap; }
.stars .star-dim { color: rgba(110,81,71,.22); }
.hotel-name { font-family: var(--serif); font-weight: 600; font-size: 1.16rem; letter-spacing: .03em; color: var(--ink); }
.hotel-text { font-weight: 300; font-size: .84rem; line-height: 1.5; color: var(--ink-soft); margin-top: .18rem; }
.hotel-contact { display: flex; flex-wrap: wrap; gap: .5rem .9rem; margin-top: .7rem;
  padding-top: .65rem; border-top: 1px solid rgba(110,81,71,.13); }
.hotel-link { font-size: .74rem; letter-spacing: .04em; color: var(--wax); text-decoration: none;
  border-bottom: 1px solid rgba(177,110,96,.35); transition: color .3s var(--ease), border-color .3s var(--ease); }
.hotel-link:hover { color: var(--gold-1); border-color: var(--gold-2); }

/* =====================================================================
   CELEBRATION CONFETTI
   ===================================================================== */
.confetti-canvas { position: fixed; inset: 0; z-index: 90; pointer-events: none; }

/* =====================================================================
   GIFTS — placeholder bank-details card
   ===================================================================== */
.gift-card { width: 100%; max-width: 420px; margin: 0 auto; padding: 1.5rem 1.6rem; text-align: left; }
.gift-title { font-size: .58rem; letter-spacing: .26em; text-transform: uppercase; color: var(--rose-deep); margin-bottom: .8rem; text-align: center; }
.gift-rows { display: flex; flex-direction: column; gap: .5rem; margin: 0; }
.gift-rows > div { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  padding-bottom: .5rem; border-bottom: 1px solid rgba(110,81,71,.12); }
.gift-rows > div:last-child { border-bottom: 0; padding-bottom: 0; }
.gift-rows dt { font-size: .58rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); flex: 0 0 auto; }
.gift-rows dd { margin: 0; font-family: var(--serif); font-weight: 600; color: var(--ink); font-size: .95rem; text-align: right; }

/* =====================================================================
   FINALE — full-screen "Can't wait" send-off image
   ===================================================================== */
.finale-scene { position: relative; min-height: 100svh; min-height: 100dvh; width: 100%; overflow: hidden;
  display: flex; align-items: center; justify-content: center; text-align: center; padding: 2rem 1.5rem; }
.finale-bg { position: absolute; inset: 0; z-index: 0; background-size: cover; background-position: center; transform: scale(1.06); }
/* Deep enough behind the words for the gold to read against a bright,
   sunlit photograph — graded so the couple stays visible. */
.finale-bg::after { content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(78% 46% at 50% 52%, rgba(20,10,7,.62), rgba(20,10,7,.30) 62%, transparent 82%),
    linear-gradient(180deg, rgba(18,9,6,.42), rgba(18,9,6,.20) 42%, rgba(14,7,5,.60)); }
.finale-inner { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.finale-inner .eyebrow { letter-spacing: .4em; text-shadow: 0 1px 6px rgba(0,0,0,.7); }

/* =====================================================================
   DESKTOP — the invitation opens up on a large screen. Wider measures,
   larger type, and two-column layouts where the content earns them.
   ===================================================================== */
@media (min-width: 900px) {
  .stage { min-height: 78svh; padding: clamp(4.5rem, 10vh, 7rem) 2.5rem; }
  .stage > .inner { max-width: 760px; gap: 1rem; }
  .eyebrow { font-size: .74rem; letter-spacing: .5em; }

  /* Opening typography scales with the wider frame */
  .ht-invited { font-size: clamp(4.5rem, 9vw, 7rem); }
  .ht-name    { font-size: clamp(4.2rem, 8.5vw, 6.6rem); }
  .ht-amp     { font-size: clamp(2.4rem, 4vw, 3.4rem); }
  .ht-eyebrow { font-size: .8rem; letter-spacing: .42em; }
  .hero-type  { padding: clamp(4rem, 9vh, 7rem) 2rem clamp(3.5rem, 8vh, 6rem); }

  /* Countdown reads as a proper feature */
  .countdown { gap: 2.6rem; }
  .countdown .unit { min-width: 84px; }
  .countdown .unit b { font-size: 3rem; }
  .countdown .unit span { font-size: .58rem; }
  .countdown-wrap { padding: 1.8rem 2.6rem; }

  /* Our story — roomier rows, larger plates */
  .story-list { gap: 3.4rem; max-width: 900px; }
  .story-item { gap: 2.6rem; }
  .story-photo { flex: 0 0 46%; max-width: 46%; aspect-ratio: 3 / 2; }
  .story-chapter { font-size: 1.75rem; }
  .story-text { font-size: 1.02rem; line-height: 1.72; }
  #s4 > .inner { max-width: 940px !important; }

  /* Programme + details side by side where it helps */
  .program-card { max-width: 620px; padding: 2.2rem 2.4rem; }
  .prog-item { grid-template-columns: 82px 1fr; column-gap: 1.9rem; padding-bottom: 1.9rem; }
  .program::before { left: 90px; }
  .prog-dot { left: 86px; }
  .prog-time { font-size: .95rem; }
  .prog-title { font-size: 1.24rem; }
  .prog-text { font-size: .95rem; }

  .detail-cards { grid-template-columns: 1fr 1fr; gap: 1.4rem; max-width: 720px; }
  .map-frame { max-width: 720px; aspect-ratio: 16/7; }

  /* Dress code + palette */
  #s7 > .inner { max-width: 820px !important; }
  .dress-img { max-width: 700px; }
  .swatch .chip { width: 58px; height: 58px; }
  .swatch .chip-name { font-size: .6rem; }

  /* Hotels in two columns */
  .hotels { grid-template-columns: 1fr 1fr; gap: 1.2rem; max-width: 820px; }
  #s-stay > .inner { max-width: 860px !important; }
  .hotel-name { font-size: 1.28rem; }
  .hotel-text { font-size: .9rem; }

  /* RSVP + gifts */
  .rsvp-form { max-width: 560px; }
  .gift-card { max-width: 520px; padding: 2rem 2.2rem; }
  .gift-rows dd { font-size: 1.05rem; }

  /* Florals scale up with the canvas */
  .floral { width: clamp(180px, 17vw, 280px); opacity: .26; }
  .floral-tl { top: -26px; left: -40px; }
  .floral-br { bottom: -26px; right: -40px; }

  .finale-inner .eyebrow { font-size: .82rem; }
}

/* ---------------------------------------------------------------------
   Landscape / desktop opening: the couple stand centre-left in the 16:9
   cut, so the words move into the open garden on the right instead of
   sitting over their faces. Grouped as one ranged-right column.
   NB: this must come AFTER the base .hero-type rule — equal specificity,
   so source order decides, and being earlier silently loses.
   --------------------------------------------------------------------- */
@media (min-width: 900px) and (min-aspect-ratio: 1/1) {
  /* The couple stand centre-frame, so the words open out to either side of
     them: the invitation on the left, their names on the right. Both groups
     sit vertically centred and run large, filling the width the desktop
     gives us instead of huddling in the middle. */
  .hero-type {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    padding: 0 clamp(2rem, 4.5vw, 4.5rem);
  }
  .ht-top, .ht-bottom {
    flex: 0 1 auto; max-width: 34%;
    gap: clamp(.7rem, 1.6vh, 1.2rem);
  }
  .ht-top    { align-items: flex-start; text-align: left; }
  .ht-bottom { align-items: flex-end;   text-align: right; }
  .ht-names  { align-items: flex-end; }

  .ht-eyebrow { font-size: clamp(.78rem, 1.15vw, 1rem); letter-spacing: .4em; line-height: 1.85; }
  .ht-invited { font-size: clamp(5rem, 8.6vw, 9rem); }
  .ht-name    { font-size: clamp(4.2rem, 7.2vw, 7.4rem); }
  .ht-amp     { font-size: clamp(2.2rem, 3.4vw, 3.4rem); }

  /* Darken both edges and leave the centre — where they're standing — clear. */
  .hero-vignette {
    background:
      linear-gradient(90deg,  rgba(26,14,10,.62) 0%, rgba(26,14,10,.30) 20%, transparent 40%),
      linear-gradient(270deg, rgba(26,14,10,.62) 0%, rgba(26,14,10,.30) 20%, transparent 40%),
      radial-gradient(120% 92% at 50% 42%, transparent 70%, rgba(30,16,11,.24) 100%);
  }
}

@media (min-width: 1400px) {
  .stage > .inner { max-width: 860px; }
  .story-list { max-width: 1040px; }
  #s4 > .inner { max-width: 1080px !important; }
  .story-chapter { font-size: 1.95rem; }
  .hotels, #s-stay > .inner { max-width: 940px; }
}

/* =====================================================================
   ACCESSIBILITY
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  .reveal { opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* Hide content until JS boots, to avoid FOUC of un-animated state */
.js-loading main { opacity: 0; }
