:root {
  --paper: #fbf5f1;
  --paper-2: #f5e8e2;
  --blush: #efc9c1;
  --rose: #d7958c;
  --mauve: #8a5650;
  --ink: #5b3532;
  --terra: #a9432c;
  --terra-deep: #8f3522;
  --copper: #bf6a43;
  --line: rgba(138, 86, 80, 0.28);
  --cream: #fbeee6;

  --serif: "Cormorant Garamond", Georgia, serif;
  --caps: "Cormorant SC", "Cormorant Garamond", Georgia, serif;
  --script: "Pinyon Script", cursive;
  --deva: "Tiro Devanagari Hindi", serif;
  --sans: "Jost", system-ui, sans-serif;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --gutter: clamp(16px, 5vw, 64px);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 72px; }
body {
  margin: 0;
  /* Paper grain: a small noise PNG made once in app.js (--grain), layered into
     backgrounds. No full-screen overlay, so nothing re-blends while scrolling. */
  background: var(--grain, none), var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 19px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; }
h1, h2, h3 { margin: 0; font-weight: 400; }
p { margin: 0; }
.script { font-family: var(--script); }

.skip {
  position: absolute; left: -999px; top: 8px; z-index: 200;
  background: var(--ink); color: var(--paper); padding: 8px 14px;
}
.skip:focus { left: 8px; }

:focus-visible { outline: 1.5px solid var(--terra); outline-offset: 3px; }

/* ---------- Envelope intro ---------- */
.intro { display: none; }
.js .intro {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center; overflow: hidden;
  background:
    var(--grain, none),
    radial-gradient(circle at 18% 22%, rgba(241, 201, 194, 0.55), transparent 42%),
    radial-gradient(circle at 85% 80%, rgba(243, 214, 207, 0.6), transparent 45%),
    var(--paper);
  transition: opacity 0.9s var(--ease), visibility 0s linear 0.9s;
}
.intro.gone { opacity: 0; visibility: hidden; }
/* Hold the hero's entrance until the envelope is open. The class sits on the
   hero itself (not <html>), so releasing it only restyles the hero. Scrolling
   is blocked in JS rather than with overflow:hidden on <html>/<body>: toggling
   that re-lays-out the whole page in the middle of the hand-over (measured). */
/* The hero's entrance animations are only attached once .go is added (see
   app.js). Pausing them instead needed an !important rule, and Chrome refuses
   to run any animation touched by !important on the GPU (measured). */
/* Everything that animates during the opening gets its GPU layer up front, so
   no layer is created and painted from scratch mid-animation. */
.js .intro { will-change: opacity; }
/* 0.999 rather than fully opaque: an opaque cover lets the GPU skip drawing
   the hero underneath, so the whole hero was first drawn in a single frame
   when the envelope started fading (~90ms hitch, measured). */
.js .intro:not(.gone) { opacity: 0.999; }

.intro-stage {
  display: flex; flex-direction: column; align-items: center; gap: 34px;
  padding: 0 16px; transition: transform 0.9s var(--ease); will-change: transform;
}
/* As the card rises out, glide the whole group down so the open envelope and
   card sit centred, in step with the card (same 1s, same 1.05s delay).
   The card ends 59% of an envelope-height above the envelope, so the group's
   centre moves up 29.5% of that height = 0.197 x envelope width. The extra
   26px recentres for the hint line under the envelope (half its height + gap).
   Translate only: scaling the 3D envelope makes the GPU redraw it (measured). */
.intro { --open-shift: calc(min(460px, 86vw) * 0.197 + 26px); }
.intro.open .intro-stage {
  transform: translate3d(0, var(--open-shift), 0);
  transition: transform 1s var(--ease) 1.05s;
}
/* Then drift up a little as it fades into the hero. */
.intro.open.gone .intro-stage {
  transform: translate3d(0, calc(var(--open-shift) - 18px), 0);
  transition: transform 0.9s var(--ease);
}
.intro.gone .intro-stage { transform: translate3d(0, -18px, 0); }
.env-float { animation: bob 4.5s ease-in-out infinite; }
.intro.open .env-float { animation-play-state: paused; }
@keyframes bob { 0%, 100% { transform: translateY(0) rotate(-0.4deg); } 50% { transform: translateY(-8px) rotate(0.4deg); } }

.env {
  position: relative; width: min(460px, 86vw); aspect-ratio: 3 / 2;
  perspective: 1400px; cursor: pointer;
}
.env-back {
  position: absolute; inset: 0; border-radius: 3px;
  background: linear-gradient(180deg, #dea69b, #e7b8ae);
  box-shadow: 0 34px 60px -34px rgba(91, 53, 50, 0.6), 0 2px 6px rgba(91, 53, 50, 0.08);
}
.env-card {
  position: absolute; left: 5%; right: 5%; top: 6%; height: 88%; z-index: 2;
  background: var(--grain, none), #fffaf7; text-align: center;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  box-shadow: 0 2px 12px rgba(91, 53, 50, 0.14);
  transition: transform 1s var(--ease) 1.05s; will-change: transform;
}
.env-card::before { content: ""; position: absolute; inset: 7px; border: 1px solid var(--line); pointer-events: none; }
.env-card-kicker, .env-card-date {
  font-family: var(--sans); font-weight: 300; text-transform: uppercase;
  font-size: clamp(8px, 2.2vw, 10px); letter-spacing: 0.26em; color: var(--mauve);
}
.env-card-names { font-family: var(--script); font-size: clamp(28px, 8vw, 42px); line-height: 1.15; color: var(--ink); }
.env-card-line { font-style: italic; font-size: clamp(13px, 3.4vw, 16px); color: var(--mauve); margin-bottom: 6px; }
.env-card-city { font-style: italic; font-size: clamp(12px, 3vw, 14px); color: var(--mauve); }
.intro.open .env-card { transform: translateY(-74%); }

.env-front { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 3; pointer-events: none; }

.env-flap {
  position: absolute; left: 0; right: 0; top: 0; height: 60%; z-index: 4;
  transform-origin: top center; transform-style: preserve-3d; will-change: transform;
  transition: transform 0.85s cubic-bezier(0.5, 0, 0.3, 1) 0.35s, z-index 0s linear 0.78s;
}
.flap-face { position: absolute; inset: 0; clip-path: polygon(0 0, 100% 0, 50% 100%); backface-visibility: hidden; }
.flap-out { background: linear-gradient(180deg, #f1d1c9 0%, #e8bcb2 100%); }
.flap-in {
  /* Its own flip composes with the flap's, so draw the triangle upside down
     here; once open it reads as a flap pointing up from the envelope edge. */
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
  transform: rotateX(180deg);
  background:
    radial-gradient(circle, transparent 7px, #fff4ee 7px, #fff4ee 8.2px, transparent 8.2px) 0 0 / 22px 22px,
    #e9b9ae;
}
.intro.open .env-flap { transform: rotateX(180deg); z-index: 1; }

.env-seal {
  position: absolute; left: 50%; top: 60%; z-index: 5;
  width: 66px; height: 66px; transform: translate(-50%, -50%);
  border: 0; cursor: pointer; padding: 0;
  border-radius: 48% 52% 50% 50% / 52% 47% 53% 48%;
  background: radial-gradient(circle at 38% 32%, #c65a40, var(--terra) 55%, #86321f 100%);
  box-shadow: 0 6px 14px -4px rgba(91, 35, 25, 0.55), inset 0 -3px 6px rgba(0, 0, 0, 0.18), inset 0 2px 3px rgba(255, 220, 200, 0.25);
  color: #fbe4d8; font-family: var(--serif); font-size: 19px; letter-spacing: 0.02em;
  transition: transform 0.45s var(--ease), opacity 0.45s var(--ease);
}
.env-seal span {
  display: grid; place-items: center; position: absolute; inset: 8px;
  border-radius: 50%; border: 1px solid rgba(251, 228, 216, 0.45);
}
.env-seal::after {
  content: ""; position: absolute; inset: -6px; border-radius: 50%;
  border: 1px solid var(--terra); opacity: 0; animation: ring 2.4s var(--ease) 1.2s infinite;
}
@keyframes ring { 0% { transform: scale(0.85); opacity: 0.6; } 100% { transform: scale(1.45); opacity: 0; } }
.env-seal:hover { transform: translate(-50%, -50%) scale(1.06); }
.env-seal:focus-visible { outline-offset: 6px; }
.intro.open .env-seal { transform: translate(-50%, -50%) scale(0.5) rotate(-30deg); opacity: 0; }
.intro.open .env-seal::after { animation: none; }

.intro-hint {
  font-family: var(--sans); font-weight: 300; font-size: 12px; letter-spacing: 0.3em;
  text-transform: uppercase; color: var(--mauve);
  animation: rise 1.2s var(--ease) 0.4s both;
}
.intro-hint { display: grid; justify-items: center; }
.intro-hint span { grid-area: 1 / 1; display: inline-block; transition: opacity 0.5s var(--ease), transform 0.5s var(--ease); }
.intro.open .intro-hint span { opacity: 0; transform: translateY(8px); }

/* Loading: the seal waits until fonts and artwork are ready */
.intro.loading .hint-ready, .intro:not(.loading) .hint-wait { opacity: 0; transform: translateY(6px); }
.intro.loading .hint-wait i { animation: dot 1.2s ease-in-out infinite; }
.hint-wait i {
  display: inline-block; width: 3px; height: 3px; margin-left: 4px; border-radius: 50%;
  background: currentColor; vertical-align: middle;
}
.hint-wait i:nth-child(2) { animation-delay: 0.15s; }
.hint-wait i:nth-child(3) { animation-delay: 0.3s; }
.intro.loading .env-seal { opacity: 0; transform: translate(-50%, -50%) scale(0.55); pointer-events: none; }
.intro.loading .env-seal::after { animation: none; }
.intro:not(.loading):not(.open) .env-seal {
  transition: transform 0.7s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.5s var(--ease);
}

/* ---------- Nav ---------- */
.nav {
  position: fixed; inset: 0 0 auto; z-index: 50;
  transition: background-color 0.5s var(--ease), box-shadow 0.5s var(--ease);
}
.nav.scrolled {
  /* Near-solid instead of backdrop-filter blur, which re-blurs whatever is
     behind the bar on every scroll frame. */
  background: rgba(251, 245, 241, 0.97);
  box-shadow: 0 1px 0 var(--line);
}
.nav-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: 64px;
  padding: 0 var(--gutter);
}
.nav-links {
  display: flex; gap: 28px; list-style: none; margin: 0; padding: 0;
  font-family: var(--sans); font-weight: 300; font-size: 12px;
  letter-spacing: 0.22em; text-transform: uppercase;
}
.nav-right { justify-content: flex-end; align-items: center; }
.nav-links a { text-decoration: none; position: relative; padding: 4px 0; }
.nav-links a:not(.nav-rsvp)::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform 0.4s var(--ease);
}
.nav-links a:hover::after { transform: scaleX(1); }
.nav-brand {
  font-family: var(--caps); font-size: 20px; letter-spacing: 0.18em;
  text-decoration: none; white-space: nowrap;
  opacity: 0; transform: translateY(-6px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.nav.scrolled .nav-brand { opacity: 1; transform: none; }
.nav-rsvp {
  border: 1px solid var(--mauve); border-radius: 999px; padding: 6px 16px !important;
  transition: background-color 0.3s, color 0.3s;
}
.nav-rsvp:hover { background: var(--mauve); color: var(--paper); }

.nav-toggle {
  display: none; justify-self: end; grid-column: 3;
  width: 40px; height: 40px; border: 0; background: none; cursor: pointer;
  position: relative;
}
.nav-toggle span {
  position: absolute; left: 10px; right: 10px; height: 1px; background: var(--ink);
  transition: transform 0.4s var(--ease), top 0.4s var(--ease);
}
.nav-toggle span:first-child { top: 16px; }
.nav-toggle span:last-child { top: 23px; }
.nav-toggle[aria-expanded="true"] span:first-child { top: 20px; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:last-child { top: 20px; transform: rotate(-45deg); }

.drawer {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.5s var(--ease);
  background: rgba(251, 245, 241, 0.97);
}
.drawer.open { grid-template-rows: 1fr; box-shadow: 0 1px 0 var(--line); }
.drawer-inner { overflow: hidden; display: flex; flex-direction: column; align-items: center; }
.drawer-inner a {
  text-decoration: none; font-family: var(--caps); font-size: 22px; letter-spacing: 0.14em;
  padding: 10px 0; opacity: 0; transform: translateY(-6px);
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.drawer-inner a:first-child { margin-top: 8px; }
.drawer-inner a:last-child { margin-bottom: 20px; }
.drawer.open .drawer-inner a { opacity: 1; transform: none; }
.drawer.open .drawer-inner a:nth-child(2) { transition-delay: 0.04s; }
.drawer.open .drawer-inner a:nth-child(3) { transition-delay: 0.08s; }
.drawer.open .drawer-inner a:nth-child(4) { transition-delay: 0.12s; }
.drawer.open .drawer-inner a:nth-child(5) { transition-delay: 0.16s; }
.drawer.open .drawer-inner a:nth-child(6) { transition-delay: 0.2s; }

@media (max-width: 860px) {
  .nav-links { display: none; }
  .nav-brand { grid-column: 2; font-size: 17px; }
  .nav-toggle { display: block; }
  .nav.drawer-open { background: rgba(251, 245, 241, 0.97); }
  .nav.drawer-open .nav-brand { opacity: 1; transform: none; }
}
@media (min-width: 861px) { .drawer { display: none; } }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid; place-items: center;
  overflow: hidden;
  background:
    var(--grain, none),
    radial-gradient(ellipse at 50% 55%, rgba(255, 252, 249, 0.9), transparent 60%),
    var(--paper);
}
.wash { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; will-change: transform; }
.wash canvas { position: absolute; display: block; pointer-events: none; }
/* Layers are pre-painted bitmaps; only opacity and transform animate. */
/* 0.001, not 0: fully transparent layers are skipped, so the canvases would
   only be uploaded to the GPU at the hand-over (a ~200ms hitch, measured).
   At 0.001 that upload happens during loading, invisibly. */
.js .wash canvas { opacity: 0.001; }
.js .wash .layer-flower { will-change: transform, opacity; transform-origin: 50% 50%; }
.js .hero.go .wash .layer-pools { animation: fade-in 1.8s ease forwards; }
.js .hero.go .wash .layer-stems { animation: fade-in 2.4s var(--ease) forwards; }
.js .hero.go .wash .layer-flower { animation: bloom 2.6s var(--ease) forwards; }
.js .hero.go .wash.instant canvas, .js .wash.instant canvas { animation: none; opacity: 1; }
@keyframes fade-in { to { opacity: 1; } }
@keyframes bloom {
  from { opacity: 0.001; transform: scale(0.6) rotate(-14deg); }
  55% { opacity: 1; }
  to { opacity: 1; transform: none; }
}
.hero.go.offscreen .petal, .hero.offscreen .scroll-cue span { animation-play-state: paused; }
.petals { position: absolute; inset: 0; pointer-events: none; }
.petal {
  position: absolute; top: -40px;
  width: 16px; height: 22px;
  border-radius: 80% 0 80% 0;
  background: radial-gradient(circle at 30% 30%, #f6d8d2, #e3a79f 70%);
  opacity: 0.7;
  opacity: 0;
  will-change: transform, opacity;
}
.hero.go .petal { animation: fall-a linear infinite; }
/* Fixed drifts (no CSS variables inside keyframes) keep these on the GPU. */
.hero.go .petal.b { animation-name: fall-b; }
.hero.go .petal.c { animation-name: fall-c; }
@keyframes fall-a {
  0% { transform: translate3d(0, -5vh, 0) rotate(0deg); opacity: 0; }
  10% { opacity: 0.75; }
  50% { transform: translate3d(48px, 50vh, 0) rotate(200deg); }
  90% { opacity: 0.6; }
  100% { transform: translate3d(-24px, 105vh, 0) rotate(400deg); opacity: 0; }
}
@keyframes fall-b {
  0% { transform: translate3d(0, -5vh, 0) rotate(0deg); opacity: 0; }
  10% { opacity: 0.75; }
  50% { transform: translate3d(-56px, 50vh, 0) rotate(-180deg); }
  90% { opacity: 0.6; }
  100% { transform: translate3d(28px, 105vh, 0) rotate(-380deg); opacity: 0; }
}
@keyframes fall-c {
  0% { transform: translate3d(0, -5vh, 0) rotate(0deg); opacity: 0; }
  10% { opacity: 0.75; }
  50% { transform: translate3d(22px, 50vh, 0) rotate(160deg); }
  90% { opacity: 0.6; }
  100% { transform: translate3d(64px, 105vh, 0) rotate(330deg); opacity: 0; }
}

.hero-content {
  position: relative; z-index: 2; text-align: center;
  padding: 96px var(--gutter) 80px;
}
.monogram { width: 120px; height: 150px; display: block; margin: 0 auto 22px; overflow: visible; }
.arch { fill: none; stroke: var(--mauve); stroke-width: 1.1; }
.arch-inner { stroke-width: 0.6; opacity: 0.6; }
.mono-letter { font-family: var(--serif); font-weight: 300; font-size: 44px; fill: var(--ink); }
.mono-amp { font-family: var(--script); font-size: 26px; fill: var(--mauve); }

.js .hero .arch { stroke-dasharray: 340; stroke-dashoffset: 340; }
.js .hero.go .arch { animation: draw 2.4s var(--ease) 0.3s forwards; }
.js .hero.go .arch-inner { animation-delay: 0.6s; }
.js .hero .mono-letter, .js .hero .mono-amp { opacity: 0; }
.js .hero.go .mono-letter, .js .hero.go .mono-amp { animation: rise 1.2s var(--ease) forwards; }
.js .hero.go .mono-letter:nth-of-type(1) { animation-delay: 1.1s; }
.js .hero.go .mono-amp { animation-delay: 1.35s; }
.js .hero.go .mono-letter:nth-of-type(3) { animation-delay: 1.6s; }
@keyframes draw { to { stroke-dashoffset: 0; } }

.names {
  font-family: var(--caps); font-weight: 400;
  font-size: clamp(34px, 7vw, 64px);
  letter-spacing: 0.16em; line-height: 1.05;
  display: flex; flex-direction: column; align-items: center;
}
.names .word { padding-left: 0.16em; }
.names-and {
  font-family: var(--caps); font-size: 0.32em; letter-spacing: 0.4em;
  margin: 6px 0; color: var(--mauve);
}
.hero-date {
  margin-top: 26px; font-family: var(--sans); font-weight: 300;
  font-size: 13px; letter-spacing: 0.5em; padding-left: 0.5em;
}
.hero-city { margin-top: 6px; font-style: italic; color: var(--mauve); font-size: 18px; }
/* Names arrive letter by letter (spans built in app.js, delays set inline) */
.names .ch { display: inline-block; }
.js .names .ch { opacity: 0.001; will-change: transform, opacity; }
.js .hero.go .names .ch { animation: letter 1.2s var(--ease) forwards; }
@keyframes letter {
  from { opacity: 0.001; transform: translateY(0.45em) rotate(4deg) scale(0.92); }
  to { opacity: 1; transform: none; }
}
.js .names > .names-and, .js .hero-date, .js .hero-city { opacity: 0.001; will-change: transform, opacity; }
.js .hero.go .names > .names-and, .js .hero.go .hero-date, .js .hero.go .hero-city { animation: rise 1.4s var(--ease) forwards; }
.js .hero.go .names > .names-and { animation-delay: 1.75s; }
.js .hero.go .hero-date { animation-delay: 2.7s; }
.js .hero.go .hero-city { animation-delay: 2.9s; }
.hero-content { will-change: transform, opacity; }
@keyframes rise { from { opacity: 0.001; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.scroll-cue {
  position: absolute; bottom: 28px; left: 50%; transform: translateX(-50%);
  width: 22px; height: 36px; border: 1px solid var(--mauve); border-radius: 12px; z-index: 2;
}
.scroll-cue span {
  position: absolute; left: 50%; top: 7px; width: 2px; height: 7px; margin-left: -1px;
  background: var(--mauve); border-radius: 2px; animation: cue 2s var(--ease) infinite;
}
@keyframes cue { 0% { opacity: 0; transform: translateY(0); } 30% { opacity: 1; } 100% { opacity: 0; transform: translateY(12px); } }

/* ---------- Reveal on scroll ---------- */
.js .reveal { opacity: 0; transform: translateY(22px); transition: opacity 1s var(--ease), transform 1s var(--ease); }
.js .reveal.in { opacity: 1; transform: none; }

/* ---------- Invite ---------- */
.invite {
  text-align: center; padding: 120px var(--gutter) 110px;
  max-width: 820px; margin: 0 auto;
}
.lotus { width: 92px; height: 54px; fill: none; stroke: var(--copper); stroke-width: 1.1; stroke-linejoin: round; }
.invocation { font-family: var(--deva); color: var(--copper); font-size: 22px; margin-top: 14px; }
.invite-line {
  font-family: var(--caps); font-size: clamp(18px, 2.6vw, 26px);
  letter-spacing: 0.14em; text-transform: uppercase; margin-top: 26px; line-height: 1.45;
}
.invite-families { margin-top: 22px; font-style: italic; color: var(--mauve); font-size: 20px; }

/* ---------- Events ---------- */
.banner {
  position: relative; height: clamp(220px, 38vw, 420px);
  display: grid; place-items: center; overflow: hidden;
  background: linear-gradient(180deg, #ead2c8, #dcb7aa);
}
.banner.has-photo .jali { display: none; }
.banner.has-photo::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(60, 30, 26, 0.15), rgba(60, 30, 26, 0.42)); }
.banner-par { position: absolute; inset: -14% 0; will-change: transform; }
.banner-par img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transform: scale(1.18); opacity: 0;
  transition: transform 3.2s var(--ease), opacity 1.4s var(--ease);
}
.banner.in .banner-par img.loaded { transform: scale(1); opacity: 1; }
/* Fade + settle with transform (GPU). Animating letter-spacing re-lays-out
   the text on every frame. */
.banner.has-photo .banner-title { transition: transform 2.2s var(--ease), opacity 1.6s var(--ease); }
.js .banner.has-photo .banner-title { transform: scale(1.12); opacity: 0; }
.js .banner.has-photo.in .banner-title { transform: none; opacity: 1; transition-delay: 0.4s; }

/* ---------- Moment (scroll-driven arch to full screen) ---------- */
.moment { position: relative; height: 260vh; background: var(--grain, none), var(--paper); }
.moment-sticky { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }
.moment-frame {
  position: absolute; inset: 0; background: var(--paper-2);
  clip-path: inset(18% 34% 18% 34% round 999px 999px 0 0);
  will-change: clip-path;
}
.moment-frame video {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 24%; display: block;
  transform: scale(1.2); transform-origin: 50% 35%; will-change: transform;
}
.moment-shade {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(40, 20, 18, 0) 40%, rgba(40, 20, 18, 0.5));
  opacity: 0; will-change: opacity;
}
.moment-line {
  position: absolute; left: 0; right: 0; bottom: 11vh; margin: 0; padding: 0 16px;
  text-align: center; color: #fffaf6; font-family: var(--script);
  font-size: clamp(46px, 8vw, 104px); line-height: 1.1;
  text-shadow: 0 2px 30px rgba(40, 20, 18, 0.35);
  opacity: 0; transform: translate3d(0, 30px, 0); will-change: transform, opacity;
}
.moment-kicker {
  position: absolute; left: 0; right: 0; text-align: center; z-index: 1;
  font-family: var(--sans); font-weight: 300; font-size: 12px; letter-spacing: 0.32em;
  text-transform: uppercase; color: var(--mauve); top: 0; will-change: transform, opacity;
}

/* ---------- Our story (polaroids) ---------- */
.story { padding: 120px var(--gutter) 140px; text-align: center; overflow: hidden; }
.polaroids {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 34px 26px;
  max-width: 1240px; margin: 60px auto 0;
}
.polaroid {
  position: relative; width: clamp(150px, 19vw, 220px); padding: 10px 10px 0; border: 0;
  background: #fffdfb; cursor: zoom-in; font: inherit; color: inherit;
  box-shadow: 0 1px 2px rgba(91, 53, 50, 0.12), 0 18px 32px -22px rgba(91, 53, 50, 0.55);
  transform: rotate(var(--r, 0deg)) translateY(var(--y, 0px));
  transition: transform 0.6s var(--ease), box-shadow 0.6s var(--ease), opacity 1s var(--ease);
}
.polaroid::before {
  content: ""; position: absolute; top: -12px; left: 50%; width: 74px; height: 24px; z-index: 1;
  transform: translateX(-50%) rotate(calc(var(--r, 0deg) * -1.6));
  background: rgba(239, 201, 193, 0.72);
  box-shadow: 0 1px 2px rgba(91, 53, 50, 0.08);
}
.polaroid:hover, .polaroid:focus-visible {
  transform: rotate(0deg) translateY(-10px) scale(1.05); z-index: 3;
  box-shadow: 0 2px 4px rgba(91, 53, 50, 0.12), 0 34px 50px -26px rgba(91, 53, 50, 0.6);
}
.js .polaroid.reveal {
  opacity: 0; transform: translateY(-70px) rotate(calc(var(--r, 0deg) * 4));
  transition: transform 0.9s var(--ease), box-shadow 0.6s var(--ease), opacity 0.9s var(--ease);
}
.js .polaroid.reveal.in { opacity: 1; transform: rotate(var(--r, 0deg)) translateY(var(--y, 0px)); }
.js .polaroid.reveal.in:hover, .js .polaroid.reveal.in:focus-visible { transform: rotate(0deg) translateY(-10px) scale(1.05); }
/* Skeleton shimmer: a highlight slid with transform (GPU) instead of
   animating background-position, which repaints on the main thread every
   frame, forever, for photos further down that haven't loaded yet. */
.polaroid-img { aspect-ratio: 3 / 4; overflow: hidden; position: relative; background: #f3e6e0; }
.polaroid-img::before {
  content: ""; position: absolute; inset: 0; will-change: transform;
  background: linear-gradient(90deg, transparent 0%, rgba(255, 250, 247, 0.75) 50%, transparent 100%);
  transform: translateX(-100%);
}
.story.inview .polaroid-img::before { animation: shimmer-x 1.4s linear infinite; }
.polaroid-img.done::before { display: none; }
@keyframes shimmer-x { to { transform: translateX(100%); } }
.polaroid-img img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 0; transform: scale(1.08); transition: opacity 0.9s var(--ease), transform 1.4s var(--ease);
}
.polaroid-img img.loaded { opacity: 1; transform: none; }
.polaroid-cap { font-family: var(--script); font-size: 22px; line-height: 1; padding: 12px 4px 14px; min-height: 48px; color: var(--ink); }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (max-width: 560px) {
  .polaroids { gap: 26px 14px; }
  .polaroid { width: calc(50% - 10px); padding: 7px 7px 0; }
  .polaroid-cap { font-size: 18px; min-height: 40px; padding: 10px 2px 12px; }
}

/* ---------- Lightbox ---------- */
.lightbox[hidden] { display: none; }
.lightbox { position: fixed; inset: 0; z-index: 95; }
.lb-backdrop { position: absolute; inset: 0; background: rgba(43, 24, 22, 0.88); opacity: 0; transition: opacity 0.5s var(--ease); }
.lightbox.show .lb-backdrop { opacity: 1; }
.lb-img {
  position: fixed; left: 0; top: 0; transform-origin: 0 0; object-fit: cover;
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.6); will-change: transform, opacity;
  transition: transform 0.6s var(--ease), opacity 0.45s var(--ease);
}
.lb-caption, .lb-count { position: fixed; left: 0; right: 0; text-align: center; color: #fbeee6; opacity: 0; transition: opacity 0.5s var(--ease) 0.2s; pointer-events: none; }
.lb-caption { bottom: 18px; font-family: var(--script); font-size: 30px; }
.lb-count { top: 22px; font-family: var(--sans); font-weight: 300; font-size: 12px; letter-spacing: 0.3em; }
.lightbox.show .lb-caption, .lightbox.show .lb-count, .lightbox.show .lb-btn { opacity: 1; }
.lb-btn {
  position: fixed; width: 48px; height: 48px; border-radius: 50%; border: 1px solid rgba(251, 238, 230, 0.5);
  background: rgba(43, 24, 22, 0.3); color: #fbeee6; font-size: 28px; line-height: 1; cursor: pointer;
  display: grid; place-items: center; opacity: 0; transition: opacity 0.5s var(--ease) 0.2s, background-color 0.3s;
}
.lb-btn:hover { background: rgba(251, 238, 230, 0.15); }
.lb-close { top: 14px; right: 14px; }
.lb-prev { left: 14px; top: 50%; margin-top: -24px; }
.lb-next { right: 14px; top: 50%; margin-top: -24px; }

/* ---------- Scroll progress line ---------- */
.nav-progress {
  position: absolute; left: 0; bottom: 0; height: 1.5px; width: 100%;
  background: var(--copper); transform-origin: left center; transform: scaleX(0); will-change: transform;
  opacity: 0; transition: opacity 0.5s var(--ease);
}
.nav.scrolled .nav-progress { opacity: 0.8; }
.jali { position: absolute; inset: 0; width: 100%; height: 100%; }
.jali circle { fill: none; stroke: #fbf1ea; stroke-width: 2.4; opacity: 0.75; }
.banner-title {
  position: relative; z-index: 1; font-family: var(--caps);
  font-size: clamp(36px, 7vw, 72px); letter-spacing: 0.3em; padding-left: 0.3em;
  color: #fffaf6; text-shadow: 0 2px 30px rgba(120, 60, 50, 0.35);
}
.js .banner { clip-path: inset(8% 6% 8% 6% round 4px); transition: clip-path 1.4s var(--ease); }
.js .banner.in { clip-path: inset(0 0 0 0 round 0px); }

.days { max-width: 820px; margin: 0 auto; padding: 80px var(--gutter) 100px; }
.day + .day { margin-top: 64px; }
.day-date { font-family: var(--script); font-size: clamp(28px, 4vw, 38px); text-align: center; color: var(--mauve); margin-bottom: 14px; }
.event-list { list-style: none; margin: 0; padding: 0; }
.event { border-bottom: 1px solid var(--line); }
.event:first-child { border-top: 1px solid var(--line); }
.event-head {
  width: 100%; display: grid; grid-template-columns: 1fr auto 20px; align-items: baseline; gap: 16px;
  background: none; border: 0; padding: 18px 2px; cursor: pointer; text-align: left; color: inherit;
}
.event-name { font-family: var(--serif); font-weight: 300; font-size: clamp(30px, 4.6vw, 44px); line-height: 1.1; transition: transform 0.5s var(--ease); }
.event-head:hover .event-name { transform: translateX(6px); }
.event-meta { font-family: var(--sans); font-weight: 300; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--mauve); }
.chev { width: 12px; height: 12px; border-right: 1px solid var(--mauve); border-bottom: 1px solid var(--mauve); transform: rotate(45deg) translateY(-4px); transition: transform 0.5s var(--ease); }
.event.open .chev { transform: rotate(225deg) translateY(-2px); }
.event-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.55s var(--ease); }
.event.open .event-body { grid-template-rows: 1fr; }
.event-inner { overflow: hidden; }
.event-detail {
  padding: 0 2px 26px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 32px;
  opacity: 0; transform: translateY(-6px); transition: opacity 0.45s var(--ease), transform 0.45s var(--ease);
}
.event.open .event-detail { opacity: 1; transform: none; transition-delay: 0.12s; }
.event-detail dl { margin: 0; font-size: 17px; }
.event-detail dt { font-family: var(--sans); font-weight: 300; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--mauve); margin-top: 10px; }
.event-detail dd { margin: 2px 0 0; }
.event-detail .event-copy { font-size: 18px; font-style: italic; color: var(--ink); align-self: center; }
.event-actions { grid-column: 1 / -1; display: flex; gap: 12px; flex-wrap: wrap; margin-top: 12px; }

.btn-line {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--sans); font-weight: 400; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  text-decoration: none; color: inherit; background: transparent; cursor: pointer;
  border: 1px solid currentColor; padding: 10px 18px; min-height: 40px;
  transition: background-color 0.3s, color 0.3s;
}
.btn-line:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

@media (max-width: 640px) {
  .event-head { grid-template-columns: 1fr 16px; }
  .event-meta { grid-column: 1; grid-row: 2; }
  .chev { grid-row: 1; grid-column: 2; align-self: center; }
  .event-detail { grid-template-columns: 1fr; }
}

/* ---------- Attire ---------- */
.attire { background: var(--grain, none), var(--paper-2); padding: 110px 0 120px; text-align: center; }
.eyebrow { font-family: var(--sans); font-weight: 300; font-size: 12px; letter-spacing: 0.32em; text-transform: uppercase; color: var(--mauve); }
.script-title { font-family: var(--script); font-size: clamp(42px, 6vw, 64px); line-height: 1.2; margin-top: 4px; color: var(--ink); }
.attire-grid {
  margin-top: 48px; display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  max-width: 1240px; margin-left: auto; margin-right: auto; padding: 0 var(--gutter);
}
.look {
  background: var(--grain, none), var(--paper); text-align: left; padding: 14px 14px 22px;
  box-shadow: 0 1px 0 var(--line), 0 18px 40px -28px rgba(91, 53, 50, 0.45);
  transition: transform 0.6s var(--ease), box-shadow 0.6s var(--ease);
}
.look:hover { transform: translateY(-6px) rotate(-0.4deg); box-shadow: 0 1px 0 var(--line), 0 30px 50px -30px rgba(91, 53, 50, 0.55); }
.board { display: grid; grid-template-columns: 1.3fr 1fr; grid-template-rows: 90px 90px; gap: 6px; }
.board .swatch { position: relative; overflow: hidden; }
.board .swatch:first-child { grid-row: 1 / 3; }
.tex-linen .swatch::after { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(90deg, rgba(255,255,255,0.12) 0 1px, transparent 1px 4px), repeating-linear-gradient(0deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 4px); }
.tex-floral .swatch::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 25% 30%, rgba(255,255,255,0.35) 0 5px, transparent 6px), radial-gradient(circle at 70% 65%, rgba(255,255,255,0.28) 0 4px, transparent 5px); background-size: 34px 34px; }
.tex-sequin .swatch::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle, rgba(255,240,210,0.55) 0 1px, transparent 1.6px); background-size: 7px 7px; }
.attire.inview .tex-sequin .swatch::after { animation: glint 4s ease-in-out infinite alternate; }
.tex-sheen .swatch::after { content: ""; position: absolute; inset: 0; background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.35) 48%, transparent 62%); transform: translateX(-120%); will-change: transform; }
.attire.inview .tex-sheen .swatch::after { animation: sheen 6s var(--ease) infinite; }
@keyframes glint { from { opacity: 0.4; } to { opacity: 1; } }
@keyframes sheen { 0% { transform: translateX(-120%); } 60%, 100% { transform: translateX(120%); } }
.look-name { font-family: var(--caps); font-size: 26px; letter-spacing: 0.12em; margin-top: 18px; text-align: center; }
.look-vibe { text-align: center; font-size: 17px; margin-top: 2px; }
.look-vibe em { font-family: var(--script); font-style: normal; font-size: 22px; color: var(--mauve); margin-right: 6px; }
.look-text { text-align: center; font-size: 16px; color: var(--mauve); margin-top: 8px; line-height: 1.5; }
.dots { display: flex; justify-content: center; gap: 6px; margin-top: 14px; }
.dots span { width: 14px; height: 14px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08); }
.look.flash { animation: flash 1.6s var(--ease); }
@keyframes flash { 0%, 100% { box-shadow: 0 1px 0 var(--line), 0 18px 40px -28px rgba(91,53,50,0.45); } 30% { box-shadow: 0 0 0 2px var(--rose), 0 18px 40px -28px rgba(91,53,50,0.45); } }

/* ---------- Travel ---------- */
.travel { background: var(--grain, none), var(--terra); color: var(--cream); position: relative; overflow: hidden; }
.travel-grid { display: grid; grid-template-columns: 1fr 1fr; }
.travel-col { padding: 96px var(--gutter) 80px; text-align: center; }
.travel-col + .travel-col { background: var(--grain, none), var(--terra-deep); }
.travel-col h2 { font-family: var(--script); font-size: clamp(40px, 5vw, 56px); line-height: 1.2; }
.travel-col p { max-width: 440px; margin: 18px auto 0; font-size: 18px; }
.travel-col .links { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-top: 26px; }
.travel .btn-line:hover { background: var(--cream); color: var(--terra-deep); border-color: var(--cream); }
.arches { display: flex; gap: clamp(8px, 2vw, 24px); padding: 0 var(--gutter); height: clamp(140px, 22vw, 260px); align-items: flex-end; background: var(--grain, none), var(--terra-deep); }
.arches span {
  flex: 1; height: 100%; border-radius: 999px 999px 0 0;
  background: linear-gradient(180deg, #f9e2cf 0%, #f0b996 55%, #d9795a 100%);
  box-shadow: inset 0 0 0 6px #c8583b, inset 0 -40px 60px -20px rgba(143,53,34,0.5);
}
.js .arches span { transform: translateY(40%); transition: transform 1.2s var(--ease); }
.js .arches.in span { transform: none; }
.js .arches.in span:nth-child(2) { transition-delay: 0.08s; }
.js .arches.in span:nth-child(3) { transition-delay: 0.16s; }
.js .arches.in span:nth-child(4) { transition-delay: 0.24s; }
.js .arches.in span:nth-child(5) { transition-delay: 0.32s; }
@media (max-width: 760px) {
  .travel-grid { grid-template-columns: 1fr; }
  .travel-col { padding: 72px var(--gutter) 64px; }
  .arches span:nth-child(n+4) { display: none; }
}

/* ---------- Explore ---------- */
.explore { padding: 110px var(--gutter) 110px; text-align: center; }
.explore-grid { max-width: 980px; margin: 48px auto 0; display: grid; grid-template-columns: 1fr 1fr; gap: 56px 64px; }
.spot h3 { font-family: var(--script); font-size: clamp(32px, 3.6vw, 40px); line-height: 1.2; color: var(--ink); }
.spot p { margin: 10px auto 0; max-width: 380px; color: var(--mauve); font-size: 18px; }
.spot .btn-line { margin-top: 18px; }
.spot:nth-child(even) { transform: translateY(40px); }
.js .spot:nth-child(even).reveal { transform: translateY(62px); }
.js .spot:nth-child(even).reveal.in { transform: translateY(40px); }
@media (max-width: 700px) {
  .explore-grid { grid-template-columns: 1fr; gap: 48px; }
  .spot:nth-child(even), .js .spot:nth-child(even).reveal.in { transform: none; }
}

/* ---------- Countdown ---------- */
.countdown { background: var(--grain, none), linear-gradient(180deg, var(--paper), #f6e2d9); padding: 110px var(--gutter) 100px; text-align: center; margin-top: 40px; }
.count-grid { display: flex; justify-content: center; gap: clamp(16px, 5vw, 64px); flex-wrap: wrap; }
.count { display: flex; flex-direction: column; align-items: center; min-width: 70px; }
.count-num { font-family: var(--serif); font-weight: 300; font-size: clamp(56px, 11vw, 128px); line-height: 1; color: var(--copper); font-variant-numeric: lining-nums tabular-nums; transition: opacity 0.35s var(--ease), transform 0.35s var(--ease); }
.count-num.tick { opacity: 0.25; transform: translateY(-6px); }
.count-lbl { font-family: var(--sans); font-weight: 300; font-size: 11px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--mauve); margin-top: 8px; }
@media (max-width: 520px) {
  .count-grid { flex-wrap: nowrap; gap: 10px; }
  .count { min-width: 0; flex: 1; }
  .count-num { font-size: clamp(36px, 12vw, 56px); }
  .count-lbl { font-size: 10px; letter-spacing: 0.16em; }
}
.count-caption { margin-top: 26px; font-style: italic; font-size: 20px; color: var(--mauve); }
.count-caption .script { font-size: 30px; font-style: normal; color: var(--ink); margin-left: 4px; }

/* ---------- FAQs ---------- */
.faqs { padding: 110px var(--gutter) 100px; max-width: 860px; margin: 0 auto; }
.caps-title { font-family: var(--caps); font-size: clamp(32px, 4vw, 44px); letter-spacing: 0.24em; text-align: center; color: var(--mauve); }
.faq-list { margin-top: 40px; }
.faq { border-bottom: 1px solid var(--line); }
.faq:first-child { border-top: 1px solid var(--line); }
.faq-q {
  width: 100%; background: none; border: 0; color: inherit; cursor: pointer; text-align: left;
  display: flex; justify-content: space-between; align-items: center; gap: 18px;
  padding: 20px 2px; font-family: var(--serif); font-size: clamp(20px, 2.4vw, 24px);
}
.plus { position: relative; width: 14px; height: 14px; flex: none; }
.plus::before, .plus::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--mauve); transition: transform 0.45s var(--ease); }
.plus::after { transform: rotate(90deg); }
.faq.open .plus::after { transform: rotate(0deg); }
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.5s var(--ease); }
.faq.open .faq-a { grid-template-rows: 1fr; }
.faq-a > div { overflow: hidden; }
.faq-a p { padding: 0 2px 22px; color: var(--mauve); font-size: 18px; max-width: 680px; opacity: 0; transition: opacity 0.4s var(--ease); }
.faq.open .faq-a p { opacity: 1; transition-delay: 0.1s; }

/* ---------- RSVP ---------- */
.rsvp { position: relative; overflow: hidden; padding: 40px var(--gutter) 130px; }
.rsvp.has-photo { padding-top: 140px; padding-bottom: 160px; }
.rsvp-bg { position: absolute; inset: -14% 0; z-index: 0; will-change: transform; }
.rsvp-bg img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; display: block; opacity: 0; transition: opacity 1.4s var(--ease); }
.rsvp-bg img.loaded { opacity: 1; }
.rsvp-bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, var(--paper) 0%, rgba(251, 245, 241, 0.5) 24%, rgba(251, 245, 241, 0.42) 76%, var(--paper-2) 100%);
}
.rsvp .rsvp-card { z-index: 1; }
.rsvp-card {
  max-width: 640px; margin: 0 auto; background: var(--grain, none), #fffaf7; padding: clamp(28px, 6vw, 56px);
  position: relative; text-align: center;
  box-shadow: 0 30px 60px -40px rgba(91, 53, 50, 0.5);
}
.rsvp-card::before { content: ""; position: absolute; inset: 10px; border: 1px solid var(--line); pointer-events: none; }
.rsvp-by { font-family: var(--sans); font-weight: 300; font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--mauve); margin-top: 6px; }
.rsvp-body { position: relative; margin-top: 30px; transition: height 0.5s var(--ease); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.rsvp-form { text-align: left; transition: opacity 0.4s var(--ease); }
.field { margin: 0 0 18px; border: 0; padding: 0; min-width: 0; }
.field label, .field legend { display: block; font-family: var(--sans); font-weight: 300; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--mauve); margin-bottom: 6px; padding: 0; }
.field input:not([type="radio"]):not([type="checkbox"]), .field select, .field textarea {
  width: 100%; font-family: var(--serif); font-size: 19px; color: var(--ink);
  background: transparent; border: 0; border-bottom: 1px solid var(--line); padding: 8px 2px; border-radius: 0;
  transition: border-color 0.3s;
}
.field textarea { resize: vertical; min-height: 80px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-bottom-color: var(--terra); }
.field input::placeholder, .field textarea::placeholder { color: rgba(138, 86, 80, 0.45); }
.field.invalid input, .field.invalid select { border-bottom-color: #b3261e; }
.field-row { display: grid; grid-template-columns: 1fr 1.6fr; gap: 20px; }
@media (max-width: 520px) { .field-row { grid-template-columns: 1fr; gap: 0; } }
.choice-row { display: flex; gap: 10px; flex-wrap: wrap; }
.choice { cursor: pointer; flex: 1 1 180px; text-transform: none !important; letter-spacing: 0 !important; margin: 0 !important; }
.choice input, .check input { position: absolute; opacity: 0; pointer-events: none; }
.choice span {
  display: block; text-align: center; border: 1px solid var(--line); padding: 12px 10px;
  font-family: var(--serif); font-size: 19px; color: var(--ink);
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.choice input:checked + span { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.choice input:focus-visible + span, .check input:focus-visible + span { outline: 1.5px solid var(--terra); outline-offset: 2px; }
.event-checks { display: flex; flex-wrap: wrap; gap: 8px; }
.check { cursor: pointer; margin: 0 !important; text-transform: none !important; letter-spacing: 0 !important; }
.check span {
  display: inline-block; border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px;
  font-family: var(--serif); font-size: 17px; color: var(--ink);
  transition: background-color 0.3s, color 0.3s, border-color 0.3s;
}
.check input:checked + span { background: var(--blush); border-color: var(--rose); }
.collapse { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.5s var(--ease); }
.collapse.open { grid-template-rows: 1fr; }
.collapse-inner { overflow: hidden; opacity: 0; transition: opacity 0.4s var(--ease); }
.collapse.open .collapse-inner { opacity: 1; }
.err { color: #b3261e; font-family: var(--sans); font-size: 13px; min-height: 0; max-height: 0; opacity: 0; overflow: hidden; transition: max-height 0.3s var(--ease), opacity 0.3s, margin 0.3s; }
.err.show { max-height: 40px; opacity: 1; margin-top: 6px; }
.form-err { text-align: center; }

.btn-solid {
  position: relative; display: flex; align-items: center; justify-content: center; width: 100%; min-height: 52px; margin-top: 10px;
  background: var(--terra); color: var(--cream); border: 0; cursor: pointer;
  font-family: var(--sans); font-weight: 400; font-size: 12px; letter-spacing: 0.3em; text-transform: uppercase;
  transition: background-color 0.3s;
}
.btn-solid:hover { background: var(--terra-deep); }
.btn-label { transition: opacity 0.3s; }
.btn-dots { position: absolute; display: flex; gap: 6px; opacity: 0; transition: opacity 0.3s; }
.btn-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--cream); }
.btn-solid.loading .btn-dots i { animation: dot 1s ease-in-out infinite; }
.btn-dots i:nth-child(2) { animation-delay: 0.15s; }
.btn-dots i:nth-child(3) { animation-delay: 0.3s; }
@keyframes dot { 0%, 100% { transform: translateY(0); opacity: 0.4; } 50% { transform: translateY(-4px); opacity: 1; } }
.btn-solid.loading { pointer-events: none; }
.btn-solid.loading .btn-label { opacity: 0; }
.btn-solid.loading .btn-dots { opacity: 1; }

.rsvp-thanks { position: absolute; inset: 0 0 auto; opacity: 0; pointer-events: none; transform: translateY(10px); transition: opacity 0.6s var(--ease) 0.15s, transform 0.6s var(--ease) 0.15s; padding: 10px 0; }
.rsvp-body.done { overflow: hidden; }
.rsvp-body.done .rsvp-form { opacity: 0; pointer-events: none; }
.rsvp-body.done .rsvp-thanks { opacity: 1; pointer-events: auto; transform: none; }
.thanks-title { font-size: 56px; line-height: 1.1; }
.thanks-text { margin: 12px auto 24px; max-width: 420px; color: var(--mauve); font-size: 19px; }

/* ---------- Footer ---------- */
.footer { text-align: center; padding: 70px var(--gutter) 60px; background: var(--grain, none), var(--paper-2); }
.monogram-sm { width: 70px; height: 88px; margin-bottom: 12px; }
.footer-tag { font-family: var(--sans); font-weight: 300; letter-spacing: 0.24em; font-size: 12px; text-transform: uppercase; color: var(--mauve); }
.footer-top { display: inline-block; margin-top: 18px; font-style: italic; color: var(--mauve); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
  html { scroll-behavior: auto; }
  .petals { display: none; }
}
