/* ═══════════════════════════════════════════════════════════
   ROYAL WEDDING INVITE — STYLES
   Mobile-first · 60fps · gold-on-maroon royal theme
   ═══════════════════════════════════════════════════════════ */

:root {
  --maroon: #6D1A33;
  --maroon-deep: #4A0F22;
  --gold: #C9A24B;
  --gold-soft: #E5C878;
  --ivory: #F4EBDB;
  --ink: #3A2230;
  --vh: 1vh; /* corrected by JS to avoid URL-bar jumps */
  --serif-display: "Cinzel", serif;
  --serif-body: "Cormorant Garamond", serif;
  --serif-dev: "Noto Serif Telugu", serif;
  --glass-fill: linear-gradient(145deg, rgba(255,255,255,.76), rgba(255,247,225,.54));
  --glass-stroke: rgba(255,255,255,.78);
  --glass-shadow: 0 14px 38px rgba(74,15,34,.14), inset 0 1px 0 rgba(255,255,255,.9), inset 0 -1px 0 rgba(201,162,75,.18);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: auto; }
body {
  font-family: var(--serif-body);
  background: var(--ivory);
  color: var(--ink);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
body.is-loading { overflow: hidden; }
.hidden { display: none !important; }
img { max-width: 100%; }
button { font-family: inherit; cursor: pointer; }
:where(a, button, input, select, textarea):focus-visible {
  outline: 3px solid var(--gold-soft);
  outline-offset: 3px;
}

/* Handmade-paper grain over everything — the single biggest "expensive" cue */
body::after {
  content: "";
  position: fixed; inset: 0;
  z-index: 66;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
  opacity: .05;
  mix-blend-mode: multiply;
}

/* ── Gold foil text ───────────────────────────────────────── */
.gold-foil {
  background: linear-gradient(105deg,
    #8a6a25 0%, var(--gold) 22%, #f6e7b6 40%, var(--gold-soft) 50%,
    #f9efc9 60%, var(--gold) 78%, #8a6a25 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  background-position: 50% 0;
}
@keyframes foil-sheen {
  0%, 100% { background-position: 0% 0; }
  50%      { background-position: 100% 0; }
}
.sec-head.shown .gold-foil { animation: foil-sheen 1.15s ease-out .15s both; }

.eyebrow {
  font-family: var(--serif-display);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold);
  opacity: .95;
}

/* ═══════════════ LOADER — THE SEAL ═══════════════ */
#loader {
  position: fixed; inset: 0; z-index: 100;
  display: grid; place-items: center;
  color: var(--gold);
  touch-action: none;
  overscroll-behavior: none;
}
.door {
  position: absolute; top: 0; bottom: 0; width: 51%;
  background:
    radial-gradient(120% 90% at 100% 50%, rgba(201,162,75,.14), transparent 55%),
    linear-gradient(160deg, #5a1429 0%, var(--maroon-deep) 55%, #350917 100%);
  transition: transform 1.5s cubic-bezier(.7, 0, .2, 1);
  will-change: transform;
}
.door-l { left: 0;  border-right: 1px solid rgba(201,162,75,.5);
  background-position: right center; }
.door-r { right: 0; border-left: 1px solid rgba(201,162,75,.5);
  transform: scaleX(-1); }
#loader.open .door-l { transform: translateX(-101%); }
#loader.open .door-r { transform: scaleX(-1) translateX(-101%); }
#loader.open .loader-center { opacity: 0; transform: scale(1.35); }
#loader.gone { display: none; }

.loader-center {
  position: relative; z-index: 2;
  display: grid; place-items: center;
  transition: opacity .8s ease, transform .9s ease;
}
#mandala {
  width: min(72vw, 320px); height: min(72vw, 320px);
  overflow: visible;
}
#mandala-spin { animation: spin 60s linear infinite; transform-origin: 0 0; }
@keyframes spin { to { transform: rotate(360deg); } }
#progress-ring { stroke-dasharray: 414.7; stroke-dashoffset: 414.7; transition: stroke-dashoffset .35s ease; }

#seal-btn {
  position: absolute;
  width: min(34vw, 148px); height: min(34vw, 148px);
  border-radius: 50%;
  border: none;
  background:
    radial-gradient(circle at 34% 30%, #8c2b47 0%, var(--maroon) 45%, var(--maroon-deep) 100%);
  box-shadow:
    0 10px 40px rgba(0,0,0,.55),
    inset 0 2px 10px rgba(255,220,160,.25),
    inset 0 -6px 16px rgba(0,0,0,.45);
  display: grid; place-items: center;
  transition: transform .3s ease, box-shadow .3s ease;
}
#seal-btn:disabled { opacity: .82; }
#seal-btn:not(:disabled) { animation: seal-pulse 2.2s ease-in-out infinite; }
@keyframes seal-pulse {
  0%,100% { transform: scale(1); }
  50%     { transform: scale(1.05); box-shadow: 0 14px 52px rgba(201,162,75,.35), inset 0 2px 10px rgba(255,220,160,.3), inset 0 -6px 16px rgba(0,0,0,.45); }
}
.seal-monogram {
  font-family: var(--serif-display);
  font-size: clamp(20px, 7vw, 32px);
  font-weight: 700;
  color: var(--gold-soft);
  text-shadow: 0 1px 0 rgba(0,0,0,.6), 0 0 18px rgba(229,200,120,.4);
  letter-spacing: .08em;
}
.seal-rim {
  position: absolute; inset: 7%;
  border-radius: 50%;
  border: 1.5px dashed rgba(229,200,120,.55);
  pointer-events: none;
}
#loader-status, #loader-tap {
  position: absolute; bottom: -64px; width: 100vw; text-align: center;
  font-family: var(--serif-display);
  font-size: 12px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold-soft);
}
#loader-tap { animation: fade-blink 1.8s ease-in-out infinite; }
#loader-retry {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 24px);
  z-index: 3;
  min-height: 44px;
  padding: 0 20px;
  transform: translateX(-50%);
  border: 1px solid rgba(229,200,120,.72);
  border-radius: 999px;
  color: var(--gold-soft);
  background: rgba(53,9,23,.82);
  font: 600 11px/1 var(--serif-display);
  letter-spacing: .18em;
  text-transform: uppercase;
  white-space: nowrap;
  touch-action: manipulation;
}
#loader-retry:active { background: rgba(109,26,51,.96); }
@keyframes fade-blink { 0%,100% { opacity: .55; } 50% { opacity: 1; } }

/* ═══════════════ PETALS ═══════════════ */
#petals {
  position: fixed; inset: 0; z-index: 60;
  pointer-events: none;
}

/* ═══════════════ HERO ═══════════════ */
#hero { position: relative; background: var(--ivory); }
.hero-sticky {
  position: sticky; top: 0;
  height: calc(var(--vh) * 100);
  overflow: hidden;
  contain: paint;
  isolation: isolate;
}
#scrub {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  background: var(--ivory);
}
/* A static wash of golden light keeps the scene luminous without repainting
   a full-screen blended layer throughout the scroll. */
.hero-sticky::after {
  content: "";
  position: absolute; inset: -30%;
  pointer-events: none;
  background: radial-gradient(ellipse 34% 26% at 50% 50%, rgba(255,232,170,.5), transparent 70%);
  mix-blend-mode: soft-light;
}
.vignette {
  position: absolute; inset: -2px; pointer-events: none;
  /* feathers the floating world into the page ivory — no hard frame edges */
  background:
    radial-gradient(ellipse 78% 54% at 50% 42%, transparent 56%, var(--ivory) 92%),
    linear-gradient(to bottom, var(--ivory) 0%, transparent 12%, transparent 80%, var(--ivory) 97%);
}

/* Editorial side notes occupy only genuinely empty wide-screen margins. */
.hero-side { display: none; }
@media (min-width: 1180px) and (min-aspect-ratio: 4 / 3) {
  .hero-side {
    --side-outer: clamp(48px, 8vw, 170px);
    --side-enter: -14px;
    position: absolute;
    top: 50%;
    z-index: 2;
    width: min(280px, calc(50vw - 36.5vh - var(--side-outer) - 28px));
    display: grid;
    justify-items: center;
    gap: 13px;
    color: var(--maroon);
    text-align: center;
    pointer-events: none;
    user-select: none;
    contain: layout paint;
    opacity: 0;
    transform: translate3d(var(--side-enter), -50%, 0);
    transition: opacity 1.15s ease .65s, transform 1.3s cubic-bezier(.2,.75,.25,1) .55s;
  }
  .hero-side-left { left: var(--side-outer); }
  .hero-side-right {
    --side-enter: 14px;
    right: var(--side-outer);
  }
  #hero.entered .hero-side {
    opacity: .92;
    transform: translate3d(0, -50%, 0);
  }
  .hero-side > * { position: relative; }
  .hero-side-dev {
    font-family: var(--serif-dev);
    font-size: 30px;
    font-weight: 600;
    color: var(--gold);
    text-shadow: 0 1px 0 rgba(255,255,255,.6);
  }
  .hero-side-role {
    font-family: var(--serif-display);
    font-size: 11px;
    letter-spacing: .44em;
    text-indent: .44em;
    text-transform: uppercase;
    color: rgba(109,26,51,.8);
  }
  .hero-side-rule {
    width: min(140px, 78%);
    height: 1px;
    margin: 3px 0;
    background: linear-gradient(90deg, transparent, rgba(201,162,75,.9), transparent);
  }
  .hero-side-rule::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 6px; height: 6px;
    border: 1px solid var(--gold);
    background: var(--ivory);
    transform: translate(-50%, -50%) rotate(45deg);
  }
  .hero-side em {
    font-family: var(--serif-body);
    font-style: italic;
    font-size: clamp(18px, 1.5vw, 23px);
    font-weight: 500;
    line-height: 1.3;
    color: rgba(58,34,48,.85);
  }
  .hero-side small {
    margin-top: 1px;
    font-family: var(--serif-display);
    font-size: 9.5px;
    letter-spacing: .32em;
    text-indent: .32em;
    text-transform: uppercase;
    color: rgba(109,26,51,.62);
  }
}

/* Crown — a quiet signature above the world */
#hero-crown {
  position: absolute;
  top: calc(env(safe-area-inset-top, 0px) + 18px);
  left: 0; right: 0;
  display: grid; justify-items: center; gap: 7px;
  pointer-events: none;
  z-index: 3;
}
.crown-mono {
  font-family: var(--serif-display);
  font-size: 13px; font-weight: 700;
  letter-spacing: .18em;
  color: var(--maroon);
  border: 1px solid rgba(201,162,75,.75);
  border-radius: 999px;
  padding: 7px 14px 6px;
  background: rgba(244,235,219,.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  box-shadow: 0 2px 14px rgba(74,15,34,.12);
}
.crown-rule {
  width: 46px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.crown-chapter {
  font-family: var(--serif-display);
  font-size: 10.5px;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--maroon);
  opacity: .85;
}

.beat {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: flex-end;
  text-align: center;
  padding: 0 16px calc(env(safe-area-inset-bottom, 0px) + 20px);
  opacity: 0;
  pointer-events: none;
  will-change: opacity, transform;
}
.beat > * { position: relative; }
.beat-static {
  opacity: 1;
  visibility: visible;
  transform: none;
  will-change: auto;
}

.hero-copy-glass {
  width: fit-content;
  max-width: min(92vw, 540px);
  min-width: min(90vw, 320px);
  margin-inline: auto;
  padding: 15px 22px 14px;
  overflow: hidden;
  border: 1px solid var(--glass-stroke);
  border-radius: 26px;
  background:
    linear-gradient(145deg, rgba(255,255,255,.78), rgba(255,244,215,.58) 54%, rgba(244,235,219,.72));
  box-shadow: var(--glass-shadow), 0 18px 44px rgba(46,8,22,.16);
  opacity: 0;
  transform: translate3d(0, 18px, 0) scale(.985);
  transition: opacity .75s ease .16s, transform .8s cubic-bezier(.2,.75,.25,1) .16s;
}
#hero.entered .hero-copy-glass {
  opacity: 1;
  transform: none;
}

/* A stacked board is taller, so its supporting lines tighten up. It does NOT
   get nudged or negatively margined any more: app.js reserves the board's
   measured height and the artwork is fitted above it. Do not re-add offsets. */
.hero-copy-glass--stacked { padding: 11px 18px 10px; }
.hero-copy-glass--stacked .eyebrow { margin: -2px 0 0; font-size: 11px; }
.hero-copy-glass--stacked .hero-vow {
  margin: 2px 0 6px;
  font-size: clamp(13px, 3.4vw, 16px);
  line-height: 1.3;
}
.hero-copy-glass--stacked .scroll-hint { margin-top: 2px; gap: 3px; font-size: 10px; }

/* --names-fs is written by nameBoard in app.js; the clamp is the pre-script
   fallback only. `nowrap` is required: it lets the fitter detect overflow
   through scrollWidth instead of silently wrapping. */
.names {
  font-family: var(--serif-display);
  font-weight: 700;
  font-size: var(--names-fs, clamp(29px, 8.4vw, 60px));
  line-height: 1.08;
  margin: 8px 0 5px;
  color: var(--maroon-deep);
  letter-spacing: -.02em;
  text-shadow: 0 1px 0 rgba(255,255,255,.72);
  max-width: 100%;
  white-space: nowrap;    /* required: the fitter detects overflow via scrollWidth */
  overflow: hidden;
  text-align: center;
}
/* Long names stack: groom on top, ♥ in the middle, bride below. */
.names--stacked {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  margin: 3px 0 2px;
}
/* The heart is the visual hinge of the stack — keep it clearly readable.
   Its share is accounted for by BOARD lines=2.9 in app.js; change both together. */
.names--stacked .amp {
  font-size: .72em;
  vertical-align: baseline;
  display: block;
  margin: 1px 0 2px;
  line-height: 1;
}
.names--stacked .name-word {
  display: block;
  line-height: 1.06;
  max-width: 100%;
}
.name-word { display: inline-block; white-space: nowrap; }
/* Cinematic letter-cascade entrance for the names */
.names .ltr {
  display: inline-block;
  opacity: 0;
  transform: translateY(26px) rotate(4deg);
  filter: blur(5px);
}
#hero.entered .names .ltr {
  animation: ltr-in .9s cubic-bezier(.2,.75,.25,1) forwards;
  animation-delay: calc(var(--li) * 65ms + .25s);
}
@keyframes ltr-in {
  to { opacity: 1; transform: none; filter: blur(0); }
}
.amp { font-size: .6em; vertical-align: .18em; color: var(--gold); }
.beat .eyebrow {
  color: var(--maroon);
  text-shadow: none;
}
.hero-vow {
  margin: 2px 0 13px;
  font-size: clamp(14px, 3.9vw, 19px);
  line-height: 1.4;
  letter-spacing: .03em;
  color: rgba(58,34,48,.86);
  text-shadow: none;
}

/* Dedicated countdown card */
#countdown-section {
  padding: clamp(52px, 8vw, 84px) 18px clamp(60px, 9vw, 96px);
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 0%, rgba(201,162,75,.20), transparent 54%),
    linear-gradient(180deg, #f4ebdb 0%, #f8f1e5 100%);
}
.countdown-card {
  position: relative;
  max-width: 700px;
  margin: 0 auto;
  padding: clamp(34px, 7vw, 54px) clamp(15px, 5vw, 48px) clamp(30px, 6vw, 46px);
  text-align: center;
  border: 1px solid rgba(201,162,75,.72);
  border-radius: 28px;
  background: var(--glass-fill);
  box-shadow: var(--glass-shadow);
  isolation: isolate;
}
.countdown-card::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid rgba(201,162,75,.28);
  border-radius: 21px;
  pointer-events: none;
}
.countdown-card::after {
  content: "✦";
  position: absolute;
  left: 50%; bottom: -11px;
  width: 22px; height: 22px;
  display: grid; place-items: center;
  transform: translateX(-50%) rotate(45deg);
  color: var(--gold);
  font-size: 10px;
  border: 1px solid rgba(201,162,75,.7);
  background: var(--ivory);
}
.countdown-sigil {
  display: block;
  margin: 0 auto 14px;
  font: 700 11px/1 var(--serif-display);
  letter-spacing: .28em;
  text-indent: .28em;
  color: var(--maroon);
}
#countdown-title {
  margin: 9px 0 7px;
  color: var(--maroon);
  font: 600 clamp(28px, 7vw, 44px)/1.15 var(--serif-display);
  letter-spacing: .02em;
}
.countdown-date,
.countdown-detail {
  color: rgba(58,34,48,.78);
  font-size: clamp(15px, 3.8vw, 19px);
  letter-spacing: .08em;
}
.countdown-detail {
  font-size: clamp(13px, 3.2vw, 16px);
  color: rgba(109,26,51,.72);
}
.countdown {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  max-width: 440px;
  margin: 25px auto 21px;
}
.cd-cell {
  min-width: 0;
  padding: 13px 4px 10px;
  border-radius: 14px;
  border: 1px solid rgba(201,162,75,.52);
  background: rgba(255,253,247,.78);
  box-shadow: 0 5px 18px rgba(74,15,34,.07);
  display: grid; justify-items: center; gap: 1px;
}
.cd-num {
  font-family: var(--serif-display);
  font-size: clamp(20px, 5.5vw, 29px); font-weight: 700;
  color: var(--maroon);
  font-variant-numeric: tabular-nums;
}
.cd-lbl {
  font-size: clamp(8px, 2.3vw, 10px); letter-spacing: .18em; text-transform: uppercase;
  color: rgba(58,34,48,.75);
}
.countdown-complete {
  grid-column: 1 / -1;
  color: var(--maroon);
  font-size: clamp(20px, 5vw, 28px);
}

.scroll-hint {
  margin-top: 4px;
  display: grid; justify-items: center; gap: 6px;
  font-family: var(--serif-display);
  font-size: 10.5px; letter-spacing: .13em; text-transform: none;
  color: var(--maroon);
  text-shadow: none;
}
.chev {
  width: 10px; height: 10px;
  border-right: 2px solid var(--gold);
  border-bottom: 2px solid var(--gold);
  transform: rotate(45deg);
  animation: chev-drop 1.6s ease-in-out infinite;
}
@keyframes chev-drop {
  0%,100% { transform: translateY(0) rotate(45deg); opacity: .5; }
  50%     { transform: translateY(7px) rotate(45deg); opacity: 1; }
}

/* ═══════════════ SHARED SECTION CHROME ═══════════════ */
section { position: relative; z-index: 5; }
#events, #blessings, #venue {
  padding: 72px 22px 64px;
  background:
    radial-gradient(140% 60% at 50% 0%, rgba(201,162,75,.10), transparent 55%),
    var(--ivory);
  overflow: hidden;                 /* decor bleeds are clipped, no sideways scroll */
}
#sanctum {
  background:
    radial-gradient(140% 60% at 50% 0%, rgba(201,162,75,.10), transparent 55%),
    var(--ivory);
  /* NO overflow:hidden here — it would break the sticky stage */
}

/* ═══════════════ DECOR CUTOUTS ═══════════════════════════ */
.decor {
  position: absolute;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.decor.shown { opacity: 1; }
.decor-toran {
  top: -6px; left: -4%;
  width: 108%;
  transform-origin: 50% 0;
  animation: toran-sway 7s ease-in-out infinite;
}
.decor-toran-2 { animation-delay: 3.5s; }
@keyframes toran-sway {
  0%, 100% { transform: rotate(.5deg); }
  50%      { transform: rotate(-.5deg); }
}
.decor-elephant {
  left: -34px; bottom: 30px;
  width: clamp(150px, 42vw, 280px);
}
.decor-umbrella {
  right: -26px; top: 90px;
  width: clamp(90px, 26vw, 170px);
  rotate: 9deg;
  opacity: 0;
}
.decor-umbrella.shown { opacity: .92; }
.decor-lotus {
  right: -30px; bottom: -24px;
  width: clamp(150px, 44vw, 280px);
}
#events .sec-head, #venue .sec-head { margin-top: 34px; }
#event-cards, .venue-card, #scratch-wrap, .rsvp-block, footer { position: relative; z-index: 2; }

/* ═══════════════ SANCTUM — the hidden moment ═════════════ */
#sanctum {
  height: calc(var(--vh) * 220);     /* stable runway; mobile browser chrome cannot move it */
  padding: 0 22px !important;
}
#sanctum-stage {
  position: sticky; top: 0;
  min-height: calc(var(--vh) * 100);
  display: flex; flex-direction: column;
  justify-content: center;
  padding: 20px 0;
}
#sanctum-stage .sec-head { margin-bottom: 18px; }
#sanctum-portal {
  position: relative;
  width: min(88vw, calc(var(--vh) * 50), 440px);   /* stable while mobile browser chrome moves */
  margin: 0 auto;
  aspect-ratio: 1025 / 1126;        /* arch cutout ratio */
}
#sanctum-portal::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  background: url("assets/decor/arch.webp") center / 100% 100% no-repeat;
  filter: drop-shadow(0 0 42px rgba(229,200,120,.85));
}
#sanctum-filmbar {
  width: min(60vw, 240px);
  margin: 18px auto 0;
  display: grid; gap: 7px; justify-items: center;
}
#sanctum-filmbar .bar {
  width: 100%; height: 2px;
  background: rgba(201,162,75,.25);
  border-radius: 2px;
  overflow: hidden;
}
#sanctum-filmbar .fill {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft));
  transform-origin: left;
  transform: scaleX(0);
}
#sanctum-filmbar .cap {
  font-family: var(--serif-display);
  font-size: 10px; letter-spacing: .26em; text-transform: uppercase;
  color: var(--maroon); opacity: .65;
}
.sanctum-arch {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 16px 34px rgba(74,15,34,.28));
}
#sanctum.unlocked #sanctum-portal::after { animation: arch-bless 2.2s ease; }
@keyframes arch-bless {
  0%, 100% { opacity: 0; transform: scale(1); }
  40% { opacity: 1; transform: scale(1.008); }
}
#sanctum-view {
  position: absolute;
  /* measured from the arch cutout's pixels: opening apex 40.7%, pillars 29%/72% —
     slightly overfilled; the arch artwork above masks the excess */
  left: 27.5%; right: 26.5%; top: 36%; bottom: 0.5%;
  overflow: hidden;
  z-index: 1;
  background: var(--maroon-deep);
  contain: paint;
  isolation: isolate;
}
#sanctum-view canvas, #sanctum-view img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
#sanctum-canvas { opacity: 0; transition: opacity .9s ease; }
#sanctum-poster {
  filter: sepia(.35) brightness(.72) blur(1px);
  transform-origin: 50% 40%;
  animation: kenburns 16s ease-in-out infinite alternate;
  transition: opacity .9s ease;
}
#sanctum.loading #sanctum-poster { animation-play-state: paused; }
@keyframes kenburns {
  from { transform: scale(1.04) translateY(0); }
  to   { transform: scale(1.16) translateY(-3%); }
}
#sanctum.unlocked #sanctum-canvas { opacity: 1; }
#sanctum.unlocked #sanctum-poster { opacity: 0; animation-play-state: paused; }
#sanctum-veil {
  position: absolute; inset: 0;
  z-index: 2;
  display: grid; place-content: center; gap: 8px;
  text-align: center;
  background:
    radial-gradient(80% 60% at 50% 45%, rgba(46,8,22,.28), rgba(46,8,22,.66));
  transition: opacity 1s ease;
}
#sanctum.unlocked #sanctum-veil { opacity: 0; pointer-events: none; }
.veil-lotus {
  font-size: 40px;
  animation: veil-breathe 3.4s ease-in-out infinite;
  filter: drop-shadow(0 0 14px rgba(229,200,120,.6));
}
@keyframes veil-breathe {
  0%, 100% { transform: scale(1); opacity: .85; }
  50%      { transform: scale(1.12); opacity: 1; }
}
.veil-text, .veil-progress {
  font-family: var(--serif-display);
  font-size: 11.5px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--gold-soft);
  text-shadow: 0 1px 8px rgba(46,8,22,.9);
  padding: 0 18px;
}

/* ═══════════════ FOOTER DIYAS ════════════════════════════ */
.foot-diyas {
  display: flex; align-items: center; justify-content: center;
  gap: 22px;
}
.foot-diya {
  width: 58px;
  animation: diya-flicker 2.8s ease-in-out infinite;
}
.foot-diya + .foot-monogram + .foot-diya { animation-delay: 1.3s; }
@keyframes diya-flicker {
  0%, 100% { filter: brightness(1) drop-shadow(0 0 6px rgba(229,200,120,.45)); }
  42% { filter: brightness(1.12) drop-shadow(0 0 14px rgba(229,200,120,.75)); }
  58% { filter: brightness(.96) drop-shadow(0 0 8px rgba(229,200,120,.5)); }
}
.sec-head { text-align: center; margin-bottom: 40px; }
.sec-head .eyebrow {
  letter-spacing: .1em; opacity: 0;
  transition: letter-spacing 1.4s cubic-bezier(.2,.7,.3,1), opacity 1.2s ease;
}
.sec-head.shown .eyebrow { letter-spacing: .34em; opacity: .95; }
.sec-title {
  font-family: var(--serif-display);
  font-weight: 700;
  font-size: clamp(30px, 8.4vw, 46px);
  margin-top: 8px;
}
.sec-sub { margin-top: 8px; font-size: 17px; font-style: italic; opacity: .8; }
/* Self-drawing gold flourish under section titles */
.flourish { width: 150px; height: 26px; margin: 12px auto 0; display: block; overflow: visible; }
.flourish path, .flourish circle {
  fill: none;
  stroke: var(--gold);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 220;
  stroke-dashoffset: 220;
}
.sec-head.shown .flourish path, .sec-head.shown .flourish circle {
  transition: stroke-dashoffset 1.8s ease .3s;
  stroke-dashoffset: 0;
}
.flourish .gem {
  fill: var(--gold);
  stroke: none;
  opacity: 0;
  transform-origin: center;
  transform: scale(0) rotate(45deg);
  transform-box: fill-box;
}
.sec-head.shown .flourish .gem {
  transition: opacity .5s ease 1.4s, transform .7s cubic-bezier(.2,.9,.3,1.4) 1.4s;
  opacity: 1;
  transform: scale(1) rotate(45deg);
}

/* ═══════════════ EVENT CARDS ═══════════════ */
#event-cards {
  display: grid; gap: 20px;
  max-width: 480px; margin: 0 auto;
}
.event-card {
  --accent: var(--maroon);
  position: relative;
  border-radius: 18px;
  padding: 24px 22px 22px 88px;
  background: var(--glass-fill);
  border: 1px solid var(--glass-stroke);
  box-shadow: var(--glass-shadow);
  opacity: 0; transform: translateY(46px) scale(.96);
  transition: opacity .8s cubic-bezier(.2,.7,.3,1), transform .8s cubic-bezier(.2,.7,.3,1);
  overflow: hidden;
}
/* A fixed gold sheen keeps the cards luminous without pointer-driven repaints. */
.event-card::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg,
    transparent 26%,
    rgba(246,231,182,.28) 50%,
    transparent 74%);
}
.event-card::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 6px;
  background: linear-gradient(var(--accent), color-mix(in srgb, var(--accent) 55%, #000));
}
.event-card.shown {
  opacity: 1; transform: none;
}
.event-ico {
  position: absolute; left: 20px; top: 50%;
  transform: translateY(-50%);
  width: 50px; height: 50px;
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, #fff);
  border: 1.5px solid color-mix(in srgb, var(--accent) 45%, transparent);
}
.event-ico svg { width: 26px; height: 26px; }
.event-card.shown .event-ico { animation: ico-glow .72s cubic-bezier(.2,.85,.25,1) .18s both; }
@keyframes ico-glow {
  0% { transform: translateY(-50%) scale(.82); box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
  58% { transform: translateY(-50%) scale(1.08); box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 14%, transparent); }
  100% { transform: translateY(-50%) scale(1); box-shadow: 0 0 18px color-mix(in srgb, var(--accent) 12%, transparent); }
}
.event-name {
  font-family: var(--serif-display);
  font-size: 21px; font-weight: 700;
  color: var(--accent);
  letter-spacing: .04em;
}
.event-line { font-style: italic; font-size: 15.5px; opacity: .85; margin: 3px 0 8px; }
.event-meta { font-size: 15px; line-height: 1.5; }
.event-meta b { font-weight: 600; }

/* ═══════════════ SCRATCH CARD ═══════════════ */
#scratch-wrap {
  position: relative;
  max-width: 420px;
  margin: 0 auto;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 14px 44px rgba(74,15,34,.22);
  aspect-ratio: 3 / 4;
  border: 1px solid rgba(201,162,75,.5);
  touch-action: none;
  overscroll-behavior: contain;
}
#scratch-wrap::before {
  content: "";
  position: absolute;
  inset: 7px;
  z-index: 5;
  pointer-events: none;
  border: 1.5px solid rgba(255,239,184,.82);
  border-radius: 15px;
  box-shadow:
    inset 0 0 0 1px rgba(112,65,11,.24),
    0 0 16px rgba(229,200,120,.38);
  opacity: 0;
  transform: translateZ(0) scale(.985);
}
#scratch-wrap.scratch-border-active::before {
  will-change: transform, opacity;
  animation: scratch-border-breathe 2.7s ease-in-out infinite;
}
@keyframes scratch-border-breathe {
  0%, 100% { opacity: .56; transform: translateZ(0) scale(.985); }
  50% { opacity: 1; transform: translateZ(0) scale(1); }
}
#scratch-under { position: absolute; inset: 0; }
#scratch-under img { width: 100%; height: 100%; object-fit: cover; }
.scratch-msg {
  position: absolute; inset: auto 0 0 0;
  padding: 84px 22px 24px;
  text-align: center;
  color: var(--ivory);
  background: linear-gradient(to top, rgba(46,8,22,.92) 30%, transparent);
}
.scratch-msg h3 {
  font-family: var(--serif-display);
  font-size: 19px; color: var(--gold-soft);
  margin-bottom: 8px;
}
.scratch-msg p { font-size: 16.5px; line-height: 1.5; }
#scratch-foil {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  transition: opacity .9s ease;
}
#scratch-foil.cleared { opacity: 0; pointer-events: none; }
/* Celebration when the secret is revealed */
#scratch-wrap.celebrate {
  touch-action: pan-y;
  animation: scratch-drama 1.8s cubic-bezier(.2,.8,.3,1);
}
@keyframes scratch-drama {
  0%   { transform: scale(1); box-shadow: 0 14px 44px rgba(74,15,34,.22); }
  18%  { transform: scale(1.045) rotate(.6deg); box-shadow: 0 0 60px rgba(229,200,120,.95), 0 14px 44px rgba(74,15,34,.3); }
  38%  { transform: scale(.995) rotate(-.4deg); }
  60%  { transform: scale(1.02); box-shadow: 0 0 34px rgba(229,200,120,.55); }
  100% { transform: scale(1); box-shadow: 0 14px 44px rgba(74,15,34,.22); }
}
#scratch-wrap.celebrate::after {
  content: "";
  position: absolute; inset: 0;
  z-index: 6;
  background: linear-gradient(115deg, transparent 30%, rgba(255,244,208,.9) 50%, transparent 70%);
  background-size: 260% 100%;
  animation: foil-flash 1.2s ease .15s both;
  pointer-events: none;
}
@keyframes foil-flash {
  from { background-position: 120% 0; opacity: 1; }
  to   { background-position: -60% 0; opacity: 0; }
}

/* ═══════════════ VENUE ═══════════════ */
.venue-card {
  max-width: 480px; margin: 0 auto;
  border-radius: 20px; overflow: hidden;
  background: var(--glass-fill);
  border: 1px solid var(--glass-stroke);
  box-shadow: var(--glass-shadow);
}
.venue-art {
  height: 190px;
  background-size: cover;
  background-position: center 28%;
}
.venue-info { padding: 22px; text-align: center; }
.venue-info h3 {
  font-family: var(--serif-display);
  font-size: 21px; color: var(--maroon);
}
.venue-info p { margin: 6px 0 16px; font-size: 15.5px; opacity: .85; }

.btn-gold, .btn-maroon {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 26px;
  border-radius: 999px;
  font-family: var(--serif-display);
  font-size: 14px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  text-decoration: none;
  border: none;
  transition: transform .22s ease, box-shadow .22s ease;
}
.btn-gold {
  color: var(--maroon-deep);
  background: linear-gradient(120deg, var(--gold) 0%, #f0dfa6 50%, var(--gold) 100%);
  box-shadow: 0 6px 20px rgba(201,162,75,.45);
}
.btn-maroon {
  color: var(--gold-soft);
  background: linear-gradient(160deg, #5a1429, var(--maroon-deep));
  box-shadow: 0 8px 26px rgba(74,15,34,.4);
}
.btn-gold:active, .btn-maroon:active { transform: scale(.97); }

.rsvp-block {
  width: min(100%, 480px);
  margin: 44px auto 0;
  padding: 22px 18px;
  text-align: center;
  border: 1px solid var(--glass-stroke);
  border-radius: 20px;
  background: var(--glass-fill);
  box-shadow: var(--glass-shadow);
}
.rsvp-deadline { font-style: italic; margin-bottom: 12px; opacity: .8; }

footer { text-align: center; margin-top: 64px; }
.foot-monogram { font-family: var(--serif-display); font-size: 30px; font-weight: 700; }
.foot-line { margin-top: 6px; font-size: 16px; font-style: italic; }
.foot-credit { margin-top: 18px; font-size: 12px; letter-spacing: .2em; text-transform: uppercase; opacity: .5; }

/* ═══════════════ RSVP MODAL ═══════════════ */
#rsvp-modal {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(46,8,22,.65);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  display: grid; align-items: end;
}
.modal-sheet {
  position: relative;
  background: var(--glass-fill), var(--ivory);
  border: 1px solid var(--glass-stroke);
  box-shadow: var(--glass-shadow);
  border-radius: 22px 22px 0 0;
  padding: 26px 18px calc(env(safe-area-inset-bottom, 0px) + 18px);
  max-height: 88vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  display: grid; gap: 14px;
  animation: sheet-up .45s cubic-bezier(.2,.8,.3,1);
}
@keyframes sheet-up { from { transform: translateY(100%); } }
.modal-sheet h3 {
  font-family: var(--serif-display);
  text-align: center; font-size: 20px;
}
#rsvp-close {
  position: absolute; top: 12px; right: 14px;
  width: 44px; height: 44px;
  border-radius: 50%; border: 1px solid rgba(109,26,51,.3);
  background: transparent; color: var(--maroon);
  font-size: 15px;
}
#rsvp-frame-slot iframe {
  width: 100%; height: min(62vh, 560px);
  border: none; border-radius: 14px;
  background: #fff;
}
/* Shown instead of the frame when the couple's form refuses to be embedded
   (forms.gle short links, /edit addresses, any host sending X-Frame-Options). */
.rsvp-external {
  display: grid; gap: 16px; justify-items: center;
  padding: 10px 4px 4px; text-align: center;
}
.rsvp-external .rf-submit {
  width: 100%; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center;
}

/* Native royal RSVP form (used until a real Google Form URL is configured) */
#rsvp-form { display: grid; gap: 16px; padding: 4px 4px 2px; }
.rf-label {
  display: grid; gap: 7px;
  font-family: var(--serif-display);
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--maroon);
}
.rf-opt { text-transform: none; letter-spacing: 0; opacity: .6; font-family: var(--serif-body); }
.rf-input {
  font-family: var(--serif-body);
  font-size: 17px;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid rgba(109,26,51,.28);
  background: #fffdf7;
  color: var(--ink);
  outline: none;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.rf-input:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(201,162,75,.22);
}
textarea.rf-input { resize: none; }
.rf-choices { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.rf-chip { position: relative; }
.rf-chip input { position: absolute; opacity: 0; }
.rf-chip span {
  display: block;
  text-align: center;
  padding: 12px 8px;
  border-radius: 12px;
  border: 1px solid rgba(109,26,51,.28);
  font-family: var(--serif-body);
  font-size: 15.5px;
  text-transform: none; letter-spacing: 0;
  color: var(--ink);
  background: #fffdf7;
  transition: all .25s ease;
}
.rf-chip input:checked + span {
  background: linear-gradient(160deg, #5a1429, var(--maroon-deep));
  color: var(--gold-soft);
  border-color: var(--gold);
  box-shadow: 0 6px 18px rgba(74,15,34,.3);
}
.rf-chip input:focus-visible + span {
  outline: 3px solid var(--gold-soft);
  outline-offset: 2px;
}
.rf-submit { justify-self: center; margin-top: 2px; }
#rsvp-done { text-align: center; padding: 26px 10px 18px; display: grid; gap: 10px; }
#rsvp-done.hidden { display: none; }
.rf-done-mark { font-size: 44px; animation: veil-breathe 2.8s ease-in-out infinite; }
#rsvp-done h4 { font-family: var(--serif-display); font-size: 22px; }
.rf-done-text { font-size: 16.5px; line-height: 1.5; opacity: .85; }

/* ═══════════════ GOLDEN SCROLL THREAD ════════════════════ */
#thread {
  position: fixed;
  top: 0; right: calc(env(safe-area-inset-right, 0px) + 5px);
  width: 2px; height: calc(var(--vh) * 100);
  z-index: 75;
  pointer-events: none;
  background: linear-gradient(rgba(201,162,75,.16), rgba(201,162,75,.16));
  opacity: 0;
  transition: opacity .8s ease;
}
#thread.on { opacity: 1; }
#thread::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(var(--gold-soft), var(--gold));
  transform-origin: top;
  transform: scaleY(var(--sp, 0));
}
#thread-lotus {
  position: absolute;
  right: -7px;
  top: calc(var(--sp, 0) * 100% - 8px);
  font-size: 15px;
  font-style: normal;
  filter: drop-shadow(0 0 5px rgba(229,200,120,.8));
}

/* ═══════════════ SOUND TOGGLE ═══════════════ */
#sound-toggle {
  position: fixed; top: calc(env(safe-area-inset-top, 0px) + 12px); right: 12px; z-index: 80;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(229,200,120,.6);
  background: rgba(46,8,22,.55);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  font-size: 17px;
  display: grid; place-items: center;
  transition: opacity .3s ease;
}
#sound-toggle.muted { opacity: .55; filter: grayscale(1); }

/* ═══════════════ DESKTOP POLISH ═══════════════ */
@media (min-width: 760px) {
  .beat { padding-bottom: 11vh; }
  #event-cards { max-width: 560px; }
}

/* One-shot, compositor-only entrances keep the page lively without tying
   animation work to scroll position. */
.soft-reveal {
  opacity: 0;
  transform: translate3d(0, 16px, 0) scale(.985);
  transition: opacity .72s ease, transform .82s cubic-bezier(.2,.75,.25,1);
}
.soft-reveal.revealed {
  opacity: 1;
  transform: none;
}

/* True refraction is reserved for fine-pointer hardware. On phones the same
   glass hierarchy is painted as gradients, so the scrolling canvases stay fast. */
@media (pointer: fine) {
  .hero-copy-glass,
  .countdown-card,
  .event-card,
  .venue-card,
  .rsvp-block,
  .modal-sheet,
  .film-caption,
  .world-portal-action {
    -webkit-backdrop-filter: blur(12px) saturate(1.12);
    backdrop-filter: blur(12px) saturate(1.12);
  }
}

/* Coarse-pointer devices get the same visual hierarchy with fewer blended,
   repainted layers competing with scrolling. */
@media (pointer: coarse) {
  body::after { display: none; }
  .hero-sticky::after {
    animation: none;
    mix-blend-mode: normal;
    opacity: .28;
    transform: none;
  }
  .crown-mono,
  .cd-cell,
  #rsvp-modal,
  #sound-toggle {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .event-card::after { display: none; }
  #finale::before { animation: none; }
  .gold-foil { animation: none; background-position: 50% 0; }
  .names { filter: none; }
  #hero.entered .names .ltr {
    animation: none;
    opacity: 1;
    transform: none;
    filter: none;
  }
  .chev,
  .decor-toran { animation: none; }
  .beat,
  .decor { will-change: auto; }
  .hero-copy-glass { box-shadow: 0 10px 28px rgba(74,15,34,.13), inset 0 1px 0 rgba(255,255,255,.86); }
}

/* ═══════════════ REDUCED MOTION ═══════════════ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01s !important; }
  /* The name board is sized dynamically through a CSS variable update.
     Transition-based font-size interpolation freezes the inherited value
     at the pre-update fallback, breaking the fitter. */
  .names, .names * { transition-property: none !important; }
  #hero .hero-side { opacity: .82; transform: translate3d(0, -50%, 0); }
  #sanctum { height: auto; }
  #sanctum-stage { position: relative; min-height: auto; padding: 80px 0; }
  .event-card { opacity: 1; transform: none; }
  .soft-reveal { opacity: 1; transform: none; }
  .names .ltr { opacity: 1 !important; transform: none !important; filter: none !important; }
  .sec-head .eyebrow { opacity: .95; letter-spacing: .34em; }
  .flourish path, .flourish circle { stroke-dashoffset: 0 !important; }
  .flourish .gem { opacity: 1 !important; transform: scale(1) rotate(45deg) !important; }
  #finale > * { opacity: 1; transform: none; }
  #portal-transition,
  body.portal-opening #portal-transition { clip-path: none; }
}

/* ═══════════════ FILM BANDS — cinematic loops ════════════ */
.film-band {
  position: relative;
  width: min(calc(100% - 40px), 640px);
  margin: 34px auto;
  border-radius: 18px;
  padding: 2px;                              /* the animated border thickness */
  background: linear-gradient(110deg,
    #8a6a25, var(--gold) 20%, #f6e7b6 38%, var(--gold-soft) 50%,
    #f9efc9 62%, var(--gold) 80%, #8a6a25);
  background-size: 100% 100%;
  box-shadow: 0 12px 36px rgba(74,15,34,.22);
}
.film-inner {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  aspect-ratio: 2162 / 1080;                 /* the film's native widescreen ratio */
  background: var(--maroon-deep);
}
.film-inner video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.film-inner::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(to top, rgba(46,8,22,.58), transparent 48%);
}
.film-caption {
  position: absolute; left: 18px; bottom: 13px; z-index: 2;
  display: grid; gap: 3px;
  max-width: calc(100% - 36px);
  padding: 9px 13px 8px;
  border: 1px solid rgba(255,255,255,.28);
  border-radius: 15px;
  background: linear-gradient(145deg, rgba(74,15,34,.64), rgba(24,5,13,.42));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 8px 20px rgba(12,2,7,.18);
}
.film-eyebrow {
  font-family: var(--serif-display);
  font-size: 11px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--gold-soft);
}
.film-line {
  font-family: var(--serif-body);
  font-style: italic;
  font-size: 14.5px;
  color: var(--ivory);
  text-shadow: 0 1px 8px rgba(46,8,22,.8);
}

/* Static venue map — tappable, zero third-party weight */
#map-link {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  margin-bottom: 16px;
  overflow: hidden;
  border: 1px solid rgba(201,162,75,.5);
  border-radius: 14px;
  background: #eadfc9;
}
#map-link img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 54%;
  filter: sepia(.12) saturate(.92);
  transition: transform .25s ease, box-shadow .25s ease;
}
#map-link:active img { transform: scale(.985); }

/* Portrait finale film */
.film-band.portrait { width: min(66vw, 320px); }
.film-band.portrait .film-inner { aspect-ratio: 1080 / 1930; }
.rsvp-block { margin-bottom: 10px; }
.film-band.portrait { margin-top: 46px; }

/* ═══════════════ FINALE FOOTER — the last impression ═════ */
#finale {
  position: relative;
  margin: 96px -22px -64px;
  padding: 15vh clamp(20px, 6vw, 32px) calc(env(safe-area-inset-bottom, 0px) + 14vh);
  min-height: calc(var(--vh) * 94);
  display: flex; flex-direction: column;
  justify-content: center; align-items: center;
  text-align: center;
  overflow: hidden;
  /* the page sinks into night under a soft golden dome */
  border-radius: 100% 100% 0 0 / 64px 64px 0 0;
  border-top: 1px solid rgba(229,200,120,.7);
  background:
    radial-gradient(150% 110% at 50% 10%, #7A1F3D 0%, var(--maroon-deep) 50%, #22050F 100%);
}
#finale::before {
  content: "";
  position: absolute; inset: -20%;
  pointer-events: none;
  background:
    radial-gradient(38% 30% at 30% 35%, rgba(229,200,120,.16), transparent 70%),
    radial-gradient(30% 26% at 72% 60%, rgba(201,162,75,.13), transparent 70%),
    radial-gradient(26% 22% at 50% 85%, rgba(140,43,71,.35), transparent 70%);
  animation: finale-aurora 13s ease-in-out infinite alternate;
}
@keyframes finale-aurora {
  from { transform: translate(-3%, -2%) scale(1); }
  to   { transform: translate(3%, 3%) scale(1.12); }
}
#finale::after {
  content: "";
  position: absolute; left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
#finale > * { position: relative; }
#finale > * {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 1.1s ease, transform 1.1s cubic-bezier(.2,.7,.3,1);
}
#finale.shown > * { opacity: 1; transform: none; }
#finale.shown > :nth-child(1) { transition-delay: .1s; }
#finale.shown > :nth-child(2) { transition-delay: .35s; }
#finale.shown > :nth-child(3) { transition-delay: .75s; }
#finale.shown > :nth-child(4) { transition-delay: .95s; }
#finale.shown > :nth-child(5) { transition-delay: 1.15s; }
#finale.shown > :nth-child(6) { transition-delay: 1.35s; }
.finale-eyebrow {
  display: flex; align-items: center; gap: 14px;
  font-family: var(--serif-display);
  font-size: 12.5px;
  letter-spacing: .46em;
  text-indent: .46em;
  text-transform: uppercase;
  color: rgba(244,235,219,.9);
}
.fe-rule {
  width: 34px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(229,200,120,.8));
}
.fe-rule:last-child { transform: scaleX(-1); }
.finale-script {
  font-family: "Great Vibes", cursive;
  font-weight: 400;
  font-size: clamp(52px, 15vw, 96px);
  line-height: 1.25;
  padding: 0 10px 12px;
  margin: 10px 0 0;
  background: linear-gradient(175deg, #F6E7B6 8%, var(--gold-soft) 38%, var(--gold) 72%, #9a7a2e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 3px 22px rgba(229,200,120,.28));
}
.finale-heart {
  font-size: 26px;
  color: #E0454F;
  margin: 2px 0 18px;
  animation: heart-beat 1.9s ease-in-out infinite;
  filter: drop-shadow(0 0 14px rgba(224,69,79,.55));
}
@keyframes heart-beat {
  0%, 100% { transform: scale(1); }
  12% { transform: scale(1.22); }
  24% { transform: scale(1); }
  36% { transform: scale(1.14); }
  48% { transform: scale(1); }
}
.finale-date {
  font-family: var(--serif-body);
  font-style: italic;
  font-size: clamp(19px, 5.4vw, 25px);
  color: rgba(244,235,219,.95);
  margin-bottom: 16px;
}
.finale-tag {
  font-family: var(--serif-display);
  font-size: 12.5px;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  color: var(--gold-soft);
  opacity: .92;
}

/* ═══════════════ WORLD GATEWAY — invitation → 3D celebration ═══════════════ */
/* The gateway used to be `width: min(100%, 420px)` with `overflow: hidden`,
   which is what sliced the portal's rounded border on a phone: the button
   inside asked for 88vw, the glow ring pulses out to scale(1.012), and both
   were cut flat against this box's left and right edges. It is narrower now
   and no longer clips — the ring is allowed to breathe past the button. */
.world-gateway {
  width: min(100%, 356px);
  margin: clamp(36px, 7vh, 64px) auto 0;
  display: grid;
  justify-content: center;
  justify-items: center;
  overflow: visible;
  gap: 9px;
}
.world-gateway-kicker {
  font-family: var(--serif-dev);
  font-size: 15px;
  letter-spacing: .12em;
  text-indent: .12em;
  color: rgba(246,231,182,.88);
}
.world-portal-link {
  position: relative;
  isolation: isolate;
  display: grid;
  justify-items: center;
  gap: 0;
  /* constrain to the gateway width and split the clearance evenly on both
     sides so the whole portal stays centered instead of drifting right */
  width: 100%;
  max-width: 100%;
  padding: 10px 8px;
  color: inherit;
  text-decoration: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.world-portal-link::before {
  content: "";
  position: absolute;
  inset: 2px;
  z-index: 0;
  pointer-events: none;
  border: 1.5px solid rgba(255,226,135,.82);
  border-radius: 44% 44% 24px 24px / 28% 28% 24px 24px;
  box-shadow: 0 0 18px rgba(255,206,79,.44), inset 0 0 16px rgba(255,235,161,.16);
  opacity: .68;
  transform: translateZ(0) scale(.985);
}
.world-portal-link > * { position: relative; z-index: 1; }
#finale.shown .world-portal-link::before {
  animation: portal-ring 2.55s ease-in-out 2.25s infinite;
}
@keyframes portal-ring {
  0%, 100% { opacity: .62; transform: translateZ(0) scale(.985); }
  50% { opacity: 1; transform: translateZ(0) scale(1.012); }
}
.world-portal-visual {
  position: relative;
  width: clamp(146px, 43vw, 196px);
  aspect-ratio: 4 / 5;
  isolation: isolate;
  transform: translateZ(0);
  transition: transform .45s cubic-bezier(.2,.75,.25,1);
  background: radial-gradient(ellipse at 50% 55%, rgba(255,233,142,.24) 0 13%, rgba(255,192,41,.12) 37%, transparent 70%);
}

/* A CSS-only Rajputana torana: carved pillars, royal doors and warm light. */
.world-portal-visual::before,
.world-portal-visual::after {
  content: "";
  position: absolute;
  z-index: 3;
  bottom: 14%;
  width: 19%;
  height: 64%;
  border: 1px solid rgba(229,200,120,.72);
  border-radius: 6px 6px 2px 2px;
  background:
    linear-gradient(180deg, #f6e4aa, #b7832b) top / 100% 12% no-repeat,
    linear-gradient(180deg, #b7832b, #efd28b) bottom / 100% 13% no-repeat,
    repeating-linear-gradient(0deg, transparent 0 17%, rgba(229,200,120,.23) 17% 19%, transparent 19% 34%),
    linear-gradient(90deg, #3b0718, #882746 46%, #4a0f22);
  box-shadow: inset 0 0 0 2px rgba(255,232,164,.08), 0 12px 22px rgba(12,2,7,.25);
}
.world-portal-visual::before { left: 4%; }
.world-portal-visual::after { right: 4%; }

.world-gate-crown {
  content: "";
  position: absolute;
  z-index: 4;
  top: 5%;
  left: 1%;
  width: 98%;
  height: 29%;
  clip-path: polygon(0 43%, 10% 43%, 15% 24%, 21% 43%, 35% 43%, 50% 0, 65% 43%, 79% 43%, 85% 24%, 90% 43%, 100% 43%, 100% 100%, 0 100%);
  background: linear-gradient(180deg, #f7e6ad 0 13%, #bd8a31 14% 22%, #7a1f3d 23% 72%, #430a1d 73% 100%);
  box-shadow: inset 0 -4px 0 rgba(229,200,120,.55), inset 0 2px 0 rgba(255,244,204,.42);
}
.world-gate-crown::before {
  content: "";
  position: absolute;
  top: 16%;
  left: 50%;
  width: 11%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%) rotate(45deg);
  background: linear-gradient(135deg, #fff0b6, #c28a29);
  box-shadow: 0 0 12px rgba(255,221,118,.38);
}
.world-gate-crown::after {
  content: "";
  position: absolute;
  left: 10%;
  right: 10%;
  bottom: 9%;
  height: 9px;
  border-top: 1px solid rgba(246,226,166,.68);
  background: radial-gradient(circle, #f8e7b2 0 2px, transparent 2.6px) center 2px / 17px 7px repeat-x;
}

.world-gate-opening {
  position: absolute;
  z-index: 1;
  left: 20%;
  right: 20%;
  top: 26%;
  bottom: 18%;
  overflow: hidden;
  perspective: 280px;
  border: 2px solid #d7b258;
  border-radius: 50% 50% 7px 7px / 34% 34% 7px 7px;
  background: radial-gradient(ellipse at 50% 72%, #fff9dc 0, #ffdd70 25%, #c77c25 57%, #35101e 100%);
  box-shadow: 0 0 0 4px #500e27, 0 0 0 5px rgba(229,200,120,.7), inset 0 0 32px rgba(255,241,180,.38);
}
.world-gate-opening::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 7% 19% 0;
  opacity: .76;
  transform: scaleX(1);
  background: linear-gradient(90deg, transparent, rgba(255,253,226,.94), transparent);
}

.world-gate-door {
  position: absolute;
  z-index: 2;
  top: 0;
  bottom: 0;
  width: 50.5%;
  border: 1px solid rgba(229,200,120,.68);
  backface-visibility: hidden;
  background:
    linear-gradient(135deg, transparent 46%, rgba(229,200,120,.22) 47% 50%, transparent 51%) 0 0 / 24px 24px,
    linear-gradient(45deg, transparent 46%, rgba(229,200,120,.17) 47% 50%, transparent 51%) 0 0 / 24px 24px,
    linear-gradient(90deg, #3b0718, #812541);
  box-shadow: inset 0 0 18px rgba(12,2,7,.3);
  transition: transform .4s cubic-bezier(.2,.75,.25,1);
}
.world-gate-door-left {
  left: 0;
  transform-origin: left center;
  transform: perspective(280px) rotateY(-28deg);
}
.world-gate-door-right {
  right: 0;
  transform-origin: right center;
  transform: perspective(280px) rotateY(28deg);
}
.world-gate-door::after {
  content: "";
  position: absolute;
  top: 54%;
  width: 7px;
  aspect-ratio: 1;
  border: 1px solid #f0d58d;
  border-radius: 50%;
  background: #c8983d;
  box-shadow: 0 0 7px rgba(255,224,126,.42);
}
.world-gate-door-left::after { right: 10%; }
.world-gate-door-right::after { left: 10%; }

.world-gate-threshold {
  position: absolute;
  z-index: 1;
  left: 2%;
  right: 2%;
  bottom: 5%;
  height: 14%;
  clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
  background: linear-gradient(180deg, #efd894 0 18%, #64142f 19% 51%, #c99d45 52% 66%, #350816 67% 100%);
  box-shadow: 0 10px 18px rgba(10,2,6,.24);
}
.world-gate-path {
  position: absolute;
  z-index: 2;
  left: 27%;
  right: 27%;
  top: 65%;
  bottom: 2%;
  opacity: .72;
  transform: scaleY(1);
  transform-origin: 50% 0;
  clip-path: polygon(43% 0, 57% 0, 100% 100%, 0 100%);
  background: linear-gradient(180deg, rgba(255,248,202,.92), rgba(255,207,70,.57) 42%, rgba(255,174,21,.08));
}

#finale.shown .world-gate-door-left {
  animation: world-gate-open-left .95s cubic-bezier(.18,.72,.24,1) 1.45s both;
}
#finale.shown .world-gate-door-right {
  animation: world-gate-open-right .95s cubic-bezier(.18,.72,.24,1) 1.45s both;
}
#finale.shown .world-gate-opening::before {
  animation:
    world-gate-light 1.05s ease-out 1.5s both,
    world-gate-breathe 3.6s ease-in-out 2.65s infinite;
}
#finale.shown .world-gate-path {
  animation: world-gate-path 1.05s cubic-bezier(.18,.72,.24,1) 1.6s both;
}
@keyframes world-gate-open-left {
  from { transform: perspective(280px) rotateY(0); }
  to { transform: perspective(280px) rotateY(-28deg); }
}
@keyframes world-gate-open-right {
  from { transform: perspective(280px) rotateY(0); }
  to { transform: perspective(280px) rotateY(28deg); }
}
@keyframes world-gate-light {
  from { opacity: .12; transform: scaleX(.15); }
  70% { opacity: .94; transform: scaleX(1.13); }
  to { opacity: .76; transform: scaleX(1); }
}
@keyframes world-gate-breathe {
  0%, 100% { opacity: .68; transform: scaleX(.92); }
  50% { opacity: .92; transform: scaleX(1.08); }
}
@keyframes world-gate-path {
  from { opacity: 0; transform: scaleY(.08); }
  to { opacity: .72; transform: scaleY(1); }
}
.world-portal-action {
  position: relative;
  z-index: 5;
  /* `min-width: min(88vw, 326px)` made this button wider than the ring around
     it on a phone, so the two collided at the sides. It now sizes to the
     gateway and stops short of it, leaving the glow ring room to pulse. */
  width: 100%;
  max-width: 292px;
  min-height: 62px;
  margin-top: -10px;
  padding: 13px 20px 11px;
  overflow: hidden;
  display: grid;
  place-items: center;
  gap: 3px;
  border: 1px solid rgba(255,255,255,.34);
  border-radius: 22px;
  background:
    linear-gradient(145deg, rgba(255,255,255,.16), rgba(255,255,255,.035) 50%),
    rgba(70,14,35,.78);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), inset 0 -1px 0 rgba(229,200,120,.14), 0 14px 32px rgba(12,2,7,.32);
  transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease;
}
.world-portal-action::before {
  content: "";
  position: absolute;
  inset: -30% auto -30% -45%;
  width: 34%;
  transform: skewX(-18deg);
  background: linear-gradient(90deg, transparent, rgba(255,246,199,.18), transparent);
  transition: left .7s ease;
}
.world-portal-action::after {
  content: "";
  position: absolute;
  top: -4px;
  left: 50%;
  width: 9px;
  aspect-ratio: 1;
  transform: translateX(-50%) rotate(45deg);
  border: 1px solid rgba(255,239,184,.72);
  background: var(--maroon-deep);
}
.world-portal-action strong {
  font-family: var(--serif-display);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .045em;
  text-indent: .045em;
  text-transform: none;
  color: #f6e7b6;
}
.world-portal-action small {
  font-family: var(--serif-body);
  font-size: 13px;
  font-style: normal;
  line-height: 1.35;
  color: rgba(244,235,219,.76);
}
/* Small phones: the whole gateway steps down one size rather than pressing
   against the screen edges. */
@media (max-width: 400px) {
  .world-gateway { width: min(100%, 312px); }
  .world-portal-visual { width: clamp(132px, 40vw, 168px); }
  .world-portal-action { max-width: 264px; min-height: 58px; padding: 12px 16px 10px; }
  .world-portal-action small { font-size: 12px; }
  .world-gateway-kicker { font-size: 13.5px; }
}
.portal-tap-cue {
  position: relative;
  z-index: 6;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 5px 11px 5px 8px;
  border: 1px solid rgba(255,239,184,.4);
  border-radius: 999px;
  background: rgba(41,7,19,.48);
  color: rgba(255,244,207,.9);
  font-family: var(--serif-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .035em;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(0, 9px, 0) scale(.96);
}
.portal-tap-hand {
  display: inline-block;
  font-family: "Segoe UI Symbol", sans-serif;
  font-size: 18px;
  line-height: 1;
  transform-origin: 50% 0;
}
#finale.shown .portal-tap-cue {
  animation: portal-tap-enter .48s cubic-bezier(.2,.78,.25,1) 3.25s both;
}
#finale.shown .portal-tap-hand {
  animation: portal-tap-nudge 1.7s ease-in-out 3.85s infinite;
}
@keyframes portal-tap-enter {
  to { opacity: .9; transform: translate3d(0, 0, 0) scale(1); }
}
@keyframes portal-tap-nudge {
  0%, 100% { transform: translate3d(0, 0, 0); }
  42% { transform: translate3d(0, -5px, 0); }
  68% { transform: translate3d(0, -2px, 0); }
}
.world-portal-link:focus-visible { outline: none; }
.world-portal-link:focus-visible .world-portal-action {
  outline: 3px solid #fff0b5;
  outline-offset: 4px;
  box-shadow: 0 0 0 7px rgba(229,200,120,.16), 0 14px 34px rgba(12,2,7,.34);
}
.world-portal-link:active .world-portal-action { transform: scale(.98); }
.world-portal-link:active .world-portal-visual { transform: scale(.985); }
body.portal-opening .world-portal-visual { transform: translateY(-3px) scale(1.08); }
@media (hover: hover) {
  .world-portal-link:hover .world-portal-visual { transform: translateY(-5px) scale(1.025); }
  .world-portal-link:hover .world-portal-action {
    border-color: rgba(255,239,184,.94);
    box-shadow: inset 0 0 0 3px rgba(229,200,120,.1), inset 0 0 30px rgba(229,200,120,.13), 0 16px 38px rgba(12,2,7,.35);
  }
  .world-portal-link:hover .world-portal-action::before { left: 118%; }
}

/* The expanding veil ends on the exact night gradient used by the 3D loader. */
#portal-transition {
  --portal-x: 50vw;
  --portal-y: 50vh;
  position: fixed;
  inset: 0;
  z-index: 999;
  display: grid;
  place-items: center;
  overflow: hidden;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  clip-path: circle(0 at var(--portal-x) var(--portal-y));
  color: #f6e7b6;
  background: radial-gradient(ellipse at 50% 60%, #2a1020 0%, #14060f 70%, #0a0512 100%);
  transition: clip-path .82s cubic-bezier(.68,.05,.2,1), opacity .08s linear, visibility 0s linear .82s;
}
body.portal-opening {
  overflow: hidden;
  touch-action: none;
}
body.portal-opening #portal-transition {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
  clip-path: circle(150vmax at var(--portal-x) var(--portal-y));
  transition-delay: 0s;
}
.portal-transition-rays {
  position: absolute;
  width: 130vmax;
  height: 130vmax;
  border-radius: 50%;
  opacity: 0;
  background:
    radial-gradient(circle, rgba(255,246,199,.96) 0 3%, rgba(229,200,120,.64) 8%, transparent 34%),
    repeating-conic-gradient(from 0deg, rgba(255,239,184,.25) 0 5deg, transparent 5deg 15deg);
  -webkit-mask-image: radial-gradient(circle, #000 0 10%, rgba(0,0,0,.88) 30%, transparent 68%);
  mask-image: radial-gradient(circle, #000 0 10%, rgba(0,0,0,.88) 30%, transparent 68%);
}
body.portal-opening .portal-transition-rays { animation: portal-bloom .78s ease-out forwards; }
@keyframes portal-bloom {
  0% { opacity: 0; transform: scale(.18) rotate(0deg); }
  34% { opacity: .95; }
  100% { opacity: 0; transform: scale(1.25) rotate(16deg); }
}
.portal-transition-copy {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: 9px;
  padding: 28px;
  opacity: 0;
  transform: translateY(10px);
  text-align: center;
}
.portal-transition-copy span {
  font-family: var(--serif-dev);
  font-size: 17px;
  letter-spacing: .16em;
  color: var(--gold-soft);
}
.portal-transition-copy strong {
  font-family: var(--serif-display);
  font-size: clamp(14px, 4vw, 19px);
  font-weight: 500;
  letter-spacing: .24em;
  text-indent: .24em;
  text-transform: uppercase;
}
body.portal-opening .portal-transition-copy {
  opacity: 1;
  transform: none;
  transition: opacity .3s ease .23s, transform .45s ease .18s;
}

@media (prefers-reduced-motion: reduce) {
  #finale > * { opacity: 1; transform: none; }
  #scratch-wrap.revealed::before,
  #finale.shown .portal-tap-cue {
    animation: none;
    opacity: .82;
    transform: none;
  }
  #finale.shown .portal-tap-hand { animation: none; }
  #portal-transition,
  body.portal-opening #portal-transition { clip-path: none; }
}

/* ── Studio credit + draft badge ── */
.finale-credit{
  margin-top:26px;font-family:var(--serif-display);font-size:10.5px;letter-spacing:.24em;
  text-transform:uppercase;color:rgba(244,235,219,.42);text-decoration:none;
}
.finale-credit:hover{color:var(--gold-soft)}

#draft-badge{
  position:fixed;left:50%;transform:translateX(-50%);bottom:calc(env(safe-area-inset-bottom,0px) + 14px);z-index:999;
  padding:10px 20px;border:1px solid rgba(229,200,120,.65);border-radius:999px;
  background:rgba(28,4,9,.88);color:var(--gold-soft);text-decoration:none;
  font-family:var(--sans, -apple-system, BlinkMacSystemFont, sans-serif);font-size:12.5px;font-weight:500;
  letter-spacing:.06em;text-transform:uppercase;
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  box-shadow:0 8px 32px rgba(0,0,0,.6), 0 0 0 1px rgba(255,255,255,.06) inset;
  display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
  transition:all .25s ease;
}
#draft-badge:hover{
  background:rgba(201,162,75,.2);border-color:var(--gold);color:#FFF;transform:translateX(-50%) translateY(-1px);
}

/* ═══════════════ EXPIRED SCREEN ═══════════════ */
/* Only paints once JS removes [hidden] (a real, past-date guest link).
   Without :not([hidden]) the flex display overrides the hidden attribute
   and the retired screen shows on the demo, the editor preview, everything. */
.expired[hidden] { display: none; }
.expired {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(20px, 5vw, 40px);
  background: radial-gradient(150% 110% at 50% 20%, #7A1F3D 0%, #4a0f22 40%, #22050F 100%);
  overflow-y: auto;
}
.expired-inner {
  max-width: 520px;
  text-align: center;
  color: var(--cream);
  animation: expired-fade-in .8s ease-out .2s both;
}
@keyframes expired-fade-in {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
.expired-om {
  display: block;
  font-size: clamp(48px, 14vw, 72px);
  line-height: 1;
  color: var(--gold-pale);
  margin-bottom: 16px;
  opacity: .8;
  font-weight: 300;
}
.expired-title {
  font-family: var(--serif);
  font-size: clamp(28px, 8vw, 48px);
  font-weight: 500;
  color: var(--gold-pale);
  margin: 0 0 24px;
  letter-spacing: .03em;
  line-height: 1.2;
}
.expired-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 28px 0;
  opacity: .6;
}
.expired-divider span {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-pale), transparent);
}
.expired-divider svg {
  width: 20px;
  height: 20px;
  color: var(--gold-pale);
}
.expired-message {
  font-family: var(--serif-dev);
  font-size: clamp(15px, 4vw, 18px);
  line-height: 1.8;
  color: rgba(246,231,182,.92);
  margin: 0 0 20px;
  font-weight: 300;
}
.expired-blessing {
  font-family: var(--serif-dev);
  font-size: clamp(14px, 3.8vw, 16px);
  line-height: 1.7;
  color: rgba(246,231,182,.78);
  margin: 0 0 24px;
  font-style: italic;
  font-weight: 300;
}
.expired-verse {
  font-family: var(--serif);
  font-size: clamp(20px, 6vw, 32px);
  color: var(--gold-pale);
  margin: 28px 0 8px;
  font-weight: 400;
  letter-spacing: .08em;
}
.expired-verse-sub {
  font-family: var(--serif-dev);
  font-size: 13px;
  color: rgba(246,231,182,.65);
  margin: 0;
  letter-spacing: .1em;
  text-transform: uppercase;
}

