:root {
  --pink: #FF46A2;
  --pink-ink: #7d0b45;
  --scene: #FFEBE7;
  --card-ink: #8A0B4C;
  --ink: #b0105c;
  --foil: url("assets/foil.webp?v=5");
  --glitter: url("assets/glitter.webp?v=3");
  /* Type: three sizes only, the headline, the name line, and everything else */
  --gold: #F6D8A8;
  --cream: var(--gold);
  --fs-body: clamp(16px, calc(.6vw + 13.6px), 18px);
  --fs-name: calc(clamp(16px, calc(.6vw + 13.6px), 20px) * 2); /* name size unchanged by the body tweak */
  --track: .14em;
  --sheen: linear-gradient(110deg, rgba(255, 253, 244, 0) 40%, rgba(255, 253, 244, .85) 50%, rgba(255, 253, 244, 0) 60%);
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-io: cubic-bezier(.65, 0, .35, 1);
  --serif: "Playfair Display", Georgia, "Times New Roman", serif;
  --sans: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --script: "Alex Brush", "Brush Script MT", cursive;
  color-scheme: light;
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--pink);
  font-family: var(--sans);
  color: var(--cream);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

body.is-loading, body.is-envelope { overflow: hidden; }

.defs { position: absolute; width: 0; height: 0; overflow: hidden; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

.nowrap { white-space: nowrap; }

/* ---------- Gold foil text ----------
   Only for large display type: the generated foil texture clipped to the letters,
   with a darker pink edge so it holds up on pink. Small text uses solid cream. */
.foil {
  background-image: var(--foil);
  background-size: 420px auto;
  background-position: var(--fx, 0) var(--fy, 0);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes slosh { 50% { transform: translate(-6px, -1px); } }
@keyframes fadeIn { to { opacity: 1; } }

/* ---------- 2. Envelope ---------- */
.stage {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 24px 16px;
  background: var(--scene);
  transition: opacity .8s ease, visibility .8s;
}

.stage[hidden] { display: none; }
.stage.is-done { opacity: 0; visibility: hidden; pointer-events: none; }

/* The flap and card rise above the envelope when it opens, so space is reserved above
   it (the "Open invitation" button sits in that space until tapped), and the envelope
   scales down on short screens so the whole opening always stays on screen. */
.envelope-wrap {
  --env-w: min(86vw, 540px, calc((100dvh - 48px) / 1.62 * 1.42));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 22px;
  height: calc(var(--env-w) / 1.42 * 1.62);
  animation: envIn 1.1s var(--ease-out) both;
}

@keyframes envIn { from { opacity: 0; transform: translateY(40px) scale(.94); } }

.envelope {
  position: relative;
  display: block;
  flex: none;
  width: var(--env-w);
  aspect-ratio: 1.42;
  padding: 0;
  border: 0;
  background: none;
  perspective: 1400px;
  -webkit-tap-highlight-color: transparent;
  transition: transform .5s var(--ease-out);
}


.envelope > * { position: absolute; display: block; }

.env__back {
  inset: 0;
  border-radius: 0 0 6px 6px; /* square top so the flap corners meet it exactly */
  background: #D42A7E;
  box-shadow: 0 18px 40px -16px rgba(176, 16, 92, .28);
}

.env__liner { display: none; }

.env__card {
  left: 6%; right: 6%; top: 6%; bottom: 5%;
  z-index: 2;
  border-radius: 4px;
  background: var(--scene);
  box-shadow: 0 0 0 1px rgba(196, 30, 110, .25);
  transition: transform 1.1s var(--ease-io);
}

.env__card-title {
  position: absolute;
  left: 0; right: 0; top: 33.333%;
  translate: 0 -50%; /* centred on the line a third of the way down */
  font-family: var(--sans);
  font-weight: 500;
  font-size: clamp(14px, 3.4vw, 22px);
  letter-spacing: var(--track);
  text-indent: var(--track);
  text-transform: uppercase;
  line-height: 1.4;
  text-align: center;
  white-space: nowrap;
  color: var(--card-ink);
}


/* Gold glitter sprinkles in two corners of a card */
.sprinkles {
  position: absolute;
  width: 30%;
  aspect-ratio: 1;
  background: var(--glitter) 0 0 / 120px;
  -webkit-mask: var(--splat);
  mask: var(--splat);
  --splat:
    radial-gradient(circle at 10% 14%, #000 4.5%, transparent 5%),
    radial-gradient(circle at 26% 8%, #000 2.5%, transparent 3%),
    radial-gradient(circle at 6% 34%, #000 3%, transparent 3.5%),
    radial-gradient(circle at 34% 22%, #000 1.8%, transparent 2.3%),
    radial-gradient(circle at 18% 28%, #000 1.4%, transparent 1.9%),
    radial-gradient(circle at 44% 6%, #000 1.6%, transparent 2.1%),
    radial-gradient(circle at 12% 50%, #000 1.3%, transparent 1.8%);
}

.sprinkles--tl { left: 0; top: 0; }
.sprinkles--br { right: 0; bottom: 0; transform: rotate(180deg); }

/* Live glitter in two corners of the cream card, the same dots as the pink corners */
.card-confetti { position: absolute; width: min(32%, 210px); aspect-ratio: 1; pointer-events: none; }
.card-confetti--tl { left: 0; top: 0; }
.card-confetti--br { right: 0; bottom: 0; }

.env__pocket {
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  border-radius: 0 0 6px 6px; /* square top so the flap corners meet it exactly */
  overflow: hidden;
}

.env__flap {
  left: 0; right: 0; top: 0;
  height: 58%;
  z-index: 4;
  transform-origin: 50% 0;
  transform-style: preserve-3d;
  transition: transform 1s var(--ease-io);
}

.env__flap-face {
  position: absolute;
  inset: 0;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.env__flap-front {
  background: #EC3A93;
}

/* The back face is flipped on its own axis, so its triangle is mirrored to stay the
   same piece of paper: hinge along the envelope edge, point upward once open */
.env__flap-back {
  inset: -1px 0 0 0; /* reaches 1px past the hinge so no hairline shows when open */
  transform: rotateX(180deg);
  clip-path: polygon(0 100%, 100% 100%, 50% 0);
  background: #D42A7E;
}

/* The seal doubles as the loader: the champagne flute fills as the page loads */
.env__seal {
  left: 50%; top: calc(58% - 20px);
  z-index: 5;
  width: 24%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--pink);
  translate: -50% -50%;
  transition: transform .5s var(--ease-out), opacity .45s ease;
}

.env__seal > svg { position: absolute; display: block; overflow: visible; }

.seal__ring { inset: 0; width: 100%; height: 100%; }
.seal__border { fill: none; stroke: url(#mfoil); stroke-width: 3; }

.seal__glass { left: 50%; top: 50%; width: 56%; height: auto; translate: -50% -50%; }

/* The glass is simply there; only the drink moves */
.env__seal .m-liquid { transform: translateY(64px); }
.env__seal .m-wave { animation: slosh 2.4s ease-in-out infinite; }
.env__seal .m-bubbles { display: none; }

/* Appears once the page has loaded. Opening with music is the main action; the tap is
   what lets the browser play the song. A small link opens it quietly. */
.env__choice {
  display: flex;
  flex-direction: column;
  align-items: center;
  order: -1; /* above the envelope */
  gap: 12px;
  visibility: hidden;
  opacity: 0;
  transition: opacity .5s ease, visibility .5s;
}

.env__choice.is-ready { visibility: visible; opacity: 1; }
.env__choice.is-chosen { visibility: hidden; opacity: 0; }

.env__choice .btn { min-height: 50px; min-width: 210px; padding: 0 28px; font-size: 15px; }
.btn--ink { border: 1.5px solid var(--card-ink); background: var(--card-ink); color: var(--scene); }
.btn--ink:hover, .btn--ink:focus-visible { background: #6E0A3D; border-color: #6E0A3D; }

.env__quiet {
  padding: 6px 10px;
  border: 0;
  background: none;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--card-ink);
  cursor: pointer;
}

.env__quiet:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .3em; }
.env__choice button:focus-visible { outline: 2px solid var(--card-ink); outline-offset: 3px; }

/* Opening sequence (classes added by app.js) */
.envelope.is-opening .env__seal { opacity: 0; }
.envelope.is-flapped .env__flap { transform: rotateX(180deg); }
.envelope.flap-behind .env__flap { z-index: 1; }
.envelope.is-sliding .env__card { transform: translateY(-62%); }

/* Gold hearts released when the envelope opens. They sit inside the envelope,
   in front of the card and behind the front pocket, so they rise out of it. */
.env__hearts {
  left: 0; top: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}

.heart {
  position: absolute;
  opacity: 0;
  animation: heartRise var(--dur) cubic-bezier(.33, .1, .55, 1) var(--delay) forwards;
}

.heart > span { display: block; animation: heartSway var(--sway) ease-in-out infinite alternate; }

.heart svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

@keyframes heartRise {
  0% { opacity: 0; transform: translateY(0) scale(.55); }
  10% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translateY(var(--rise)) scale(1); }
}

@keyframes heartSway {
  from { transform: translateX(calc(var(--sw) * -1)) rotate(-10deg); }
  to { transform: translateX(var(--sw)) rotate(10deg); }
}

/* After the card is read, the screen fades to pink before the invitation appears */
.veil {
  position: fixed;
  inset: 0;
  z-index: 65;
  background: var(--pink);
  opacity: 0;
  pointer-events: none;
}

/* ---------- 3. Invitation ---------- */
.card {
  position: relative;
  z-index: 1;
  max-width: 980px;
  margin: 0 auto;
  padding: clamp(22px, 4.55vh, 42px) 16px clamp(56px, 10vh, 96px); /* 30% less above the headline */
  text-align: center;
  visibility: hidden;
}

.is-revealed .card { visibility: visible; }

.heading {
  position: relative;
  width: 100vw;
  margin: 0 0 clamp(21px, 4vh, 37px) calc(50% - 50vw); /* 20% less than before */
  overflow: hidden;
  font-weight: 400;
  line-height: 1;
}

/* One line, the full width of the browser less a slim margin each side */
.hl {
  display: block;
  width: calc(100vw - 2 * var(--hl-margin));
  height: auto;
  margin: 0 auto;
  overflow: visible;
  --hl-margin: clamp(10px, 2.5vw, 36px);
}

/* Narrower on bigger screens so more of the invitation fits; phones keep full width */
@media (min-width: 641px) {
  .hl { width: calc((100vw - 2 * var(--hl-margin)) * .7); }
}

.hl-draw { stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.is-revealed .hl-draw { animation: draw var(--t) cubic-bezier(.45, .05, .4, 1) var(--d) forwards; }
.hl-draw--tail { stroke-width: 34; }

.hl-sheen { transform-box: fill-box; transform: translateX(0); }
.is-revealed .hl-sheen { animation: hlSheen 8s var(--ease-io) 4.4s infinite; }

@keyframes hlSheen {
  0% { transform: translateX(0); }
  38%, 100% { transform: translateX(560%); }
}

/* Everything guests need to read sits on a cream card in deep pink: gold or light
   text can't reach a readable contrast on #FF46A2, so only the headline stays gold on pink */
.copy {
  position: relative;
  overflow: hidden; /* keeps corner glitter inside the rounded corners */
  display: grid;
  justify-items: center;
  max-width: 820px;
  margin: 0 auto;
  padding: clamp(26px, 6vw, 43px) clamp(18px, 5vw, 45px); /* plus line spacing, reads as about 45px */
  border-radius: 22px;
  background: var(--scene);
  color: var(--card-ink);
  opacity: 0;
}

.is-revealed .copy { animation: fadeIn 1s ease 2s forwards; }

/* One text style for everything except the headline and the name line */

.text {
  margin: 0 0 .7em;
  text-wrap: balance;
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--card-ink, var(--gold));
}

.name {
  margin: 0 0 .35em;
  font-family: var(--script);
  font-weight: 400;
  font-size: calc(var(--fs-name) * 1.35); /* script reads smaller than caps, so it runs larger */
  line-height: 1.15;
  text-wrap: balance;
  color: var(--card-ink);
}

/* Raised, smaller ordinal: 100th */
.name sup { font-size: .55em; line-height: 0; vertical-align: .62em; margin-left: .02em; }

.sep { display: inline-block; margin: 0 .7em; }

/* Very narrow phones: a little less side space and tracking so the intro stays on two lines */
@media (max-width: 380px) {
  .card { padding-left: 10px; padding-right: 10px; }
  .copy { padding-left: 12px; padding-right: 12px; }
  .copy .text { letter-spacing: .1em; }
}

@media (max-width: 560px) {
  .text .sep { display: none; }
  .text time { display: block; }
}

.link {
  color: inherit;
  text-decoration: none;
  overflow-wrap: anywhere;
}

.link:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .3em; }

a:focus-visible, button:focus-visible {
  outline: 2px solid var(--cream);
  outline-offset: 4px;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 32px;
  border-radius: 999px;
  font-family: var(--sans);
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1;
  letter-spacing: var(--track);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: transform .25s var(--ease-out), background-color .25s;
  -webkit-tap-highlight-color: transparent;
}

.btn--gold {
  min-width: 200px;
  border: 0;
  background: var(--gold);
  color: var(--pink-ink);
}

/* On the cream card the main button is deep pink with cream text */
.copy .btn--gold { background: var(--card-ink); color: var(--scene); }
.copy .btn--gold:hover, .copy .btn--gold:focus-visible { background: #6E0A3D; }
.copy a:focus-visible, .copy button:focus-visible { outline-color: var(--card-ink); }

.btn--gold:hover, .btn--gold:focus-visible {
  transform: translateY(-2px);
  background: #FBE6C2;
}

.btn--block { width: 100%; }

.rsvp-wrap { margin: 1em 0 2em; font-size: var(--fs-body); }

/* Secondary: smaller so the RSVP button is the obvious choice */
.alt-rsvp {
  --fs-body: clamp(12px, calc(.4vw + 10.4px), 15px);
  display: grid;
  justify-items: center;
  margin: 0 0 1.6em; /* about 12px tighter above "No presents please" */
  font-size: var(--fs-body);
}
.alt-rsvp .text { margin-bottom: .35em; }

.footer-note { margin: 0; }

/* ---------- Reveal sequence ---------- */
.reveal { opacity: 0; translate: 0 16px; }

.is-revealed .reveal {
  animation: fadeUp 1.1s var(--ease-out) forwards;
  animation-delay: calc(2.3s + var(--i, 0) * .2s);
}

@keyframes fadeUp { to { opacity: 1; translate: 0 0; } }

/* ---------- Glitter splatter ---------- */
.confetti {
  position: fixed;
  z-index: 0;
  width: min(42vw, 420px);
  height: min(30vw, 300px);
  pointer-events: none;
  visibility: hidden;
}

.is-revealed .confetti { visibility: visible; }

.confetti--tl { top: 0; left: 0; }
.confetti--br { bottom: 0; right: 0; }

/* Keep the splatter in the corners, clear of the headline, on phones */
@media (max-width: 640px) {
  .confetti { width: 50vw; height: 34vw; }
}

.dot {
  position: absolute;
  background: var(--glitter);
  background-size: 64px;
  opacity: 0;
  translate: 0 12px;
  will-change: transform;
}

.is-revealed .dot { animation: dotIn 1.4s var(--ease-out) forwards, sparkle 1.8s steps(2, jump-none) infinite; }

@keyframes dotIn { to { opacity: var(--o, 1); translate: 0 0; } }
@keyframes sparkle { to { background-position: 3px 2px; } }

/* The card sprinkles twinkle like the floating glitter */
.sprinkles { animation: sparkle 1.8s steps(2, jump-none) infinite; }
.sprinkles--br { animation-delay: .9s; }

/* ---------- Add to calendar ----------
   A quiet link on the card; the main button on the thank-you screen after a "Yes".
   Tapping it reveals Apple / Outlook (a calendar file) and Google Calendar. */
.text-btn {
  padding: 6px 10px;
  border: 0;
  background: none;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--card-ink);
  cursor: pointer;
}

.text-btn:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .3em; }
.text-btn:focus-visible { outline: 2px solid var(--card-ink); outline-offset: 3px; }

.cal { display: grid; justify-items: center; gap: 10px; }
.cal[hidden], .cal__options[hidden] { display: none; }
.cal--card { margin: -.3em 0 .2em; }
.cal--card .cal__toggle { font-size: 13px; }
.cal--thanks { margin: 0 0 10px; }

.cal__options { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }

.cal__opt {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 0 18px;
  border: 1.5px solid var(--card-ink);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--card-ink);
}

.cal__opt:hover { background: rgba(138, 11, 76, .08); }
.cal__opt:focus-visible { outline: 2px solid var(--card-ink); outline-offset: 3px; }

/* ---------- Music button ---------- */
.music-btn {
  position: fixed;
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  z-index: 70; /* above the envelope stage so it's there from the start */
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--scene);
  color: #8A0B4C;
  cursor: pointer;
  opacity: 0;
  transition: transform .25s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}

.music-btn[hidden] { display: none; }
.music-btn:not([hidden]) { animation: fadeIn .6s ease forwards; }
.music-btn:hover { transform: translateY(-2px); }
.music-btn:focus-visible { outline: 2px solid var(--scene); outline-offset: 3px; }

.music-btn svg { width: 24px; height: 24px; }
.music-btn path { fill: currentColor; }
.music-btn .wave { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.music-btn__on { display: none; }
.music-btn.is-playing .music-btn__on { display: block; }
.music-btn.is-playing .music-btn__off { display: none; }

/* ---------- Modal ---------- */
.modal {
  --fs-body: clamp(14px, calc(.6vw + 11.6px), 16px); /* page body less 2px */
  width: min(560px, calc(100vw - 24px));
  max-height: calc(100dvh - 24px);
  padding: 0;
  border: 0;
  border-radius: 22px;
  background: var(--pink);
  color: var(--cream);
  overflow: auto;
  overscroll-behavior: contain;
}

.modal::backdrop {
  background: rgba(70, 4, 38, .6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.modal[open] { animation: modalIn .5s var(--ease-out); }
.modal[open]::backdrop { animation: backdropIn .4s ease; }

@keyframes backdropIn { from { opacity: 0; } }

@keyframes modalIn { from { opacity: 0; transform: translateY(24px) scale(.97); } }

.modal__inner {
  position: relative;
  margin: 10px;
  padding: 40px 22px 28px;
  border-radius: 16px;
  border: 1.5px solid rgba(255, 241, 214, .85);
}

.modal__close {
  position: absolute;
  top: 10px; right: 10px;
  z-index: 2;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}

.modal__close svg { width: 22px; height: 22px; stroke: #f6dfb0; stroke-width: 2; stroke-linecap: round; }
.modal__close:hover { background: rgba(125, 11, 69, .15); }

.modal__title {
  margin: 0 0 28px;
  text-align: center;
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--fs-name);
  letter-spacing: .06em;
  text-indent: .06em;
  line-height: 1.1;
  color: var(--gold);
}


.field { margin: 0 0 22px; padding: 0; border: 0; min-width: 0; }

.label {
  display: block;
  margin: 0 0 10px;
  padding: 0;
  font-size: var(--fs-body);
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
}

.optional { text-transform: none; letter-spacing: .02em; font-weight: 400; }

.input {
  width: 100%;
  min-height: 50px;
  padding: 12px 14px;
  border: 1.5px solid rgba(246, 223, 176, .9);
  border-radius: 12px;
  background: #fffaf3;
  color: #3a0a22;
  font-family: var(--sans);
  font-size: 16px; /* 16px stops iOS zooming */
  transition: border-color .2s, box-shadow .2s;
}

.input::placeholder { color: #9b6b80; }
.input:focus { outline: none; border-color: #fff0c8; box-shadow: 0 0 0 3px rgba(255, 240, 200, .55); }
textarea.input { resize: vertical; min-height: 92px; line-height: 1.5; }
.input[aria-invalid="true"] { border-color: #fff; box-shadow: 0 0 0 3px rgba(125, 11, 69, .55); }

/* Yes / No use the same pill buttons as the page: outline, flat gold when chosen */
.toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.toggle__opt { position: relative; cursor: pointer; border-radius: 999px; }
.toggle__opt input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }

.toggle__opt span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 16px;
  border: 1.5px solid var(--gold);
  border-radius: 999px;
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--gold);
  background: transparent;
  transition: background-color .25s, color .25s;
}

.toggle__opt:hover span { background: rgba(255, 241, 214, .14); }
.toggle__opt input:checked + span { background: var(--gold); color: var(--pink-ink); }
.toggle__opt input:focus-visible + span { outline: 2px solid var(--gold); outline-offset: 3px; }

.guests { display: grid; gap: 10px; }

.guest { display: flex; gap: 8px; align-items: flex-start; animation: rowIn .4s var(--ease-out); }
.guest.is-leaving { animation: rowOut .25s ease forwards; }

@keyframes rowIn { from { opacity: 0; transform: translateY(-6px); } }
@keyframes rowOut { to { opacity: 0; transform: translateX(16px); } }

.guest__fields { flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; min-width: 0; }
.guest__label { min-width: 0; }

.guest__remove {
  flex: none;
  width: 48px; height: 48px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--gold);
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
  transition: background .2s, opacity .2s;
}

.guest__remove svg { width: 18px; height: 18px; stroke: #fff0c8; stroke-width: 2.2; stroke-linecap: round; }
.guest__remove:hover { background: rgba(255, 241, 214, .14); }
.guest__remove:disabled { opacity: .35; cursor: not-allowed; }

@media (max-width: 400px) {
  .guest__fields { grid-template-columns: 1fr; }
  .guest__remove { align-self: center; }
}

.add-btn {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
  gap: 6px;
  margin-top: 12px;
  min-height: 48px;
  padding: 0 12px;
  white-space: nowrap;
  border: 1.5px solid var(--gold);
  border-radius: 999px;
  background: transparent;
  color: #fff6e0;
  font-family: var(--sans);
  font-size: var(--fs-body);
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s, transform .25s var(--ease-out);
}

.add-btn span { font-size: 18px; line-height: 1; }
.add-btn:hover { background: rgba(255, 241, 214, .14); }

.error {
  margin: 8px 0 0;
  color: #fff;
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.45;
}

.error:empty { display: none; }
.error::before { content: "\2726  "; color: #fff0c8; }

.form-error {
  margin: 0 0 18px;
  padding: 14px 16px;
  border-radius: 12px;
  background: rgba(125, 11, 69, .3);
  border: 1px solid rgba(246, 223, 176, .7);
  color: #fff;
  font-size: var(--fs-body);
  line-height: 1.6;
  text-align: center;
}

.form-error a { color: #fff0c8; font-weight: 500; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }



.spinner {
  display: none;
  width: 20px; height: 20px;
  border: 2.5px solid rgba(125, 11, 69, .25);
  border-top-color: var(--pink-ink);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}

.btn.is-loading { cursor: progress; }
.btn.is-loading .spinner { display: inline-block; }
.btn.is-loading .btn-label::after { content: "\2026"; }

@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Thank you ---------- */
.thanks { position: relative; text-align: center; padding: 26px 0 8px; }

.thanks__glass { width: 64px; height: auto; margin: 0 auto 6px; display: block; overflow: visible; }

.thanks__title {
  margin: 0 0 14px;
  font-family: var(--script);
  font-weight: 400;
  font-size: clamp(54px, 15vw, 76px);
  line-height: 1.15;
  padding: 0 .15em;
  outline: none;
  animation: thanksIn 1.3s var(--ease-out) both;
}

.thanks__msg {
  margin: 0 auto 30px;
  max-width: 30ch;
  font-size: var(--fs-body);
  font-weight: 500;
  letter-spacing: var(--track);
  line-height: 1.75;
  text-transform: uppercase;
  animation: fadeUp .9s var(--ease-out) .6s both;
  opacity: 0;
  translate: 0 16px;
}

.thanks .btn { animation: fadeUp .9s var(--ease-out) .9s both; opacity: 0; translate: 0 16px; }

@keyframes thanksIn {
  from { opacity: 0; clip-path: inset(0 100% 0 0); transform: translateY(6px); }
  to { opacity: 1; clip-path: inset(0 0 0 0); transform: none; }
}

.thanks__sparkles { position: absolute; inset: 0; pointer-events: none; }

.spark {
  position: absolute;
  left: 50%; top: 42%;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--glitter) 0 0 / 32px;
  opacity: 0;
  animation: burst 1.6s var(--ease-out) forwards;
}

@keyframes burst {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.4); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1); }
}

@media (min-width: 720px) {
  .modal__inner { padding: 48px 40px 34px; }
}

/* ---------- Popup on cream ----------
   The popup copies the cream card (deep pink on #FFEBE7, readable) and adds a hot pink
   border so it stands apart from the cream card behind it. */
.modal { background: var(--scene); color: var(--card-ink); border: 4px solid var(--pink); }
.modal__inner { border: 0; }
.modal:focus { outline: none; }
.modal__close svg { stroke: var(--card-ink); }
.modal__close:hover { background: rgba(138, 11, 76, .08); }
.modal__title, .label, .thanks__msg { color: var(--card-ink); }
.modal a:focus-visible, .modal button:focus-visible { outline-color: var(--card-ink); }

.modal .toggle__opt span { border-color: var(--card-ink); color: var(--card-ink); }
.modal .toggle__opt:hover span { background: rgba(138, 11, 76, .08); }
.modal .toggle__opt input:checked + span { background: var(--card-ink); color: var(--scene); }
.modal .toggle__opt input:focus-visible + span { outline-color: var(--card-ink); }

.modal .input { background: #fff; border-color: rgba(138, 11, 76, .4); color: #3a0a22; }
.modal .input::placeholder { color: #a0607e; }
.modal .input:focus { border-color: var(--card-ink); box-shadow: 0 0 0 3px rgba(138, 11, 76, .15); }
.modal .input[aria-invalid="true"] { border-color: var(--card-ink); box-shadow: 0 0 0 3px rgba(138, 11, 76, .25); }

.modal .add-btn, .modal .guest__remove { border-color: var(--card-ink); color: var(--card-ink); }
.modal .guest__remove svg { stroke: var(--card-ink); }
.modal .add-btn:hover, .modal .guest__remove:hover { background: rgba(138, 11, 76, .08); }

.modal .error, .modal .error::before { color: var(--card-ink); }
.modal .form-error { background: rgba(138, 11, 76, .06); border-color: var(--card-ink); color: var(--card-ink); }
.modal .form-error a { color: var(--card-ink); }

.modal .btn--gold { background: var(--card-ink); color: var(--scene); }
.modal .btn--gold:hover, .modal .btn--gold:focus-visible { background: #6E0A3D; }
.modal .spinner { border-color: rgba(255, 235, 231, .35); border-top-color: var(--scene); }

/* Thank-you heading in deep pink script: gold would be too faint on cream */
.modal .thanks__title {
  background: none;
  -webkit-text-fill-color: var(--card-ink);
  color: var(--card-ink);
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .hl-sheen, .thanks__title { animation: none !important; }
  .music-btn, .copy, .reveal, .thanks__msg, .thanks .btn { opacity: 1; translate: none; animation: none !important; }
  .hl-draw { stroke-dashoffset: 0; animation: none !important; }
  .dot { opacity: var(--o, 1); translate: none; animation: none !important; }
  .sprinkles { animation: none !important; }
  .env__hearts { display: none; }
  .btn:hover { transform: none; }
}
