/* ============================================================
   Luxury Wedding Invitation Template — "Noir Cinema"
   Default palette: noir — charcoal & champagne gold
   Switchable themes: noir · royal · ivory (see :root[data-theme])
   Custom colours/fonts: config.js palette + fonts (applied by JS)
   All client content lives in config.js
   ============================================================ */

:root,
:root[data-theme="noir"] {
  --bg: #101014;             /* invitation column */
  --bg-deep: #0a0a0e;        /* page + deep bands */
  --panel: #17171e;          /* raised cards */

  --gold: #d4b678;           /* champagne gold accent */
  --gold-deep: #b3924f;
  --gold-soft: #ead9ab;

  --ink: #ece4d3;            /* ivory text */
  --muted: #a29a89;

  --line: rgba(212, 182, 120, 0.32);
  --line-faint: rgba(212, 182, 120, 0.14);
  --glow: rgba(212, 182, 120, 0.14);
  --vignette: rgba(4, 4, 8, 0.78);
  --map-filter: grayscale(1) contrast(1.06) brightness(0.94);
  --shadow-card: 0 1px 0 rgba(212, 182, 120, 0.06), 0 22px 44px -18px rgba(0, 0, 0, 0.75);
  --on-gold: #171207;        /* text sitting on gold fills */
  color-scheme: dark;
}

:root[data-theme="royal"] {
  --bg: #101728;
  --bg-deep: #0a101e;
  --panel: #161f37;

  --gold: #ccd4e2;           /* platinum silver */
  --gold-deep: #9aa7c0;
  --gold-soft: #e7edf6;

  --ink: #e9edf6;
  --muted: #8f9ab2;

  --line: rgba(204, 212, 226, 0.28);
  --line-faint: rgba(204, 212, 226, 0.12);
  --glow: rgba(204, 212, 226, 0.12);
  --vignette: rgba(3, 8, 20, 0.8);
  --map-filter: grayscale(1) contrast(1.05) brightness(0.96);
  --shadow-card: 0 1px 0 rgba(204, 212, 226, 0.06), 0 22px 44px -18px rgba(0, 0, 0, 0.7);
  --on-gold: #101722;
}

:root[data-theme="ivory"] {
  --bg: #f8f3e9;             /* warm ivory paper */
  --bg-deep: #efe7d6;
  --panel: #fdfaf2;

  --gold: #a8842e;           /* antique gold */
  --gold-deep: #8a6b1f;
  --gold-soft: #c9ab5e;

  --ink: #2b2620;
  --muted: #7a705f;

  --line: rgba(138, 107, 31, 0.35);
  --line-faint: rgba(138, 107, 31, 0.16);
  --glow: rgba(168, 132, 46, 0.12);
  --vignette: rgba(120, 96, 52, 0.2);
  --map-filter: grayscale(0.85) contrast(1.02) sepia(0.12);
  --shadow-card: 0 1px 0 rgba(138, 107, 31, 0.08), 0 18px 38px -16px rgba(74, 58, 22, 0.35);
  --on-gold: #fdf8ec;
  color-scheme: light;
}

:root {
  /* Typography roles — customisable from config.js (fonts: { … }) */
  --font-display: "Marcellus", "Cormorant Garamond", "Noto Serif Bengali", serif;
  --font-serif: "Cormorant Garamond", "Noto Serif Bengali", Georgia, serif;
  --font-script: "Pinyon Script", "Noto Serif Bengali", cursive;
  --font-sans: "Montserrat", "Noto Serif Bengali", system-ui, sans-serif;
}

* { box-sizing: border-box; }

/* Author `display` rules would otherwise defeat the hidden attribute. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  background: var(--bg-deep);
}

body {
  margin: 0;
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink);
  background:
    radial-gradient(1100px 520px at 50% -8%, var(--glow), transparent 62%),
    var(--bg-deep);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.is-locked { overflow: hidden; height: 100dvh; }

::selection { background: var(--gold); color: var(--on-gold); }

img, svg { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

/* ============ Film grain + scroll progress ============ */

.grain {
  position: fixed;
  inset: -120px;
  z-index: 96;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-jitter 0.9s steps(4) infinite;
}

@keyframes grain-jitter {
  0%   { transform: translate3d(0, 0, 0); }
  25%  { transform: translate3d(-34px, 22px, 0); }
  50%  { transform: translate3d(20px, -30px, 0); }
  75%  { transform: translate3d(-16px, -14px, 0); }
  100% { transform: translate3d(26px, 30px, 0); }
}

.progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 95;
  pointer-events: none;
}

.progress span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold), var(--gold-soft));
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}

/* ============ Phone-column layout ============ */

.invite {
  position: relative;
  max-width: 560px;
  margin: 0 auto;
  min-height: 100vh;
  background: var(--bg);
  overflow-x: clip;
  box-shadow: 0 0 0 1px var(--line-faint), 0 40px 120px -30px rgba(0, 0, 0, 0.8);
}

@media (max-width: 575.98px) {
  .invite { box-shadow: none; }
}

/* ============ Cinematic opening ============ */
/* The two veils ARE the curtain. The stage itself stays transparent, so
   when the panels part the invitation is genuinely, visibly revealed. */

.intro {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  background: transparent;
  text-align: center;
  padding: 24px;
}

.intro__veil {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  background:
    repeating-linear-gradient(90deg,
      rgba(255, 255, 255, 0.014) 0 2px,
      transparent 2px 44px,
      rgba(0, 0, 0, 0.22) 44px 46px,
      transparent 46px 90px),
    radial-gradient(90% 62% at var(--veil-lit, 100%) 0%, var(--glow), transparent 58%),
    var(--bg-deep);
  transition: transform 1.3s cubic-bezier(0.85, 0, 0.15, 1) 0.12s;
  will-change: transform;
}

.intro__veil--l {
  left: 0;
  --veil-lit: 100%;
}

.intro__veil--r {
  right: 0;
  --veil-lit: 0%;
  transition-delay: 0.19s; /* the second panel answers the first, a beat later */
}

/* Gold trim along each panel's leading edge.
   Invisible while the invitation is closed — the two edges sit at the
   screen's centre and would otherwise read as one line crossing the text.
   They fade in on open, then ride outward with the panels. */
.intro__veil::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: linear-gradient(180deg,
    transparent, var(--gold-deep) 14%, var(--gold) 32%,
    var(--gold-soft) 50%, var(--gold) 68%, var(--gold-deep) 86%, transparent);
  opacity: 0;
  transition: opacity 0.5s ease 0.25s;
}

.intro.is-opening .intro__veil::after { opacity: 0.85; }

.intro__veil--l::after { right: 0; }
.intro__veil--r::after { left: 0; }

/* The seam of light where the closed panels meet.
   Hidden while the invitation is closed — it otherwise overlaps the
   intro text and button. It ignites only when the button is pressed,
   growing from the top just as the panels begin to part. */
.intro__seam {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  background: linear-gradient(180deg,
    transparent, var(--gold) 12%, var(--gold-soft) 50%, var(--gold) 88%, transparent);
  opacity: 0;
  transform: scaleY(0);
  transform-origin: center top;
  transition: opacity 0.4s ease, transform 0.55s cubic-bezier(0.3, 0, 0.2, 1),
    box-shadow 0.4s ease;
  pointer-events: none;
}

.intro.is-opening .intro__seam {
  opacity: 1;
  transform: scaleY(1);
  box-shadow: 0 0 24px 2px var(--glow), 0 0 90px 12px var(--glow);
}

.intro.is-open .intro__veil--l { transform: translate3d(-101%, 0, 0); }
.intro.is-open .intro__veil--r { transform: translate3d(101%, 0, 0); }

/* As the panels part, the seam flares wide and dissolves into the light. */
.intro.is-open .intro__seam {
  opacity: 1;
  box-shadow: 0 0 34px 4px var(--glow), 0 0 120px 20px var(--glow);
  animation: seam-flare 1.15s cubic-bezier(0.3, 0, 0.3, 1) 0.12s forwards;
}

@keyframes seam-flare {
  0%   { opacity: 1; transform: scaleX(1); filter: blur(0); }
  38%  { opacity: 0.9; transform: scaleX(10); filter: blur(3px); }
  100% { opacity: 0; transform: scaleX(34); filter: blur(16px); }
}

.intro.is-done { display: none; }

.intro__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.55, 0, 0.55, 0.2);
}

.intro.is-opening .intro__content,
.intro.is-open .intro__content {
  opacity: 0;
  transform: translateY(-20px) scale(0.985);
  pointer-events: none;
}

.intro__content > * {
  animation: intro-in 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.intro__content > *:nth-child(1) { animation-delay: 0.15s; }
.intro__content > *:nth-child(2) { animation-delay: 0.35s; }
.intro__content > *:nth-child(3) { animation-delay: 0.75s; }
.intro__content > *:nth-child(4) { animation-delay: 0.95s; }
.intro__content > *:nth-child(5) { animation-delay: 1.15s; }
.intro__content > *:nth-child(6) { animation-delay: 1.35s; }

@keyframes intro-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

.intro__ring {
  position: relative;
  width: 148px;
  height: 148px;
  margin: 18px 0 22px;
}

.intro__ring svg { width: 100%; height: 100%; }

.intro__ring-track {
  stroke: var(--line);
  stroke-width: 1;
  opacity: 0.65;
}

.intro__ring-arc {
  stroke: var(--gold);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 465;
  stroke-dashoffset: 465;
  transform: rotate(-90deg);
  transform-origin: center;
  animation: ring-draw 2.2s cubic-bezier(0.4, 0, 0.2, 1) 0.35s forwards;
}

@keyframes ring-draw {
  to { stroke-dashoffset: 0; }
}

.intro__initials {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 34px;
  letter-spacing: 0.08em;
  color: var(--gold-soft);
}

.intro__eyebrow {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--muted);
}

.intro__names {
  margin: 14px 0 6px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(30px, 7.6vw, 44px);
  line-height: 1.2;
  letter-spacing: 0.06em;
  color: var(--ink);
}

.intro__names span { display: block; }

.intro__amp {
  font-family: var(--font-script) !important;
  font-size: 0.72em;
  color: var(--gold);
  padding: 0.08em 0;
}

.intro__line {
  margin: 2px 0 30px;
  font-family: var(--font-script);
  font-size: 22px;
  color: var(--gold-soft);
  opacity: 0.9;
}

.intro__open {
  position: relative;
  overflow: hidden;
  padding: 15px 34px;
  background: transparent;
  border: 1px solid var(--gold);
  color: var(--gold-soft);
  font-family: var(--font-sans);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  transition: color 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease, transform 0.35s ease;
}

.intro__open::after {
  content: "";
  position: absolute;
  top: 0;
  left: -80%;
  width: 55%;
  height: 100%;
  background: linear-gradient(105deg, transparent, rgba(234, 217, 171, 0.35), transparent);
  transform: skewX(-18deg);
  animation: sheen 3.2s ease-in-out 1.8s infinite;
}

.intro__open:hover {
  color: var(--on-gold);
  background: var(--gold);
  box-shadow: 0 0 34px var(--glow);
  transform: translateY(-1px);
}

@keyframes sheen {
  0%       { left: -80%; }
  55%, 100% { left: 140%; }
}

/* ============ Type helpers ============ */

.eyebrow {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--gold);
}

.eyebrow--light { color: var(--gold-soft); }
.eyebrow--gold { color: var(--gold); }

.section-title {
  margin: 12px 0 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(30px, 8.4vw, 40px);
  line-height: 1.16;
  letter-spacing: 0.03em;
  text-align: center;
  color: var(--ink);
}

.section-title em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--gold);
}

.script {
  font-family: var(--font-script);
  color: var(--gold-soft);
  line-height: 1.4;
}

.blessing {
  margin: 0;
  font-family: "Noto Serif Bengali", var(--font-serif);
  font-size: 16px;
  color: var(--gold-soft);
  opacity: 0.92;
}

/* ============ Flourish ============ */
/* The signature divider — two gold strokes parting around a floating
   diamond. Lives above the welcome eyebrow and beneath every section
   title. On reveal the strokes draw outward from the gap and the
   diamond snaps in last. Without JS it is simply printed, like ink. */
.flourish {
  width: 190px;
  max-width: 72%;
  margin: 18px auto 0;
  color: var(--gold);
}

/* The welcome lead-in sits above the eyebrow instead of below a title. */
.flourish--lead { margin: 0 auto 18px; }

/* Rises with nothing — the draw itself is the entrance. */
.flourish.reveal { transform: none; }

.flourish path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.8;
}

.flourish.reveal .fl__line {
  stroke-dasharray: 1 3;
  stroke-dashoffset: 1.5;
  transition: stroke-dashoffset 0.9s cubic-bezier(0.4, 0, 0.2, 1) 0.3s;
}

.flourish.reveal .fl__line:nth-of-type(2) { transition-delay: 0.52s; }

.flourish.reveal.is-in .fl__line { stroke-dashoffset: 0; }

.flourish.reveal .fl__gem {
  opacity: 0;
  transform: scale(0.3);
  transform-origin: center;
  transform-box: fill-box;
  transition: opacity 0.5s ease 0.88s, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 0.88s;
}

.flourish.reveal.is-in .fl__gem {
  opacity: 1;
  transform: scale(1);
}

/* ============ Hero ============ */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 104px 26px 120px;
  overflow: clip;
  background:
    radial-gradient(130% 90% at 50% -6%, var(--glow), transparent 56%),
    var(--bg);
}

.hero__vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(118% 118% at 50% 42%, transparent 52%, var(--vignette) 100%);
}

.hero__dust {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.dust {
  position: absolute;
  bottom: -3%;
  left: var(--x);
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  opacity: 0;
  background: radial-gradient(circle, var(--gold-soft) 0%, rgba(212, 182, 120, 0.25) 45%, transparent 72%);
  filter: drop-shadow(0 0 5px var(--glow));
  animation: dust-rise var(--t) linear var(--d) infinite;
}

@keyframes dust-rise {
  0%   { transform: translate3d(0, 0, 0) scale(0.7); opacity: 0; }
  8%   { opacity: var(--o); }
  60%  { opacity: var(--o); }
  100% { transform: translate3d(var(--dx), -108vh, 0) scale(1.15); opacity: 0; }
}

.hero__frame {
  position: absolute;
  inset: 14px;
  border: 1px solid var(--line-faint);
  pointer-events: none;
}

.hero__corner {
  position: absolute;
  width: 26px;
  height: 26px;
  border-color: var(--gold);
  border-style: solid;
  border-width: 0;
}

.hero__corner--tl { top: -1px; left: -1px; border-top-width: 2px; border-left-width: 2px; }
.hero__corner--tr { top: -1px; right: -1px; border-top-width: 2px; border-right-width: 2px; }
.hero__corner--bl { bottom: -1px; left: -1px; border-bottom-width: 2px; border-left-width: 2px; }
.hero__corner--br { bottom: -1px; right: -1px; border-bottom-width: 2px; border-right-width: 2px; }

/* The frame etches itself in after the date, corners snapping on last. */
body.intro-done .hero__frame {
  opacity: 0;
  animation: frame-in 1.3s ease 2.15s both;
}

@keyframes frame-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

body.intro-done .hero__corner {
  opacity: 0;
  animation: corner-in 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 2.6s both;
}

@keyframes corner-in {
  from { opacity: 0; transform: scale(0.3); }
  to   { opacity: 1; transform: scale(1); }
}

.hero__inner {
  position: relative;
  z-index: 1;
  max-width: 480px;
}

body.intro-done .hero__inner > * {
  animation: hero-in 0.95s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

body.intro-done .hero__inner > *:nth-child(1) { animation-delay: 0.1s; }
body.intro-done .hero__inner > *:nth-child(2) { animation-delay: 0.24s; }
body.intro-done .hero__inner > *:nth-child(3) { animation-delay: 0.36s; }
body.intro-done .hero__inner > *:nth-child(5) { animation-delay: 1.6s; }
body.intro-done .hero__inner > *:nth-child(6) { animation-delay: 1.85s; }
body.intro-done .hero__inner > *:nth-child(7) { animation-delay: 2s; }

/* The names animate letter-by-letter instead of as a block. */
body.intro-done .hero__inner > .hero__names { animation: none; }

body.intro-done .hero__amp {
  animation: hero-in 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) 1.15s both;
}

@keyframes hero-in {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}

.seal {
  width: 52px;
  height: 52px;
  margin: 26px auto;
  transform: rotate(45deg);
  border: 1px solid var(--gold);
  box-shadow: 0 0 0 4px var(--bg), 0 0 0 5px var(--line), 0 0 30px var(--glow);
  display: grid;
  place-items: center;
}

.seal__initials {
  transform: rotate(-45deg);
  font-family: var(--font-display);
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--gold-soft);
}

.hero__names {
  margin: 18px 0 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(34px, 9.6vw, 54px);
  line-height: 1.14;
  letter-spacing: 0.05em;
  text-wrap: balance;
}

.hero__name {
  display: block;
  background: linear-gradient(180deg, var(--gold-soft) 8%, var(--gold) 58%, var(--gold-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 22px var(--glow));
}

/* Letter-by-letter entrance (spans added by script.js) */
.ltr {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.55em);
  background: inherit;
  -webkit-background-clip: inherit;
  background-clip: inherit;
}

body.intro-done .ltr {
  animation: ltr-in 0.85s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  animation-delay: calc(0.45s + var(--i) * 0.055s);
}

.ltr--sp { width: 0.32em; }

@keyframes ltr-in {
  from { opacity: 0; transform: translateY(0.55em); filter: blur(7px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

.hero__amp {
  display: block;
  font-family: var(--font-script);
  font-size: 0.62em;
  color: var(--gold);
  margin: 0.1em 0;
  filter: none;
}

.hero__rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 26px auto 22px;
  max-width: 280px;
}

.hero__rule span {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line));
}

.hero__rule span:last-child {
  background: linear-gradient(90deg, var(--line), transparent);
}

.hero__rule i {
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
  border: 1px solid var(--gold);
  flex: none;
}

/* The gold rule draws outward from its centre diamond (after the names). */
body.intro-done .hero__rule span {
  transform: scaleX(0);
  animation: rule-draw 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
}

body.intro-done .hero__rule span:first-child {
  transform-origin: right center;
  animation-delay: 1.62s;
}

body.intro-done .hero__rule span:last-child {
  transform-origin: left center;
  animation-delay: 1.74s;
}

body.intro-done .hero__rule i {
  opacity: 0;
  transform: rotate(45deg) scale(0.3);
  animation: gem-in 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) 1.55s forwards;
}

@keyframes rule-draw {
  to { transform: scaleX(1); }
}

@keyframes gem-in {
  to { opacity: 1; transform: rotate(45deg) scale(1); }
}

.hero__date {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-soft);
}

.hero__place {
  margin: 8px 0 0;
  font-style: italic;
  font-size: 16px;
  color: var(--muted);
}

.hero__scroll {
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-family: var(--font-sans);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--muted);
  animation: cue-pulse 2.6s ease-in-out infinite;
}

.hero__scroll svg { width: 16px; height: 16px; }

.hero__scroll.is-hidden {
  animation: none;
  opacity: 0;
  transition: opacity 0.6s ease;
}

@keyframes cue-pulse {
  0%, 100% { opacity: 0.45; transform: translate(-50%, 0); }
  50%      { opacity: 1; transform: translate(-50%, 5px); }
}

/* ============ Sections shared ============ */

section, .custom__section {
  position: relative;
  padding: 78px 24px;
  text-align: center;
}

/* Hairlines that dissolve toward the edges instead of stopping hard. */
section + section,
.custom__section,
.footer {
  border-image: linear-gradient(90deg, transparent, var(--line-faint) 20%, var(--line-faint) 80%, transparent) 1;
}

.band--deep { background: var(--bg-deep); }

.countdown, .events, .venue, .footer-band { background: var(--bg-deep); }

/* ============ Welcome ============ */

.welcome__families {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  margin: 30px 0 22px;
}

.welcome__parents {
  margin: 0;
  max-width: 34ch;
  font-size: 17.5px;
  font-style: italic;
  color: var(--ink);
}

.welcome__divider {
  width: 1px;
  height: 34px;
  background: linear-gradient(180deg, transparent, var(--gold), transparent);
}

.welcome__line {
  margin: 0 auto;
  max-width: 40ch;
  font-size: 18px;
  color: var(--muted);
}

.welcome__epigraph {
  margin: 30px auto 0;
  font-size: 26px;
  max-width: 24ch;
}

/* ============ Countdown ============ */

.countdown__panel {
  max-width: 460px;
  margin: 0 auto;
  padding: 38px 18px 34px;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--shadow-card);
  position: relative;
}

.countdown__panel::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid var(--line-faint);
  pointer-events: none;
}

/* ============ Etched frames (countdown + RSVP panels) ============ */
/* While a panel waits for its reveal the printed border stands down; the
   trace then redraws it around the perimeter — outer frame first, inner
   keyline a beat later. The rects are measured in script.js, which sets
   --len to the true perimeter. */
.frame-trace {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.frame-trace--inner { inset: 7px; }

.frame-trace rect {
  fill: none;
  stroke: var(--line);
  stroke-width: 1;
}

.frame-trace--inner rect { stroke: var(--line-faint); }

.countdown__panel.reveal,
.rsvp__panel.reveal { border-color: transparent; }

.countdown__panel.reveal::before,
.rsvp__panel.reveal::before { border-color: transparent; }

.countdown__panel.reveal .frame-trace rect,
.rsvp__panel.reveal .frame-trace rect {
  stroke-dasharray: var(--len, 9999);
  stroke-dashoffset: var(--len, 9999);
}

.countdown__panel.reveal.is-in .frame-trace rect,
.rsvp__panel.reveal.is-in .frame-trace rect {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.5s cubic-bezier(0.4, 0, 0.2, 1) 0.2s;
}

.countdown__panel.reveal.is-in .frame-trace--inner rect,
.rsvp__panel.reveal.is-in .frame-trace--inner rect {
  transition-delay: 0.65s;
}

.countdown__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin: 28px 0 20px;
}

.countdown__cell { perspective: 300px; }

/* Numbers arrive one by one, blur-to-sharp, as the frame closes around them. */
.countdown__panel.reveal .countdown__cell {
  opacity: 0;
  transform: translateY(12px);
  filter: blur(3px);
  transition: opacity 0.55s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1), filter 0.7s ease;
}

.countdown__panel.reveal.is-in .countdown__cell { opacity: 1; transform: none; filter: blur(0); }

.countdown__panel.reveal.is-in .countdown__cell:nth-child(1) { transition-delay: 0.75s; }
.countdown__panel.reveal.is-in .countdown__cell:nth-child(2) { transition-delay: 0.88s; }
.countdown__panel.reveal.is-in .countdown__cell:nth-child(3) { transition-delay: 1.01s; }
.countdown__panel.reveal.is-in .countdown__cell:nth-child(4) { transition-delay: 1.14s; }

.countdown__panel.reveal .countdown__note { opacity: 0; transition: opacity 0.8s ease; }
.countdown__panel.reveal.is-in .countdown__note { opacity: 1; transition-delay: 1.45s; }

.countdown__num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(28px, 8vw, 36px);
  line-height: 1.2;
  color: var(--gold-soft);
  text-shadow: 0 0 26px var(--glow);
  transform-origin: 50% 100%;
}

.countdown__num.is-tick { animation: flip-in 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }

@keyframes flip-in {
  from { transform: rotateX(-84deg); opacity: 0.25; }
  to   { transform: rotateX(0deg); opacity: 1; }
}

.countdown__label {
  display: block;
  margin-top: 6px;
  font-family: var(--font-sans);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
}

.countdown__note {
  margin: 0;
  font-style: italic;
  font-size: 16px;
  color: var(--muted);
}

/* ============ Story ============ */

.story__timeline {
  position: relative;
  max-width: 560px;
  margin: 40px auto 0;
  padding-left: 30px;
  text-align: left;
}

.story__rail {
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 9px;
  width: 1px;
  background: linear-gradient(180deg, var(--gold), var(--gold-soft) 70%, var(--gold-deep));
  box-shadow: 0 0 12px var(--glow);
  transform: scaleY(0);
  transform-origin: top center;
  will-change: transform;
}

body.reduced .story__rail { transform: none; }

/* A bead of light rides the tip of the drawing rail, so the gold line
   reads as poured rather than printed. */
.rail-comet {
  position: absolute;
  left: 9px;
  top: 8px;
  width: 7px;
  height: 7px;
  margin-left: -3.5px;
  border-radius: 50%;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(circle, var(--gold-soft) 0%, var(--gold) 55%, transparent 78%);
  box-shadow: 0 0 10px 2px var(--glow), 0 0 26px 8px var(--glow);
  opacity: 0;
  transition: opacity 0.45s ease;
  animation: comet-pulse 1.9s ease-in-out infinite;
}

.rail-comet.is-on { opacity: 1; }

@keyframes comet-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.4); }
}

.chapter {
  position: relative;
  padding: 0 0 40px 26px;
}

.chapter:last-child { padding-bottom: 4px; }

/* A soft pool of light behind whichever chapter is being read. */
.chapter::before {
  content: "";
  position: absolute;
  inset: -14px -18px;
  background: radial-gradient(58% 72% at 50% 32%, var(--glow), transparent 74%);
  opacity: 0;
  transition: opacity 0.7s ease;
  pointer-events: none;
  z-index: -1;
}

.chapter.is-active::before { opacity: 1; }

.chapter__dot {
  position: absolute;
  top: 7px;
  left: -26px;
  width: 9px;
  height: 9px;
  transform: rotate(45deg);
  border: 1px solid var(--gold);
  background: var(--bg);
  transition: background 0.5s ease, box-shadow 0.5s ease, transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.chapter.is-in .chapter__dot {
  background: var(--gold);
  box-shadow: 0 0 14px var(--glow), 0 0 4px var(--gold);
}

.chapter.is-active .chapter__dot {
  box-shadow: 0 0 20px var(--glow), 0 0 6px var(--gold);
  transform: rotate(45deg) scale(1.3);
}

.chapter__label {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
  transition: color 0.5s ease, text-shadow 0.5s ease;
}

.chapter.is-active .chapter__label {
  color: var(--gold-soft);
  text-shadow: 0 0 16px var(--glow);
}

.chapter__title {
  margin: 8px 0 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 22px;
  letter-spacing: 0.03em;
  color: var(--ink);
}

.chapter__text {
  margin: 0;
  max-width: 52ch;
  font-size: 16.5px;
  color: var(--muted);
}

/* ============ Events ============ */

.events__list {
  display: grid;
  gap: 20px;
  max-width: 560px;
  margin: 40px auto 0;
}

.event-card {
  position: relative;
  padding: 30px 24px 26px;
  text-align: center;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), border-color 0.5s ease, box-shadow 0.5s ease;
}

.event-card::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 50%;
  transform: translateX(-50%);
  width: 64px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  transition: width 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}

@media (hover: hover) {
  .event-card:hover {
    transform: translateY(-5px);
    border-color: var(--gold);
    box-shadow: var(--shadow-card), 0 0 34px var(--glow);
  }
  .event-card:hover::before { width: 132px; }
}

.event-card:focus-within {
  border-color: var(--gold);
  box-shadow: var(--shadow-card), 0 0 26px var(--glow);
}

.event-card__tag {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold);
}

.event-card__name {
  margin: 10px 0 4px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 25px;
  letter-spacing: 0.04em;
  color: var(--ink);
}

.event-card__tagline {
  margin: 0;
  font-style: italic;
  font-size: 16px;
  color: var(--muted);
}

.event-card__divider {
  width: 42px;
  height: 1px;
  margin: 18px auto;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}

.event-card__rows { margin: 0; }

.event-card__rows .row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 12px;
  padding: 7px 0;
}

.event-card__rows dt {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.event-card__rows dt svg {
  width: 14px;
  height: 14px;
  color: var(--gold);
  flex: none;
}

.row__dot {
  width: 5px;
  height: 5px;
  transform: rotate(45deg);
  border: 1px solid var(--gold);
  display: inline-block;
}

.event-card__rows dd {
  margin: 0;
  font-size: 16.5px;
  color: var(--ink);
}

/* Icons engrave themselves, row by row, as the card settles. Paths carry
   pathLength="1" so a dasharray of 1 is always the full stroke. */
.event-card.reveal .ico { opacity: 0; }
.event-card.reveal .ico path { stroke-dasharray: 1 3; stroke-dashoffset: 1.5; }

.event-card.reveal.is-in .ico { opacity: 1; transition: opacity 0.3s ease var(--ico-d, 0.55s); }
.event-card.reveal.is-in .ico path {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.65s ease var(--ico-d, 0.55s);
}
.event-card.reveal.is-in .ico path:nth-of-type(2) { transition-delay: calc(var(--ico-d, 0.55s) + 0.12s); }
.event-card.reveal.is-in .ico path:nth-of-type(3) { transition-delay: calc(var(--ico-d, 0.55s) + 0.24s); }
.event-card.reveal.is-in .ico path:nth-of-type(4) { transition-delay: calc(var(--ico-d, 0.55s) + 0.36s); }

.event-card.reveal .row:nth-child(1) { --ico-d: 0.55s; }
.event-card.reveal .row:nth-child(2) { --ico-d: 0.67s; }
.event-card.reveal .row:nth-child(3) { --ico-d: 0.79s; }
.event-card.reveal .row:nth-child(4) { --ico-d: 0.91s; }

.event-card__actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}

.link-btn {
  display: inline-block;
  padding: 10px 16px;
  border: 1px solid var(--line);
  color: var(--gold-soft);
  background: transparent;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}

.link-btn:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--on-gold);
  box-shadow: 0 0 26px var(--glow);
  transform: translateY(-1px);
}

.link-btn__arrow {
  display: inline-block;
  transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.link-btn:hover .link-btn__arrow,
.link-btn:focus-visible .link-btn__arrow { transform: translate(2px, -2px); }

.link-btn--calendar { border-style: dashed; }

/* ============ Gallery ============ */

.gallery__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-flow: dense;
  gap: 10px;
  max-width: 560px;
  margin: 40px auto 0;
  counter-reset: plate;
}

.g-photo {
  position: relative;
  padding: 0;
  border: 1px solid var(--line-faint);
  background: var(--panel);
  overflow: hidden;
  aspect-ratio: 1 / 1;
  cursor: zoom-in;
  counter-increment: plate;
}

.g-photo--wide { grid-column: span 2; aspect-ratio: 2 / 1; }
.g-photo--tall { grid-row: span 2; aspect-ratio: 1 / 2; }

.g-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.03);
  transition: transform 0.9s cubic-bezier(0.2, 0.7, 0.2, 1), filter 0.7s ease;
}

/* Presentation mat: an inner keyline and soft vignette present the
   artwork deliberately — like a gallery plate — until the couple's
   photographs are dropped in. */
.g-photo::before {
  content: "";
  position: absolute;
  inset: 7px;
  z-index: 2;
  border: 1px solid var(--line-faint);
  box-shadow: inset 0 0 36px rgba(4, 4, 8, 0.45);
  transition: border-color 0.5s ease, box-shadow 0.5s ease;
  pointer-events: none;
}

/* Roman-numeral plate number, top right. */
.g-photo::after {
  content: counter(plate, upper-roman);
  position: absolute;
  top: 13px;
  right: 14px;
  z-index: 2;
  font-family: var(--font-sans);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.2em;
  color: var(--gold-soft);
  opacity: 0.62;
  transition: opacity 0.4s ease;
  pointer-events: none;
}

@media (hover: hover) {
  .g-photo img { filter: saturate(0.55) contrast(1.04); }
  .g-photo:hover img,
  .g-photo:focus-visible img { filter: saturate(1); transform: scale(1.09); }
  .g-photo:hover::before,
  .g-photo:focus-visible::before {
    border-color: var(--line);
    box-shadow: inset 0 0 24px rgba(4, 4, 8, 0.3);
  }
  .g-photo:hover::after,
  .g-photo:focus-visible::after { opacity: 1; }
}

.g-photo__cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  padding: 26px 12px 10px;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-soft);
  background: linear-gradient(180deg, transparent, rgba(6, 6, 10, 0.82));
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.45s ease, transform 0.45s ease;
  pointer-events: none;
}

.g-photo:hover .g-photo__cap,
.g-photo:focus-visible .g-photo__cap { opacity: 1; transform: none; }

.gallery__hint {
  margin: 22px 0 0;
  font-style: italic;
  font-size: 15px;
  color: var(--muted);
}

/* ============ Custom sections ============ */

.custom__section {
  border-top: 1px solid var(--line-faint);
}

.custom__section--quote {
  background: var(--bg-deep);
  padding-top: 84px;
  padding-bottom: 84px;
}

.custom__quote-mark {
  font-family: var(--font-display);
  font-size: 52px;
  line-height: 1;
  color: var(--gold);
  opacity: 0.85;
  display: block;
  margin-bottom: 6px;
}

.custom__quote {
  margin: 0 auto;
  max-width: 36ch;
  font-size: 21px;
  font-style: italic;
  line-height: 1.75;
  color: var(--ink);
}

.custom__quote-source {
  margin: 22px auto 0;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}

.custom__note {
  margin: 18px auto 0;
  max-width: 44ch;
  font-style: italic;
  color: var(--muted);
}

.custom__body {
  margin: 26px auto 0;
  max-width: 44ch;
  font-size: 17.5px;
  color: var(--muted);
}

.c-cards {
  display: grid;
  gap: 16px;
  max-width: 560px;
  margin: 34px auto 0;
}

.c-card {
  padding: 26px 22px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-card);
}

.c-card__kicker {
  margin: 0 0 8px;
  font-family: var(--font-sans);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
}

.c-card__title {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 20px;
  letter-spacing: 0.03em;
  color: var(--ink);
}

.c-card__text {
  margin: 0;
  font-size: 16px;
  color: var(--muted);
}

.c-card__swatches {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 16px;
}

.c-card__swatches i {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid var(--line);
  box-shadow: inset 0 0 0 2px var(--panel);
}

.faq {
  max-width: 620px;
  margin: 34px auto 0;
  text-align: left;
}

.faq__item {
  border: 1px solid var(--line);
  background: var(--panel);
  margin-bottom: 10px;
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
  padding: 16px 18px;
  background: none;
  border: 0;
  text-align: left;
  font-family: var(--font-serif);
  font-size: 17.5px;
  font-weight: 600;
  color: var(--ink);
}

.faq__q-icon {
  position: relative;
  width: 12px;
  height: 12px;
  flex: none;
}

.faq__q-icon::before,
.faq__q-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--gold);
  transition: transform 0.4s ease;
}

.faq__q-icon::before { width: 12px; height: 1px; transform: translate(-50%, -50%); }
.faq__q-icon::after  { width: 1px; height: 12px; transform: translate(-50%, -50%); }

.faq__item.is-open .faq__q-icon::after { transform: translate(-50%, -50%) rotate(90deg) scaleY(0); }

.faq__a {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.faq__a-inner {
  padding: 0 18px 18px;
  color: var(--muted);
  border-top: 1px solid var(--line-faint);
  padding-top: 14px;
  margin: 0 0 0 0;
}

/* ============ Venue ============ */

.venue__split {
  display: grid;
  gap: 34px;
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
}

.venue__name {
  margin: 26px 0 6px;
  font-family: var(--font-display);
  font-size: 20px;
  letter-spacing: 0.03em;
  color: var(--gold-soft);
}

.venue__address {
  margin: 0 0 24px;
  font-style: italic;
  color: var(--muted);
}

.venue__frame {
  position: relative;
  border: 1px solid var(--line);
  padding: 6px;
  background: var(--panel);
  box-shadow: var(--shadow-card);
}

.venue__frame iframe {
  display: block;
  width: 100%;
  height: 300px;
  border: 0;
  filter: var(--map-filter);
}

/* ============ RSVP ============ */

.rsvp__panel {
  max-width: 560px;
  margin: 0 auto;
  padding: 40px 24px 36px;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--shadow-card);
  position: relative;
}

.rsvp__panel::before {
  content: "";
  position: absolute;
  inset: 7px;
  border: 1px solid var(--line-faint);
  pointer-events: none;
}

.rsvp__note {
  margin: 18px auto 30px;
  max-width: 40ch;
  font-style: italic;
  color: var(--muted);
}

.rsvp__form { text-align: left; }

/* Form fields cascade in once the panel's frame has been traced. */
.rsvp__panel.reveal .rsvp__form > * {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.55s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.rsvp__panel.reveal.is-in .rsvp__form > * { opacity: 1; transform: none; }

.rsvp__panel.reveal.is-in .rsvp__form > *:nth-child(1) { transition-delay: 0.7s; }
.rsvp__panel.reveal.is-in .rsvp__form > *:nth-child(2) { transition-delay: 0.8s; }
.rsvp__panel.reveal.is-in .rsvp__form > *:nth-child(3) { transition-delay: 0.9s; }
.rsvp__panel.reveal.is-in .rsvp__form > *:nth-child(4) { transition-delay: 1s; }
.rsvp__panel.reveal.is-in .rsvp__form > *:nth-child(5) { transition-delay: 1.1s; }
.rsvp__panel.reveal.is-in .rsvp__form > *:nth-child(6) { transition-delay: 1.2s; }

.field { margin-bottom: 26px; }

.field__label {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--gold);
}

.field__optional { color: var(--muted); letter-spacing: 0.12em; text-transform: none; }

.field__input {
  width: 100%;
  padding: 12px 14px;
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: 17px;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.field__input:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold), 0 0 26px var(--glow);
}

.field__input--area { resize: vertical; min-height: 84px; }

.field__input::placeholder { color: var(--muted); opacity: 0.6; font-style: italic; }

select.field__input {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23a8842e' stroke-width='1.5'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 12px;
}

.choice { display: flex; flex-wrap: wrap; gap: 10px; }

.choice__opt {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 10px 16px;
  border: 1px solid var(--line);
  cursor: pointer;
  font-size: 15.5px;
  color: var(--ink);
  transition: border-color 0.3s ease, background 0.3s ease, box-shadow 0.3s ease;
}

.choice__opt:hover { border-color: var(--gold); }

.choice__opt input {
  accent-color: var(--gold);
  width: 15px;
  height: 15px;
  margin: 0;
}

.choice__opt:has(input:checked) {
  border-color: var(--gold);
  background: var(--glow);
  box-shadow: 0 0 20px var(--glow);
  animation: pill-pop 0.45s cubic-bezier(0.2, 0.7, 0.2, 1);
}

@keyframes pill-pop {
  0%   { transform: scale(0.96); }
  55%  { transform: scale(1.025); }
  100% { transform: scale(1); }
}

.rsvp__submit {
  position: relative;
  overflow: hidden;
  width: 100%;
  margin-top: 6px;
  padding: 16px 20px;
  border: 0;
  background: linear-gradient(120deg, var(--gold-deep), var(--gold) 45%, var(--gold-deep));
  color: var(--on-gold);
  font-family: var(--font-sans);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  box-shadow: 0 14px 34px -12px var(--glow);
  transition: filter 0.3s ease, transform 0.2s ease;
}

.rsvp__submit:hover { filter: brightness(1.08); }
.rsvp__submit:active { transform: translateY(1px); }
.rsvp__submit:disabled { opacity: 0.6; cursor: wait; }

.rsvp__submit-label { transition: opacity 0.25s ease; }

/* While the RSVP posts, the button becomes a sealing wax spinner. */
.rsvp__submit.is-sending .rsvp__submit-label { opacity: 0; }

.rsvp__submit.is-sending::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50%;
  border: 2px solid rgba(23, 18, 7, 0.28);
  border-top-color: var(--on-gold);
  animation: spin 0.8s linear infinite;
}

.rsvp__submit::after {
  content: "";
  position: absolute;
  top: 0;
  left: -80%;
  width: 50%;
  height: 100%;
  background: linear-gradient(105deg, transparent, rgba(255, 250, 235, 0.5), transparent);
  transform: skewX(-18deg);
  animation: sheen 3.4s ease-in-out infinite;
}

.rsvp__done {
  padding: 10px 0 4px;
  text-align: center;
  animation: done-in 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

@keyframes done-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* The acceptance seal draws itself — circle first, then the check. */
.rsvp__done svg circle {
  stroke-dasharray: 170;
  stroke-dashoffset: 170;
  animation: draw-stroke 0.8s cubic-bezier(0.4, 0, 0.2, 1) 0.25s forwards;
}

.rsvp__done svg path {
  stroke-dasharray: 42;
  stroke-dashoffset: 42;
  animation: draw-stroke 0.5s ease 0.85s forwards;
}

@keyframes draw-stroke {
  to { stroke-dashoffset: 0; }
}

.rsvp__done svg {
  width: 62px;
  height: 62px;
  margin: 0 auto 16px;
  color: var(--gold);
  filter: drop-shadow(0 0 14px var(--glow));
}

.rsvp__done-note {
  margin: 0 auto;
  max-width: 36ch;
  font-size: 18px;
  font-style: italic;
  color: var(--ink);
}

/* ============ Footer ============ */

.footer {
  position: relative;
  padding: 84px 24px 44px;
  text-align: center;
  background: var(--bg-deep);
  border-top: 1px solid var(--line-faint);
  overflow: clip;
}

.footer__glow {
  position: absolute;
  inset: auto 0 0;
  height: 70%;
  pointer-events: none;
  background: radial-gradient(70% 90% at 50% 108%, var(--glow), transparent 70%);
}

.footer__inner { position: relative; }

/* When the closing section scrolls into view, the monogram presses in
   like a wax seal. */
.footer__inner.is-in .footer__monogram {
  animation: seal-stamp 0.75s cubic-bezier(0.2, 0.7, 0.2, 1) 0.25s both;
}

@keyframes seal-stamp {
  0%   { opacity: 0; transform: rotate(45deg) scale(1.5); }
  62%  { opacity: 1; transform: rotate(45deg) scale(0.94); }
  100% { opacity: 1; transform: rotate(45deg) scale(1); }
}

.footer__monogram {
  width: 64px;
  height: 64px;
  margin: 0 auto 26px;
  transform: rotate(45deg);
  border: 1px solid var(--gold);
  box-shadow: 0 0 0 5px var(--bg-deep), 0 0 0 6px var(--line);
  display: grid;
  place-items: center;
}

.footer__monogram .seal__initials {
  font-size: 17px;
}

.footer__closing {
  margin: 0;
  font-family: var(--font-script);
  font-size: 27px;
  color: var(--gold-soft);
}

.footer__names {
  margin: 14px 0 4px;
  font-family: var(--font-display);
  font-size: 26px;
  letter-spacing: 0.08em;
  color: var(--ink);
}

.footer__date {
  margin: 0 0 30px;
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--muted);
}

.share-btn {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 13px 26px;
  background: transparent;
  border: 1px solid var(--gold);
  color: var(--gold-soft);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  transition: background 0.3s ease, color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}

.share-btn svg { width: 16px; height: 16px; }

.share-btn:hover {
  background: var(--gold);
  color: var(--on-gold);
  box-shadow: 0 0 30px var(--glow);
  transform: translateY(-1px);
}

.footer__hashtag {
  margin: 28px 0 0;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--gold);
}

.footer__credit {
  margin: 14px 0 0;
  font-family: var(--font-sans);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--muted);
  opacity: 0.85;
}

/* Studio social links — circular gold outline icons, echoing the seal. */
.footer__socials {
  display: flex;
  justify-content: center;
  gap: 14px;
  margin: 30px 0 0;
}

.footer__socials a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--gold);
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease,
    box-shadow 0.3s ease;
}

.footer__socials a:hover,
.footer__socials a:focus-visible {
  border-color: var(--gold);
  color: var(--on-gold);
  background: var(--gold);
  box-shadow: 0 0 22px -4px var(--glow);
}

.footer__socials svg {
  width: 19px;
  height: 19px;
}

/* ============ Floating controls ============ */

.music-btn {
  position: fixed;
  left: 18px;
  bottom: 64px; /* clears the hero frame's corner brackets */
  z-index: 60;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  background: var(--bg-deep);
  color: var(--gold-soft);
  box-shadow: 0 0 26px var(--glow);
  transition: transform 0.25s ease, opacity 0.4s ease;
}

.music-btn:hover { transform: scale(1.07); }

.music-btn__disc { width: 22px; height: 22px; position: absolute; }

.music-btn.is-playing .music-btn__disc { animation: spin 7s linear infinite; }

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

.music-btn__bars {
  position: absolute;
  bottom: 7px;
  display: none;
  gap: 2.5px;
  align-items: flex-end;
  height: 8px;
}

.music-btn.is-playing .music-btn__bars { display: inline-flex; }

.music-btn__bars i {
  width: 2.5px;
  height: 3px;
  background: var(--gold);
  animation: bar 0.9s ease-in-out infinite;
}

.music-btn__bars i:nth-child(2) { animation-delay: 0.22s; }
.music-btn__bars i:nth-child(3) { animation-delay: 0.44s; }

@keyframes bar {
  0%, 100% { height: 3px; }
  50%      { height: 8px; }
}

.share-fab {
  position: fixed;
  right: 18px;
  bottom: 64px; /* clears the hero frame's corner brackets */
  z-index: 60;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 18px;
  border-radius: 999px;
  border: 1px solid var(--gold);
  background: var(--bg-deep);
  color: var(--gold-soft);
  font-family: var(--font-sans);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  box-shadow: 0 0 26px var(--glow);
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.share-fab svg { width: 15px; height: 15px; }

.share-fab.is-visible { opacity: 1; transform: none; pointer-events: auto; }

.toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: 100;
  padding: 12px 22px;
  border: 1px solid var(--gold);
  background: var(--bg-deep);
  color: var(--gold-soft);
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.08em;
  box-shadow: 0 0 34px var(--glow);
  transform: translate(-50%, 90px);
  opacity: 0;
  transition: transform 0.45s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.45s ease;
  pointer-events: none;
}

.toast.is-visible { transform: translate(-50%, 0); opacity: 1; }

/* ============ Lightbox ============ */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 98;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(5, 5, 9, 0.93);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.lightbox.is-open { opacity: 1; }

.lightbox__stage {
  margin: 0;
  max-width: min(92vw, 1000px);
  text-align: center;
}

.lightbox__img {
  max-width: 100%;
  max-height: 78vh;
  margin: 0 auto;
  border: 1px solid var(--line);
  box-shadow: 0 40px 110px -30px rgba(0, 0, 0, 0.9);
}

.lightbox.is-open .lightbox__img { animation: lb-in 0.55s cubic-bezier(0.2, 0.7, 0.2, 1); }

@keyframes lb-in {
  from { opacity: 0; transform: scale(0.965); }
  to   { opacity: 1; transform: scale(1); }
}

.lightbox__caption {
  display: flex;
  justify-content: center;
  gap: 18px;
  margin-top: 16px;
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-soft);
}

#lbCount { color: var(--muted); }

.lightbox__close,
.lightbox__nav {
  position: absolute;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--gold);
  background: rgba(8, 8, 12, 0.6);
  color: var(--gold-soft);
  transition: background 0.3s ease, color 0.3s ease;
}

.lightbox__close svg,
.lightbox__nav svg { width: 18px; height: 18px; }

.lightbox__close:hover,
.lightbox__nav:hover { background: var(--gold); color: var(--on-gold); }

.lightbox__close { top: 20px; right: 20px; }

.lightbox__nav--prev { left: 14px; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 14px; top: 50%; transform: translateY(-50%); }

/* ============ Reveal-on-scroll ============ */

.reveal {
  opacity: 0;
  transform: translateY(26px);
  filter: blur(5px);
  transition: opacity 0.85s cubic-bezier(0.2, 0.7, 0.2, 1), transform 0.85s cubic-bezier(0.2, 0.7, 0.2, 1), filter 0.95s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.reveal.is-in { opacity: 1; transform: none; filter: blur(0); }

/* Variation on the shared entrance: small cards rise a little less,
   gallery plates settle with a faint scale, and — on desktop — story
   chapters drift in from their own side of the rail. */
.c-card.reveal,
.faq__item.reveal { transform: translateY(16px); }

.g-photo.reveal { transform: translateY(14px) scale(0.985); }

@media (min-width: 960px) {
  .chapter.reveal:nth-child(odd) { transform: translate(-16px, 22px); }
  .chapter.reveal:nth-child(even) { transform: translate(16px, 22px); }
}

body.reduced .progress { display: none; }

/* ============ Reduced motion ============ */

/* ============ Reduced motion (opt-in) ============
   Motion plays for everyone by default. When INVITE_CONFIG.motion is
   "honor", script.js tags <html class="motion-reduced"> for guests whose
   device asks for reduced motion — these rules give them a still,
   instant version with nothing left hidden or half-drawn. */

html.motion-reduced *,
html.motion-reduced *::before,
html.motion-reduced *::after {
  animation-duration: 0.01ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.01ms !important;
}
html.motion-reduced { scroll-behavior: auto; }
html.motion-reduced .dust { display: none; }
html.motion-reduced .ltr { opacity: 1; transform: none; filter: none; }
html.motion-reduced body.intro-done .ltr { animation: none; }
html.motion-reduced .reveal { opacity: 1; transform: none; filter: none; }
html.motion-reduced .rail-comet { display: none; }

html.motion-reduced body.intro-done .hero__inner > *,
html.motion-reduced body.intro-done .hero__amp { animation: none !important; opacity: 1; transform: none; }
html.motion-reduced body.intro-done .hero__frame,
html.motion-reduced body.intro-done .hero__corner { animation: none !important; opacity: 1; }
html.motion-reduced body.intro-done .hero__rule span { animation: none !important; transform: none; }
html.motion-reduced body.intro-done .hero__rule i { animation: none !important; opacity: 1; transform: rotate(45deg); }
html.motion-reduced .hero__scroll { animation: none !important; opacity: 0.85; }
html.motion-reduced .rsvp__done { animation: none !important; }
html.motion-reduced .rsvp__done svg circle,
html.motion-reduced .rsvp__done svg path { animation: none !important; stroke-dashoffset: 0; }
html.motion-reduced .footer__inner.is-in .footer__monogram { animation: none !important; opacity: 1; transform: rotate(45deg); }
html.motion-reduced .chapter::before { transition: none !important; }

/* ============ Desktop ============ */

@media (min-width: 960px) {
  .invite { max-width: 1160px; }

  section, .custom__section { padding: 104px 48px; }

  /* — Hero: full cinema screen — */
  .hero { padding: 130px 60px 150px; }
  .hero__frame { inset: 24px; }
  .hero__corner { width: 34px; height: 34px; }
  .hero__inner { max-width: 760px; }
  .hero__names { font-size: clamp(54px, 6.4vw, 84px); }
  .seal { width: 62px; height: 62px; margin: 34px auto; }
  .seal__initials { font-size: 18px; }
  .hero__rule { max-width: 380px; margin: 34px auto 26px; }
  .hero__date { font-size: 14px; }

  /* — Welcome: families side by side — */
  .welcome__families {
    flex-direction: row;
    justify-content: center;
    align-items: center;
    gap: 44px;
  }
  .welcome__divider { width: 46px; height: 1px; background: linear-gradient(90deg, transparent, var(--gold), transparent); }
  .welcome__epigraph { font-size: 30px; }

  /* — Countdown — */
  .countdown__panel { max-width: 620px; padding: 48px 30px 42px; }
  .countdown__num { font-size: 46px; }

  /* — Story: centre rail, alternating chapters — */
  .story__timeline { max-width: 900px; padding-left: 0; }
  .story__rail { left: 50%; }
  .rail-comet { left: 50%; }
  .chapter {
    width: 50%;
    padding: 0 54px 56px;
  }
  .chapter:nth-child(odd) { text-align: right; }
  .chapter:nth-child(odd) .chapter__text { margin-left: auto; }
  .chapter:nth-child(even) {
    margin-left: 50%;
    text-align: left;
  }
  .chapter__dot { left: auto; }
  .chapter:nth-child(odd) .chapter__dot { right: -5px; }
  .chapter:nth-child(even) .chapter__dot { left: -4px; }
  .chapter__title { font-size: 25px; }

  /* — Events: three gilded cards — */
  .events__list {
    max-width: none;
    grid-template-columns: repeat(3, 1fr);
    gap: 22px;
  }

  /* — Gallery: mosaic — */
  .gallery__grid {
    max-width: none;
    grid-template-columns: repeat(5, 1fr);
    gap: 14px;
  }

  /* — Custom sections — */
  .custom__quote { max-width: 52ch; font-size: 24px; }
  .custom__note, .custom__body { max-width: 60ch; }
  .c-cards {
    max-width: none;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
  }
  .faq { max-width: 820px; }

  /* — Venue: two columns — */
  .venue__split {
    max-width: none;
    grid-template-columns: 1fr 1.15fr;
    align-items: center;
    text-align: left;
    gap: 54px;
  }
  .venue__name { margin-top: 0; }
  .venue__frame iframe { height: 380px; }

  /* — RSVP — */
  .rsvp__panel { max-width: 700px; padding: 52px 46px 46px; }

  /* — Footer — */
  .footer { padding: 110px 48px 54px; }
  .footer__names { font-size: 32px; }
  .footer__closing { font-size: 32px; }

  .intro__names { font-size: 56px; }
  .intro__ring { width: 176px; height: 176px; }
  .intro__initials { font-size: 40px; }
  .intro__line { font-size: 27px; }
}
