/* ==========================================================================
   Lao-inspired luxury wedding invitation · style.css
   --------------------------------------------------------------------------
   Contents
     1. Design tokens (colours, fonts, z-index, animation timing)
     2. Base & paper texture
     3. Stage (scenes 1–3) — shared layer rules
     4. LAYER POSITIONS — DESKTOP / TABLET LANDSCAPE
     5. Envelope + 3D flap
     6. Wax seal, ribbon, branches, temple, ornaments
     7. Closed-state title
     8. Invitation card + staggered text
     9. OPENING SEQUENCE (state machine driven by script.js)
    10. Ambient motion (float, shimmer, reveal, parallax)
    11. LAYER POSITIONS — MOBILE / PORTRAIT
    12. Scene 4 · information sections
    13. Reduced motion & no-JS fallbacks
   ========================================================================== */

/* 1. DESIGN TOKENS ======================================================== */
:root {
  /* Palette */
  --burgundy-950: #2a060c;
  --burgundy-900: #3d0b14;
  --burgundy-800: #551120;
  --burgundy-700: #6b1827;
  --burgundy-600: #832233;
  --cream-50: #fcf7ee;
  --cream-100: #f6ecdc;
  --cream-200: #eedfc6;
  --champagne: #e7d0b0;
  --blush: #e9cdc4;
  --gold-200: #f1dcaa;
  --gold-300: #e2c07c;
  --gold-400: #cfa35a;
  --gold-500: #b5863c;
  --gold-600: #8f6527;
  --ink: #4b2a1e;
  --ink-soft: #7b5845;

  --gold-foil: linear-gradient(115deg, #8f6527 0%, #d9b46a 28%, #f6e2ae 45%, #c99a4c 62%, #8f6527 100%);

  /* Fonts (system fallbacks keep the look if Google Fonts is unavailable) */
  --font-serif: "Cormorant Garamond", "Cormorant", Garamond, "Hoefler Text", "Times New Roman", serif;
  --font-lao: "Noto Serif Lao", "Phetsarath OT", "Saysettha OT", "Lao Sangam MN", "Noto Sans Lao", "Lao UI", serif;

  /* Z-INDEX SYSTEM — one place to reorder the stack */
  --z-paper: 0;
  --z-print: 2;        /* faint printed medallions */
  --z-temple: 5;
  --z-title: 15;       /* closed-state title */
  --z-envelope: 20;    /* body + pocket + flap live inside this layer */
  --z-ribbon: 30;
  --z-branch: 40;
  --z-seal: 50;
  --z-card: 60;        /* invitation card is above every decoration once open */
  --z-ui: 80;          /* scroll cue, replay button */

  /* ANIMATION TIMING — tune the whole opening here.
     "delay" = when the step starts after the click; durations overlap on purpose. */
  --ease-silk: cubic-bezier(.22, .61, .36, 1);
  --ease-lift: cubic-bezier(.16, 1, .3, 1);
  --ease-flap: cubic-bezier(.62, 0, .24, 1);

  --t-title: 600ms;      --d-title: 0ms;
  --t-seal: 900ms;       --d-seal: 0ms;      /* 1. seal lifts, shrinks, fades */
  --t-flap: 1500ms;      --d-flap: 450ms;    /* 2. flap rotates open in 3D */
  --t-ribbon: 1700ms;    --d-ribbon: 700ms;  /* 3. ribbon drifts aside */
  --t-card: 1600ms;      --d-card: 1350ms;   /* 4. card rises out of the envelope */
  --t-ornament: 900ms;   --d-ornament: 2350ms; /* 5. gold ornaments fade in */
  --d-text: 2500ms;      --t-text: 900ms;    /* 6. text, staggered by --stagger */
  --stagger: 95ms;
  --t-total: 4300ms;     /* read by script.js: when the state becomes "open" */
}

/* 2. BASE ================================================================= */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-serif);
  color: var(--ink);
  background-color: var(--cream-100);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; }
[hidden] { display: none !important; }
button, input, select, textarea { font: inherit; color: inherit; }
[lang="lo"] { font-family: var(--font-lao); letter-spacing: 0; }
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; left: 1rem; top: -4rem; z-index: 100;
  background: var(--burgundy-800); color: var(--cream-50);
  padding: .6rem 1rem; border-radius: 4px; text-decoration: none;
}
.skip-link:focus { top: 1rem; }
:focus-visible { outline: 2px solid var(--gold-500); outline-offset: 3px; }

/* Paper texture: fine grain + large soft mottling, generated as inline SVG (no extra files). */
.paper,
.stage,
.section--cream,
.section--champagne,
.invitation-card__paper {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .42 0 0 0 0 .29 0 0 0 0 .18 0 0 0 .085 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.008 .02' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .6 0 0 0 0 .45 0 0 0 0 .3 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23m)'/%3E%3C/svg%3E");
}

/* 3. STAGE ================================================================ */
/*
  Every decorative layer is positioned in "u" units.
  Desktop: 1u ≈ 1% of the viewport height, capped by width so very narrow
  landscape windows shrink the composition instead of cropping it.
  Change a layer's numbers below (e.g. `left: calc(36 * var(--u))`) to move it.
*/
.stage {
  --u: 1vh;
  --u: min(1svh, .68vw);
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 540px;
  overflow: hidden;
  isolation: isolate;
  background-color: #efdaca;              /* sampled from the reference paper */
  /* Soft champagne lighting over the paper */
  background-image:
    radial-gradient(ellipse 55% 60% at 62% 38%, rgba(250, 236, 222, .55), transparent 70%),
    radial-gradient(ellipse 70% 60% at 100% 100%, rgba(205, 165, 120, .28), transparent 70%),
    radial-gradient(ellipse 40% 50% at 40% 0%, rgba(233, 205, 196, .35), transparent 70%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .42 0 0 0 0 .29 0 0 0 0 .18 0 0 0 .085 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.008 .02' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .6 0 0 0 0 .45 0 0 0 0 .3 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23m)'/%3E%3C/svg%3E");

  /* Envelope geometry (shared by envelope, seal, ribbon and card maths).
     The envelope image is 931 × 1403 → width = height × 0.6636. */
  --env-h: calc(112 * var(--u));
  --env-w: calc(var(--env-h) * .6636);
  --env-x: calc(-26 * var(--u));                 /* negative = bleeds off the left edge */
  --env-y: calc(50% - var(--env-h) / 2);
  --env-right: calc(var(--env-x) + var(--env-w)); /* visible right edge of the burgundy */

  /* Where the flap tip (and therefore the seal) sits, as a fraction of the envelope */
  --tip-x: .757;
  --tip-y: .49;
  --seal-cx: calc(var(--env-x) + var(--env-w) * var(--tip-x));
  --seal-cy: calc(var(--env-y) + var(--env-h) * var(--tip-y));
}

/* All decorative layers: absolutely positioned, never intercept clicks. */
.stage > .ornament,
.temple, .envelope, .ribbon, .flower-branch, .wax-seal-wrap {
  position: absolute;
  pointer-events: none;
}
.temple img, .ribbon img, .flower-branch img, .ornament {
  width: 100%;
  height: 100%;
  object-fit: contain;          /* never stretch artwork */
  user-select: none;
  -webkit-user-drag: none;
}
.stage > .ornament { height: auto; }
/* Pointer parallax: script.js sets --mx / --my (−1…1) on the stage. */
.parallax {
  translate: calc(var(--mx, 0) * var(--depth, 0) * 1px) calc(var(--my, 0) * var(--depth, 0) * 1px);
  transition: translate 900ms var(--ease-silk);
}

/* 4. LAYER POSITIONS — DESKTOP / TABLET LANDSCAPE ==========================
   Measured from the reference (พื้นหลังการ์ดเชิญ…png, 1550 × 1015).
   At that size 1u ≈ 10px and "50%" is the vertical centre, so a value like
   `top: calc(50% - 31 * var(--u))` means "310px above the centre".
   ========================================================================== */

/* Envelope — left third, bleeding off the left and top/bottom edges.
   Reference: burgundy spans x 0–≈500px, flap tip at the seal. */
.envelope {
  z-index: var(--z-envelope);
  left: var(--env-x);
  top: var(--env-y);
  width: var(--env-w);
  height: var(--env-h);
  pointer-events: auto;
  cursor: pointer;
}

/* Wax seal — centred on the flap tip. Reference: centre (308, 490), Ø ≈ 190px */
.wax-seal-wrap {
  z-index: var(--z-seal);
  --seal: calc(19 * var(--u));
  width: var(--seal);
  aspect-ratio: 640 / 616;
  left: calc(var(--seal-cx) - var(--seal) * .5);
  top: calc(var(--seal-cy) - var(--seal) * .5);
}

/* Ribbon — a sheer "V" pinned under the seal, as in the reference:
   .ribbon--lower runs from the seal down to the bottom edge (x ≈ 330–700px),
   .ribbon--upper (same image, flipped) runs up-right over the flap to x ≈ 520px. */
.ribbon { z-index: var(--z-ribbon); aspect-ratio: 922 / 1400; opacity: .92; }
.ribbon--lower {
  height: calc(var(--env-h) * .56);
  left: calc(var(--seal-cx) - var(--env-h) * .055);
  top: calc(var(--seal-cy) - var(--env-h) * .07);
  rotate: -11deg;
  transform-origin: 10% 0%;
}
.ribbon--upper {
  height: calc(var(--env-h) * .4);
  left: calc(var(--seal-cx) - var(--env-h) * .03);
  top: calc(var(--seal-cy) - var(--env-h) * .37);
  rotate: 6deg;
  transform-origin: 0% 100%;
}
.ribbon--upper img { scale: 1 -1; }      /* flipped vertically: rises to the upper right */

/* Flower branches */
.flower-branch { z-index: var(--z-branch); }
/* Grounding: a soft contact shadow so the sprigs read as lying ON the paper, not hovering above it */
.flower-branch img {
  transform-origin: 8% 95%;   /* sway pivots at the stem */
  filter: drop-shadow(1px 3px 2px rgba(74, 34, 18, .28)) drop-shadow(3px 8px 10px rgba(74, 34, 18, .14));
}
/* The two sprigs beside the ribbon sit UNDER the sheer ribbon, so their stems are tucked
   beneath it (as in the reference) instead of ending in open space. */
.flower-branch--center-left,
.flower-branch--mid { z-index: calc(var(--z-ribbon) - 1); }

.flower-branch--upper-left {           /* ref: x 150–390, y 50–330 (on the envelope) */
  width: calc(27 * var(--u)); aspect-ratio: 1000 / 994;
  left: calc(13 * var(--u)); top: calc(50% - 46 * var(--u));
}
.flower-branch--center-left {          /* ref: x 385–640, y 195–480 (beside the ribbon, top) */
  width: calc(27 * var(--u)); aspect-ratio: 870 / 1000;
  left: calc(35 * var(--u)); top: calc(50% - 30 * var(--u));
}
.flower-branch--mid {                  /* ref: x 390–650, y 470–770 (beside the ribbon, lower) */
  width: calc(26 * var(--u)); aspect-ratio: 885 / 1000;
  left: calc(36 * var(--u)); top: calc(50% - 4 * var(--u));
  rotate: -10deg;
}
.flower-branch--lower-left {           /* ref: x 0–290, y 530–1000 (on the envelope) */
  width: calc(35 * var(--u)); aspect-ratio: 1000 / 979;
  left: calc(-7 * var(--u)); top: calc(50% + 4 * var(--u));
  rotate: -12deg;
}
.flower-branch--lower-right {          /* ref: x 1180–1550, y 650–1015 */
  width: calc(37 * var(--u)); aspect-ratio: 885 / 1000;
  right: calc(-1 * var(--u)); top: calc(50% + 14 * var(--u));
}
.flower-branch--accent {               /* ref: x 580–810, y 790–1015 (ribbon foot) */
  width: calc(23 * var(--u)); aspect-ratio: 870 / 1000;
  left: calc(57 * var(--u)); top: calc(50% + 28 * var(--u));
}

/* Temple — ref: x ≈ 960 (faded landscape) – 1540, spire top y ≈ 230, runs off the bottom */
.temple {
  z-index: var(--z-temple);
  height: calc(80 * var(--u)); aspect-ratio: 811 / 1200;
  right: 0; top: calc(50% - 28 * var(--u));
}

/* Printed medallions & corner motifs */
.ornament--print { z-index: var(--z-print); }
.ornament--print-a { width: calc(19 * var(--u)); right: calc(15 * var(--u)); top: calc(50% - 36 * var(--u)); }  /* ref: 1210–1400, 140–300 */
.ornament--print-b { width: calc(10 * var(--u)); left: calc(53 * var(--u)); top: calc(50% - 48 * var(--u)); }   /* ref: 540–640, 20–120 */
.ornament--corner { z-index: var(--z-branch); }
.ornament--corner-tr { width: calc(4.6 * var(--u)); right: calc(6 * var(--u)); top: calc(50% - 47.5 * var(--u)); } /* ref: small diamond ≈ (1465, 50) */
.ornament--corner-edge { width: calc(9 * var(--u)); right: calc(-3.5 * var(--u)); top: calc(50% - 54 * var(--u)); } /* ref: gold flourish at the top-right edge */

/* Closed-state title: centred in the open cream area, nudged left of the temple */
.stage-title {
  --title-w: calc(48 * var(--u));
  position: absolute;
  z-index: var(--z-title);
  width: var(--title-w);
  left: max(calc(var(--env-right) + 41 * var(--u)), calc((var(--env-right) + 100% - 30 * var(--u)) / 2));
  top: 50%;
  translate: -50% -50%;
}

/* Invitation card — centred in the cream area once open */
.invitation-card {
  --card-w: calc(54 * var(--u));
  --card-h: calc(85 * var(--u));
  position: absolute;
  z-index: var(--z-card);
  width: var(--card-w);
  height: var(--card-h);
  left: calc((var(--env-right) + 100%) / 2 - var(--card-w) / 2);
  top: calc(50% - var(--card-h) / 2 - 3 * var(--u));   /* lifted to leave room for the scroll cue */
}

/* 5. ENVELOPE + 3D FLAP ==================================================== */
.envelope { perspective: 1500px; perspective-origin: 40% 50%; }
.envelope__body,
.envelope__pocket,
.envelope__flap,
.flap-face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.envelope__body { filter: brightness(.84) saturate(1.05) drop-shadow(10px 14px 22px rgba(60, 10, 18, .35)); }

/* The large front flap, traced from the envelope artwork (percent of the image).
   Hinge = left edge. If you swap the envelope image, re-trace these 5 points. */
.envelope { --flap-shape: polygon(0% 0%, 2.4% 1.5%, 75.7% 49%, 3.8% 99.4%, 0% 100%); }
.envelope__pocket {
  clip-path: var(--flap-shape);
  background:
    linear-gradient(90deg, rgba(0,0,0,.45), transparent 35%),
    repeating-linear-gradient(135deg, rgba(207,163,90,.05) 0 2px, transparent 2px 14px),
    radial-gradient(ellipse 80% 60% at 20% 50%, #4a0e19, var(--burgundy-950) 80%);
  opacity: 0;                         /* only visible while the flap is open */
}
.envelope__flap {
  transform-origin: 0% 50%;
  transform-style: preserve-3d;
  transform: rotateY(0deg);
}
.flap-face {
  object-fit: fill;                   /* identical box to the body image, so pixels line up */
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.flap-face--front {
  clip-path: var(--flap-shape);
  filter: brightness(.84) saturate(1.05);   /* must match .envelope__body */
}
.flap-face--back {
  /* Mirrored shape: the back face is turned 180° so its polygon is flipped horizontally */
  clip-path: polygon(100% 0%, 97.6% 1.5%, 24.3% 49%, 96.2% 99.4%, 100% 100%);
  transform: rotateY(180deg);
  filter: brightness(.55) saturate(1.1) sepia(.15);
}

/* 6. SEAL, RIBBON, BRANCHES, TEMPLE, ORNAMENTS ============================= */
.wax-seal {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  border-radius: 50%;
  filter: drop-shadow(0 calc(1.2 * var(--u)) calc(1.6 * var(--u)) rgba(60, 20, 8, .45));
  transition: scale 400ms var(--ease-silk), filter 400ms var(--ease-silk);
  -webkit-tap-highlight-color: transparent;
}
.wax-seal img { width: 100%; height: 100%; object-fit: contain; }
.wax-seal:hover { scale: 1.04; }
.wax-seal:active { scale: .97; }
.wax-seal__monogram {
  position: absolute;
  inset: 22% 22% 24% 20%;
  display: flex; align-items: center; justify-content: center;
  gap: 4%;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: calc(var(--seal, 19vh) * .26);
  line-height: 1;
  color: #a77a35;
  /* debossed: light lower-right edge, dark upper-left edge */
  text-shadow: 1px 1px 0 rgba(255, 238, 190, .75), -1px -1px 0 rgba(90, 55, 15, .55);
}
.wax-seal__monogram i {
  width: 1px; height: 70%;
  background: linear-gradient(#8b6224, #e9cf91 50%, #8b6224);
  box-shadow: 1px 0 0 rgba(255, 238, 190, .6);
}
.wax-seal__monogram span:first-child { translate: 0 -12%; }
.wax-seal__monogram span:last-child { translate: 0 12%; }
/* Gentle gold shimmer, masked to the seal's own silhouette */
.wax-seal__shine {
  position: absolute; inset: 0;
  -webkit-mask: url("assets/web/wax-seal-gold.webp") center / contain no-repeat;
          mask: url("assets/web/wax-seal-gold.webp") center / contain no-repeat;
  background: linear-gradient(115deg, transparent 35%, rgba(255, 247, 214, .65) 48%, transparent 60%) no-repeat;
  background-size: 250% 100%;
  background-position: 130% 0;
  mix-blend-mode: soft-light;
  opacity: .9;
}
/* Soft halo inviting the tap */
.wax-seal::before {
  content: "";
  position: absolute; inset: -12%;
  border-radius: 50%;
  border: 1px solid rgba(226, 192, 124, .7);
  opacity: 0;
}

.ribbon img { filter: drop-shadow(0 6px 10px rgba(110, 40, 40, .12)); }

.temple img {
  mix-blend-mode: multiply;
  filter: grayscale(1) sepia(1) saturate(1.9) hue-rotate(-18deg) brightness(1.2) contrast(.8);
  -webkit-mask-image: linear-gradient(to bottom, #000 70%, rgba(0,0,0,.4) 100%);
          mask-image: linear-gradient(to bottom, #000 70%, rgba(0,0,0,.4) 100%);
}
.temple { opacity: .55; }

.ornament--print {
  opacity: .16;
  mix-blend-mode: multiply;
  filter: sepia(.6) saturate(.5);
}
.ornament--corner { filter: drop-shadow(0 2px 3px rgba(90, 55, 15, .3)); }

/* 7. CLOSED-STATE TITLE ==================================================== */
.stage-title { text-align: center; color: var(--ink); }
.stage-title__eyebrow {
  margin: 0 0 calc(1.6 * var(--u));
  font-size: calc(1.75 * var(--u));
  letter-spacing: .32em;
  text-transform: uppercase;
  color: var(--gold-600);
}
.stage-title__names {
  margin: 0;
  font-weight: 400;
  font-style: italic;
  font-size: calc(8.4 * var(--u));
  line-height: 1.02;
  color: var(--burgundy-700);
  display: flex; flex-direction: column; align-items: center;
}
.stage-title__names .amp,
.card-names__amp,
.couple__amp {
  font-style: italic;
  background: var(--gold-foil);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.stage-title__names .amp { font-size: .7em; line-height: 1.1; }
.stage-title__lao {
  margin: calc(1.6 * var(--u)) 0 0;
  font-size: calc(2.3 * var(--u));
  color: var(--ink-soft);
}
.stage-title__date {
  margin: calc(2.2 * var(--u)) auto 0;
  padding-top: calc(1.8 * var(--u));
  width: 60%;
  border-top: 1px solid rgba(181, 134, 60, .45);
  font-size: calc(2.2 * var(--u));
  letter-spacing: .3em;
  color: var(--gold-600);
}
.stage-title__open {
  margin-top: calc(3.2 * var(--u));
  padding: calc(1.2 * var(--u)) calc(3.4 * var(--u));
  min-height: 44px;
  border: 1px solid var(--gold-500);
  border-radius: 999px;
  background: rgba(252, 247, 238, .55);
  color: var(--burgundy-700);
  font-size: max(15px, calc(1.9 * var(--u)));
  letter-spacing: .14em;
  text-transform: uppercase;
  cursor: pointer;
  backdrop-filter: blur(2px);
  transition: background-color 300ms, color 300ms, box-shadow 300ms;
}
.stage-title__open:hover { background: var(--burgundy-700); color: var(--cream-50); box-shadow: 0 6px 18px rgba(85, 17, 32, .25); }
.stage-title__hint {
  margin: calc(1.4 * var(--u)) 0 0;
  font-style: italic;
  font-size: max(13px, calc(1.7 * var(--u)));
  color: var(--ink-soft);
}

/* 8. INVITATION CARD ======================================================= */
.invitation-card {
  pointer-events: none;
  transform-origin: 50% 50%;
}
.invitation-card__paper {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: var(--cream-50);
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(255,255,255,.8) inset,
    0 calc(2 * var(--u)) calc(5 * var(--u)) rgba(61, 11, 20, .22),
    0 calc(.4 * var(--u)) calc(1 * var(--u)) rgba(61, 11, 20, .12);
  overflow: hidden;
}
/* Double gold frame */
.invitation-card__paper::before,
.invitation-card__paper::after {
  content: "";
  position: absolute;
  pointer-events: none;
  border: 1px solid var(--gold-400);
}
.invitation-card__paper::before { inset: calc(1.8 * var(--u)); }
.invitation-card__paper::after { inset: calc(2.6 * var(--u)); border-color: rgba(181, 134, 60, .4); }

.invitation-card__content {
  position: relative;
  z-index: 1;
  height: 100%;
  overflow-y: auto;
  scrollbar-width: thin;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  text-align: center;
  padding: calc(8.6 * var(--u)) calc(5 * var(--u)) calc(4.6 * var(--u));
}
.invitation-card__content > * { margin: 0; }

.ornament--card-top,
.ornament--card-corner { height: auto; }
.ornament--card-top {
  position: absolute; z-index: 2;
  width: calc(7.5 * var(--u));
  left: 50%; top: calc(2.4 * var(--u));
  translate: -50% 0;
  filter: drop-shadow(0 2px 3px rgba(90, 55, 15, .3));
}
.ornament--card-corner {
  position: absolute; z-index: 2;
  width: calc(3.6 * var(--u));
  filter: drop-shadow(0 1px 2px rgba(90, 55, 15, .3));
}
.ornament--tl { left: calc(.4 * var(--u)); top: calc(.4 * var(--u)); }
.ornament--tr { right: calc(.4 * var(--u)); top: calc(.4 * var(--u)); }
.ornament--bl { left: calc(.4 * var(--u)); bottom: calc(.4 * var(--u)); }
.ornament--br { right: calc(.4 * var(--u)); bottom: calc(.4 * var(--u)); }

.card-eyebrow {
  font-size: calc(1.65 * var(--u));
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gold-600);
}
.card-lao {
  margin-top: calc(.6 * var(--u)) !important;
  font-size: calc(1.5 * var(--u));
  color: var(--ink-soft);
}
.card-names {
  margin-top: calc(1.8 * var(--u)) !important;
  font-weight: 400;
  font-style: italic;
  font-size: calc(5.7 * var(--u));
  line-height: 1;
  color: var(--burgundy-700);
  display: flex; flex-direction: column; align-items: center;
  outline: none;
}
.card-names__amp { font-size: .62em; line-height: 1.15; }
.card-names-lao {
  margin-top: calc(1.2 * var(--u)) !important;
  font-size: calc(2 * var(--u));
  color: var(--ink-soft);
}
.gold-rule {
  display: block;
  width: calc(16 * var(--u));
  height: 1px;
  margin: calc(1.8 * var(--u)) auto !important;
  background: linear-gradient(90deg, transparent, var(--gold-400), transparent);
}
.card-message {
  max-width: 34ch;
  font-size: calc(2 * var(--u));
  line-height: 1.32;
  font-style: italic;
}
.card-message-lao {
  margin-top: calc(.8 * var(--u)) !important;
  max-width: 36ch;
  font-size: calc(1.5 * var(--u));
  line-height: 1.6;
  color: var(--ink-soft);
}
.card-date {
  margin-top: calc(2 * var(--u)) !important;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: calc(2 * var(--u));
  width: 100%;
  max-width: calc(40 * var(--u));
}
.card-date__side {
  padding: calc(.6 * var(--u)) 0;
  border-block: 1px solid rgba(181, 134, 60, .55);
  font-size: calc(1.45 * var(--u));
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink);
}
.card-date__day {
  font-size: calc(5.2 * var(--u));
  line-height: 1;
  font-weight: 500;
  background: var(--gold-foil);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.card-time {
  margin-top: calc(.8 * var(--u)) !important;
  font-size: calc(1.9 * var(--u));
  font-style: italic;
}
.card-venue {
  margin-top: calc(1.6 * var(--u)) !important;
  display: flex; flex-direction: column; gap: calc(.3 * var(--u));
  font-size: calc(1.6 * var(--u));
  line-height: 1.4;
  color: var(--ink-soft);
}
.card-venue strong {
  font-weight: 600;
  font-size: calc(1.95 * var(--u));
  letter-spacing: .06em;
  color: var(--burgundy-700);
}
.card-rsvp { margin-top: calc(2 * var(--u)) !important; pointer-events: auto; }
.card-rsvp-by {
  margin-top: calc(1 * var(--u)) !important;
  font-size: calc(1.4 * var(--u));
  font-style: italic;
  color: var(--ink-soft);
}

/* Buttons (shared) */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px;
  padding: .7em 2.2em;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 15px;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 300ms, color 300ms, box-shadow 300ms, translate 300ms;
}
.btn:hover { translate: 0 -1px; }
.btn--burgundy { background: var(--burgundy-700); color: var(--cream-50); box-shadow: 0 6px 16px rgba(85, 17, 32, .25); }
.btn--burgundy:hover { background: var(--burgundy-800); }
.btn--gold { background: var(--gold-foil); color: var(--burgundy-900); font-weight: 600; box-shadow: 0 6px 18px rgba(20, 2, 6, .3); }
.btn--outline { border-color: var(--gold-500); color: var(--burgundy-700); background: transparent; }
.btn--outline:hover { background: var(--burgundy-700); color: var(--cream-50); }
.btn--outline-light { border-color: var(--gold-300); color: var(--gold-200); background: transparent; }
.btn--outline-light:hover { background: var(--gold-300); color: var(--burgundy-900); }

/* Scroll cue + replay */
.scroll-cue {
  position: absolute;
  z-index: var(--z-ui);
  left: calc((var(--env-right) + 100%) / 2);
  bottom: max(12px, calc(1.6 * var(--u)));
  translate: -50% 0;
  display: flex; flex-direction: column; align-items: center;
  font-size: 13px; letter-spacing: .24em; text-transform: uppercase;
  color: var(--burgundy-700);
  text-decoration: none;
  opacity: 0; visibility: hidden;
  transition: opacity 800ms var(--ease-silk), visibility 0s 800ms;
}
.scroll-cue svg { width: 22px; height: 22px; animation: cue 2.4s var(--ease-silk) infinite; }
@keyframes cue { 0%, 100% { translate: 0 0; opacity: .6; } 50% { translate: 0 5px; opacity: 1; } }

.replay-fab {
  position: fixed;
  z-index: var(--z-ui);
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px;
  padding: 0 18px 0 14px;
  border: 1px solid rgba(207, 163, 90, .8);
  border-radius: 999px;
  background: rgba(61, 11, 20, .88);
  color: var(--gold-200);
  font-size: 14px; letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(42, 6, 12, .3);
  backdrop-filter: blur(6px);
  opacity: 0; visibility: hidden; translate: 0 10px;
  transition: opacity 500ms, translate 500ms var(--ease-silk), visibility 0s 500ms, background-color 300ms;
}
.replay-fab svg { width: 18px; height: 18px; }
.replay-fab:hover { background: var(--burgundy-700); }

/* 9. OPENING SEQUENCE ======================================================
   script.js moves <html data-invite> through:
     closed → opening → open → (replay) closing → closed
   Each element declares its transition for the state it is ENTERING, so the
   opening uses the long staggered delays, and the reset is quick.
   ========================================================================== */

/* ---- CLOSED (initial) / CLOSING (replay reset: fast, no delays) ---- */
.stage-title { transition: opacity 700ms var(--ease-silk) 300ms, translate 900ms var(--ease-silk) 300ms, visibility 0s; }
.wax-seal { transition: opacity 600ms var(--ease-silk) 400ms, transform 700ms var(--ease-silk) 400ms, scale 400ms var(--ease-silk); }
.envelope__flap { transition: transform 900ms var(--ease-flap); }
.envelope__pocket { transition: opacity 400ms 500ms; }
.ribbon img { transition: transform 900ms var(--ease-silk), opacity 900ms; }
.invitation-card {
  opacity: 0;
  visibility: hidden;
  /* --from-x / --from-y are measured by script.js: vector from card centre to the envelope pocket */
  transform: translate(var(--from-x, -40vw), var(--from-y, 0px)) scale(.24) rotate(-6deg);
  transition: opacity 500ms var(--ease-silk), transform 700ms var(--ease-silk), visibility 0s 700ms;
}
.ornament--card-top, .ornament--card-corner {
  opacity: 0; scale: .7;
  transition: opacity 300ms, scale 300ms;
}
.reveal {
  opacity: 0;
  translate: 0 calc(1.4 * var(--u, 8px));
  transition: opacity 300ms, translate 300ms;
}

/* ---- OPENING / OPEN ---- */
[data-invite="opening"] .stage-title,
[data-invite="open"] .stage-title {
  opacity: 0; visibility: hidden; translate: -50% calc(-50% - 3 * var(--u));
  transition: opacity var(--t-title) var(--ease-silk) var(--d-title), translate var(--t-title) var(--ease-silk) var(--d-title), visibility 0s calc(var(--d-title) + var(--t-title));
}
/* 1. Seal lifts, scales down slightly and fades */
[data-invite="opening"] .wax-seal,
[data-invite="open"] .wax-seal {
  opacity: 0;
  transform: translateY(calc(-5 * var(--u))) scale(.82) rotate(-8deg);
  pointer-events: none;
  transition: opacity var(--t-seal) var(--ease-silk) calc(var(--d-seal) + 150ms), transform var(--t-seal) var(--ease-lift) var(--d-seal);
}
/* 2. Flap swings open on its left hinge (3D) */
[data-invite="opening"] .envelope__flap,
[data-invite="open"] .envelope__flap {
  transform: rotateY(-168deg);
  transition: transform var(--t-flap) var(--ease-flap) var(--d-flap);
}
[data-invite="opening"] .envelope__pocket,
[data-invite="open"] .envelope__pocket {
  opacity: 1;
  transition: opacity 200ms var(--d-flap);
}
/* 3. Ribbon drifts aside to reveal the opening */
[data-invite="opening"] .ribbon--upper img,
[data-invite="open"] .ribbon--upper img {
  transform: translate(calc(5 * var(--u)), calc(-4 * var(--u)));
  opacity: 0;
  transition: transform var(--t-ribbon) var(--ease-silk) calc(var(--d-ribbon) - 300ms), opacity 900ms var(--ease-silk) calc(var(--d-ribbon) - 300ms);
}
[data-invite="opening"] .ribbon--lower img,
[data-invite="open"] .ribbon--lower img {
  transform: translate(calc(4 * var(--u)), calc(3 * var(--u))) rotate(4deg);
  opacity: .7;
  transition: transform var(--t-ribbon) var(--ease-silk) var(--d-ribbon), opacity var(--t-ribbon) var(--ease-silk) var(--d-ribbon);
}
/* 4. Card rises out of the envelope and settles in the cream space */
[data-invite="opening"] .invitation-card,
[data-invite="open"] .invitation-card {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
  transition:
    opacity 600ms var(--ease-silk) var(--d-card),
    transform var(--t-card) var(--ease-lift) var(--d-card),
    visibility 0s var(--d-card);
}
/* 5. Gold ornaments */
[data-invite="opening"] .ornament--card-top,
[data-invite="opening"] .ornament--card-corner,
[data-invite="open"] .ornament--card-top,
[data-invite="open"] .ornament--card-corner {
  opacity: 1; scale: 1;
  transition: opacity var(--t-ornament) var(--ease-silk) var(--d-ornament), scale var(--t-ornament) var(--ease-lift) var(--d-ornament);
}
/* 6. Text, staggered (script.js sets --i on each .reveal) */
[data-invite="opening"] .reveal,
[data-invite="open"] .reveal {
  opacity: 1;
  translate: 0 0;
  transition:
    opacity var(--t-text) var(--ease-silk) calc(var(--d-text) + var(--i, 0) * var(--stagger)),
    translate var(--t-text) var(--ease-lift) calc(var(--d-text) + var(--i, 0) * var(--stagger));
}
/* Temple & right branch step back so the card owns the space */
.temple, .flower-branch--lower-right, .ornament--print-a { transition: opacity 1200ms var(--ease-silk), translate 900ms var(--ease-silk); }
[data-invite="opening"] .temple, [data-invite="open"] .temple { opacity: .26; transition-delay: 1200ms; }
/* UI that only appears once open */
[data-invite="open"] .scroll-cue,
[data-invite="open"] .replay-fab {
  opacity: 1; visibility: visible; translate: -50% 0;
  transition: opacity 800ms var(--ease-silk), translate 800ms var(--ease-silk), visibility 0s;
}
[data-invite="open"] .replay-fab { translate: 0 0; }

/* 10. AMBIENT MOTION ======================================================= */
@media (prefers-reduced-motion: no-preference) {
  /* Slow floating branches — different periods so they never sync up */
  .flower-branch img { animation: sway 11s ease-in-out infinite; }
  .flower-branch--center-left img { animation-duration: 13s; animation-delay: -4s; }
  .flower-branch--lower-left img { animation-duration: 15s; animation-delay: -7s; }
  .flower-branch--lower-right img { animation-duration: 12s; animation-delay: -2s; }
  .flower-branch--accent img { animation-duration: 10s; animation-delay: -5s; }
  @keyframes sway {
    0%, 100% { rotate: -.45deg; }
    50% { rotate: .55deg; }
  }

  /* Ribbon: barely-there breathing (on the wrapper so it doesn't fight the open transform) */
  .ribbon { animation: ribbon-breathe 9s ease-in-out infinite; }
  @keyframes ribbon-breathe {
    0%, 100% { scale: 1 1; }
    50% { scale: 1.012 1.008; }
  }

  /* Gold shimmer sweeping across the seal every ~6 s */
  .wax-seal__shine { animation: shimmer 6s var(--ease-silk) infinite 1.5s; }
  @keyframes shimmer {
    0% { background-position: 130% 0; }
    35%, 100% { background-position: -40% 0; }
  }
  .wax-seal::before { animation: halo 3.2s var(--ease-silk) infinite 2s; }
  @keyframes halo {
    0% { opacity: .0; scale: .92; }
    30% { opacity: .9; }
    100% { opacity: 0; scale: 1.18; }
  }

  /* Soft reveals on first load */
  .temple img { animation: temple-reveal 2.6s var(--ease-silk) both .3s; }
  @keyframes temple-reveal {
    from { opacity: 0; clip-path: inset(100% 0 0 0); translate: 0 2%; }
    to { opacity: 1; clip-path: inset(0 0 0 0); translate: 0 0; }
  }
  .stage > .ornament { animation: fade-in 1.8s var(--ease-silk) both 1s; }
  .stage > .ornament--print-b { animation-delay: 1.4s; }
  .stage > .ornament--corner { animation-delay: 1.8s; }
  .flower-branch--mid img { animation-duration: 14s; animation-delay: -9s; }
  @keyframes fade-in { from { opacity: 0; scale: .85; } }
  .stage-title { animation: title-in 1.6s var(--ease-silk) both .6s; }
  @keyframes title-in { from { opacity: 0; filter: blur(4px); } }
}

/* 11. LAYER POSITIONS — MOBILE / PORTRAIT ===================================
   Portrait screens get a stacked composition:
     title at the top · envelope centred below · branches tucked into corners ·
     temple faded behind the title · card opens centred over everything.
   Units switch to vw/svh because the composition is now width-driven.
   ========================================================================== */
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .stage {
    --u: min(1vw, .55svh);
    min-height: 600px;
    /* script.js measures where the title ends (--title-bottom) and the stage height (--stage-h);
       the envelope is then sized and centred in the space BELOW the title, so they never overlap.
       Fallbacks apply if JavaScript is unavailable. */
    --title-bottom: 44svh;
    --stage-h: 100svh;
    --gap: max(2.5svh, 14px);
    --avail: calc(var(--stage-h) - var(--title-bottom) - var(--gap) - max(4svh, 24px));
    --env-h: min(118vw, 60svh, var(--avail));
    --env-w: calc(var(--env-h) * .6636);
    --env-x: calc(50% - var(--env-w) * .56);
    --env-y: calc(var(--title-bottom) + var(--gap) + (var(--avail) - var(--env-h)) / 2);
  }

  .stage-title {
    --title-w: min(86vw, 520px);
    left: 50%;
    top: max(4.5svh, 28px);
    translate: -50% 0;
  }
  [data-invite="opening"] .stage-title,
  [data-invite="open"] .stage-title { translate: -50% -16px; }
  .stage-title__eyebrow { font-size: clamp(10px, 2.7vw, 14px); margin-bottom: 1.2svh; }
  .stage-title__names { font-size: clamp(30px, min(10.5vw, 6.4svh), 60px); flex-direction: row; gap: .25em; justify-content: center; flex-wrap: wrap; }
  .stage-title__names .amp { line-height: inherit; }
  .stage-title__lao { font-size: clamp(14px, 3.8vw, 19px); margin-top: .8svh; }
  .stage-title__date { font-size: clamp(13px, 3.4vw, 17px); margin-top: 1.2svh; padding-top: 1.1svh; width: 52%; }
  .stage-title__open { margin-top: 1.6svh; font-size: 13px; padding: 10px 22px; }
  .stage-title__hint { margin-top: .8svh; font-size: 13px; }

  .wax-seal-wrap { --seal: min(24vw, 13svh, 130px); }


  .flower-branch--upper-left {           /* tucked into the envelope's top-left */
    width: min(40vw, 22svh);
    left: calc(var(--env-x) - 12vw); top: calc(var(--env-y) + var(--env-h) * .02);
  }
  .flower-branch--center-left {          /* right of the seal */
    width: min(32vw, 19svh);
    left: auto; right: -6vw;
    top: calc(var(--env-y) + var(--env-h) * .12);
    rotate: 8deg;
  }
  .flower-branch--lower-left {
    width: min(50vw, 28svh);
    left: -16vw; top: auto; bottom: -5svh;
  }
  .flower-branch--lower-right {
    width: min(44vw, 26svh);
    right: -12vw; top: auto; bottom: -6svh;
  }
  .flower-branch--accent, .flower-branch--mid, .ornament--corner-edge { display: none; }

  .temple {                              /* faded behind the right side of the title */
    height: min(42svh, 92vw);
    right: -14vw; top: 2svh;
    opacity: .2;
  }
  [data-invite="opening"] .temple, [data-invite="open"] .temple { opacity: .12; }
  .ornament--print-a { width: 22vw; right: auto; left: -6vw; top: 14svh; }
  .stage { background-color: #efdaca; }
  .ornament--print-b { display: none; }
  .ornament--corner-tr { width: 7vw; max-width: 34px; right: 4vw; top: 2svh; }

  .invitation-card {
    --card-w: min(90vw, 440px);
    --card-h: min(calc(100svh - 100px), 760px);   /* leaves a strip below for the Replay button */
    left: calc(50% - var(--card-w) / 2);
    top: max(20px, calc(50% - var(--card-h) / 2 - 28px));
  }
  /* Replay sits centred under the card on phones so it never covers the RSVP button */
  .replay-fab { right: auto; left: 50%; translate: -50% 10px; bottom: max(14px, env(safe-area-inset-bottom)); }
  [data-invite="open"] .replay-fab { translate: -50% 0; }
  .invitation-card__content { padding: 64px 30px 40px; justify-content: safe center; }
  .invitation-card__paper::before { inset: 12px; }
  .invitation-card__paper::after { inset: 17px; }
  .ornament--card-top { width: 50px; top: 16px; }
  .ornament--card-corner { width: 24px; }
  .ornament--tl { left: 3px; top: 3px; } .ornament--tr { right: 3px; top: 3px; }
  .ornament--bl { left: 3px; bottom: 3px; } .ornament--br { right: 3px; bottom: 3px; }
  .card-eyebrow { font-size: 11px; }
  .card-lao { font-size: 12px; }
  .card-names { font-size: clamp(36px, 11vw, 52px); margin-top: 14px !important; }
  .card-names-lao { font-size: 15px; margin-top: 8px !important; }
  .gold-rule { width: 110px; margin: 16px auto !important; }
  .card-message { font-size: 17px; }
  .card-message-lao { font-size: 12.5px; }
  .card-date { max-width: 300px; gap: 12px; margin-top: 18px !important; }
  .card-date__side { font-size: 11px; letter-spacing: .16em; }
  .card-date__day { font-size: 46px; }
  .card-time { font-size: 15px; }
  .card-venue { font-size: 13.5px; margin-top: 14px !important; }
  .card-venue strong { font-size: 16px; }
  .card-rsvp { margin-top: 18px !important; }
  .card-rsvp-by { font-size: 12.5px; }

  /* Card covers the envelope once open: let the envelope sink slightly */
  .envelope { transition: translate 900ms var(--ease-silk); }

  .scroll-cue { left: 50%; bottom: 10px; font-size: 11px; }
  [data-invite="open"] .scroll-cue { opacity: 0; visibility: hidden; } /* card fills the screen; replay + RSVP cover navigation */
}

/* Squarer landscape screens (e.g. 1024 × 768 tablets): shrink the temple so it never sits under the title */
@media (min-aspect-ratio: 4/5) and (max-aspect-ratio: 3/2) and (min-width: 761px) {
  .temple { height: calc(62 * var(--u)); right: calc(-5 * var(--u)); top: calc(50% - 16 * var(--u)); }
  .ornament--print-a { right: calc(6 * var(--u)); }
}

/* Very short landscape phones: keep the desktop composition but free the card to scroll */
@media (max-height: 520px) and (min-aspect-ratio: 4/5) {
  .stage { min-height: 100svh; --u: min(1.1svh, .68vw); }
  .stage-title__open { min-height: 36px; }
}

/* Touch / small screens: drop the expensive effects */
@media (hover: none), (max-width: 760px) {
  .parallax { translate: none; transition: none; }
  .envelope__body { filter: drop-shadow(4px 6px 10px rgba(60, 10, 18, .3)); }
  .ribbon img { filter: none; }
  .flower-branch img { filter: drop-shadow(1px 3px 2px rgba(74, 34, 18, .22)); }
  .wax-seal__shine { animation: none !important; display: none; }
  .ribbon { animation: none !important; }
  .stage-title__open { backdrop-filter: none; }
}

/* 12. SCENE 4 · INFORMATION SECTIONS ======================================= */
.details { position: relative; z-index: 1; }
.section {
  padding: clamp(64px, 10vw, 120px) clamp(20px, 5vw, 48px);
  text-align: center;
}
.section--cream { background-color: var(--cream-100); }
.section--champagne { background-color: var(--cream-200); }
.section--burgundy {
  color: var(--cream-100);
  background:
    radial-gradient(ellipse 80% 70% at 50% 0%, rgba(131, 34, 51, .65), transparent 70%),
    radial-gradient(ellipse 60% 80% at 100% 100%, rgba(42, 6, 12, .6), transparent 70%),
    var(--burgundy-800);
}
.section__head { max-width: 720px; margin: 0 auto clamp(36px, 6vw, 56px); }
.eyebrow {
  margin: 0 0 12px;
  font-size: 13px;
  letter-spacing: .32em;
  text-transform: uppercase;
  color: var(--gold-600);
}
.section--burgundy .eyebrow { color: var(--gold-300); }
.section__title {
  margin: 0;
  font-weight: 400;
  font-size: clamp(34px, 6vw, 56px);
  line-height: 1.1;
  color: var(--burgundy-700);
}
.section--burgundy .section__title { color: var(--cream-50); }
.section__lao { margin: 10px 0 0; font-size: clamp(15px, 2.2vw, 18px); color: var(--ink-soft); }
.section--burgundy .section__lao { color: var(--champagne); }
.divider {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  margin-top: 22px;
}
.divider::before, .divider::after {
  content: ""; width: min(110px, 24vw); height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-400));
}
.divider::after { background: linear-gradient(90deg, var(--gold-400), transparent); }
.divider img { width: 26px; height: auto; }

/* Couple */
.couple {
  max-width: 980px; margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: clamp(20px, 4vw, 48px);
}
.person { margin: 0; }
.person__monogram {
  width: 128px; height: 128px; margin: 0 auto 22px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, var(--burgundy-600), var(--burgundy-900));
  box-shadow: 0 0 0 4px var(--cream-100), 0 0 0 5px var(--gold-400), 0 14px 30px rgba(61, 11, 20, .25);
}
.person__monogram span {
  font-size: 58px; font-style: italic; line-height: 1;
  background: var(--gold-foil);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.person__role { margin: 0; font-size: 13px; letter-spacing: .22em; text-transform: uppercase; color: var(--gold-600); }
.person__name { margin: 8px 0 0; font-weight: 500; font-size: clamp(26px, 3.4vw, 34px); color: var(--burgundy-700); }
.person__lao { margin: 4px 0 0; font-size: 18px; color: var(--ink-soft); }
.person__parents { margin: 14px 0 0; font-style: italic; font-size: 17px; }
.person__bio { margin: 10px auto 0; max-width: 34ch; font-size: 17px; color: var(--ink-soft); }
.couple__amp { align-self: center; font-size: clamp(54px, 8vw, 88px); line-height: 1; }

/* Countdown */
.countdown {
  display: flex; justify-content: center; flex-wrap: wrap;
  gap: clamp(10px, 2.4vw, 24px);
}
.countdown__unit {
  width: clamp(72px, 18vw, 128px);
  padding: clamp(14px, 2.6vw, 24px) 6px;
  border: 1px solid rgba(207, 163, 90, .55);
  border-radius: 4px;
  background: rgba(42, 6, 12, .25);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.countdown__num {
  font-size: clamp(34px, 7vw, 60px);
  line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
  background: var(--gold-foil);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.countdown__label { font-size: 12px; letter-spacing: .26em; text-transform: uppercase; color: var(--champagne); }
.countdown__note { margin: 28px 0 0; font-style: italic; font-size: 20px; color: var(--champagne); }

/* Schedule */
.schedule {
  list-style: none; margin: 0 auto; padding: 0;
  max-width: 640px;
  text-align: left;
  position: relative;
}
.schedule::before {
  content: ""; position: absolute; left: 92px; top: 8px; bottom: 8px; width: 1px;
  background: linear-gradient(var(--gold-400), rgba(207, 163, 90, .2));
}
.schedule__item {
  position: relative;
  display: grid; grid-template-columns: 92px 1fr; gap: 0 36px;
  padding: 0 0 36px;
}
.schedule__item:last-child { padding-bottom: 0; }
.schedule__item::before {
  content: ""; position: absolute; left: 87px; top: 10px;
  width: 11px; height: 11px; rotate: 45deg;
  background: var(--gold-foil);
  box-shadow: 0 0 0 4px var(--cream-100);
}
.schedule__time { font-size: 24px; color: var(--gold-600); font-variant-numeric: lining-nums; text-align: right; padding-right: 22px; line-height: 1.3; }
.schedule__title { margin: 0; font-weight: 500; font-size: 24px; line-height: 1.3; color: var(--burgundy-700); }
.schedule__lao { margin: 2px 0 0; font-size: 15px; color: var(--ink-soft); }
.schedule__desc { margin: 6px 0 0; font-size: 17px; color: var(--ink); }

/* Venue */
.venue {
  max-width: 640px; margin: 0 auto;
  padding: clamp(32px, 5vw, 52px) clamp(22px, 5vw, 56px);
  background: var(--cream-50);
  border: 1px solid rgba(181, 134, 60, .45);
  outline: 1px solid rgba(181, 134, 60, .25); outline-offset: -8px;
  box-shadow: 0 18px 40px rgba(61, 11, 20, .08);
}
.venue__name { margin: 0; font-weight: 500; font-size: clamp(26px, 3.6vw, 34px); color: var(--burgundy-700); }
.venue__lao { margin: 4px 0 0; color: var(--ink-soft); }
.venue__address { margin: 16px 0 0; font-style: normal; font-size: 18px; }
.venue__note { margin: 12px auto 26px; max-width: 42ch; font-style: italic; color: var(--ink-soft); font-size: 17px; }

/* RSVP */
.rsvp {
  max-width: 620px; margin: 0 auto;
  display: grid; grid-template-columns: 1fr 1fr; gap: 20px 22px;
  text-align: left;
  padding: clamp(26px, 5vw, 44px);
  background: rgba(252, 247, 238, .06);
  border: 1px solid rgba(207, 163, 90, .45);
  border-radius: 4px;
}
.field { grid-column: 1 / -1; margin: 0; padding: 0; border: 0; min-width: 0; }
.field--half { grid-column: span 1; }
.field label, .field legend {
  display: block; margin-bottom: 8px; padding: 0;
  font-size: 14px; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-200);
}
.req { color: var(--gold-300); }
.field input[type="text"], .field select, .field textarea {
  width: 100%;
  min-height: 46px;
  padding: 10px 14px;
  border: 1px solid rgba(231, 208, 176, .45);
  border-radius: 3px;
  background: rgba(252, 247, 238, .94);
  color: var(--ink);
  font-size: 18px;
  transition: border-color 200ms, box-shadow 200ms;
}
.field textarea { resize: vertical; min-height: 92px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--gold-300); box-shadow: 0 0 0 3px rgba(226, 192, 124, .35); }
.field [aria-invalid="true"] { border-color: #f0a29b; box-shadow: 0 0 0 3px rgba(240, 162, 155, .3); }
.field__error { margin: 6px 0 0; min-height: 1em; font-size: 15px; color: #ffc9c2; font-style: italic; }
.field__error:empty { display: none; }
.field--choice { display: flex; flex-wrap: wrap; gap: 6px 22px; }
.field--choice legend { width: 100%; }
.choice {
  display: inline-flex !important; align-items: center; gap: 10px;
  min-height: 40px; margin: 0 !important;
  font-size: 18px !important; letter-spacing: 0 !important; text-transform: none !important;
  color: var(--cream-100) !important; cursor: pointer;
}
.choice input { width: 18px; height: 18px; accent-color: var(--gold-400); margin: 0; }
.rsvp__submit { grid-column: 1 / -1; justify-self: center; margin-top: 6px; min-width: 220px; }
.rsvp__demo-note { grid-column: 1 / -1; margin: 0; text-align: center; font-size: 14px; font-style: italic; color: var(--champagne); opacity: .85; }
.rsvp-done {
  max-width: 560px; margin: 0 auto;
  padding: clamp(28px, 5vw, 44px);
  border: 1px solid rgba(207, 163, 90, .55);
  border-radius: 4px;
  background: rgba(42, 6, 12, .3);
  outline: none;
}
.rsvp-done__title { margin: 0 0 10px; font-weight: 400; font-size: clamp(28px, 4vw, 38px); color: var(--gold-200); }
.rsvp-done p { font-size: 18px; }
.rsvp-done__demo { font-size: 15px !important; color: var(--champagne); padding: 12px 14px; border-left: 2px solid var(--gold-400); text-align: left; background: rgba(0,0,0,.12); }
.rsvp-done code { font-size: .9em; color: var(--gold-200); }

/* Footer */
.footer {
  padding: 64px 20px calc(80px + env(safe-area-inset-bottom));
  text-align: center;
  background: var(--burgundy-950);
  color: var(--champagne);
}
.footer__ornament { width: 40px; margin: 0 auto 16px; }
.footer__names { margin: 0; font-size: 32px; font-style: italic; color: var(--gold-200); }
.footer__date { margin: 6px 0 24px; letter-spacing: .3em; font-size: 15px; }

@media (max-width: 760px) {
  .couple { grid-template-columns: 1fr; gap: 28px; }
  .couple__amp { font-size: 56px; }
  .rsvp { grid-template-columns: 1fr; }
  .field--half { grid-column: 1 / -1; }
  .schedule::before { left: 64px; }
  .schedule__item { grid-template-columns: 64px 1fr; gap: 0 24px; }
  .schedule__item::before { left: 59px; }
  .schedule__time { font-size: 19px; padding-right: 16px; }
  .schedule__title { font-size: 21px; }
}

/* 13. REDUCED MOTION & NO-JS =============================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  :root {
    /* Collapse the choreography into a short cross-fade */
    --t-seal: 300ms; --d-seal: 0ms;
    --t-flap: 1ms; --d-flap: 0ms;
    --t-ribbon: 1ms; --d-ribbon: 0ms;
    --t-card: 1ms; --d-card: 150ms;
    --t-ornament: 400ms; --d-ornament: 150ms;
    --t-text: 400ms; --d-text: 150ms; --stagger: 0ms;
    --t-total: 700ms;
  }
  .parallax { translate: none !important; transition: none !important; }
  .scroll-cue svg { animation: none; }
}

/* Without JavaScript the card is shown open (html[data-invite="open"]) — hide the
   interactive-only controls that would do nothing. */
.no-js .stage-title,
.no-js .wax-seal-wrap,
.no-js .js-replay { display: none; }
.no-js .invitation-card, .no-js .reveal, .no-js .ornament--card-top, .no-js .ornament--card-corner { transition: none !important; }


/* 14. NO-SCROLL MODE (JavaScript on) =======================================
   The whole experience lives in one viewport:
     • html/body never scroll
     • the information sections become PANELS that open over the invitation
     • a bottom nav (.panel-nav) switches panels; swipe ←/→ on touch, Esc = back
   <html data-panel="card|couple|date|schedule|venue|rsvp"> is set by script.js.
   Without JavaScript none of this applies and the page scrolls normally.
   ========================================================================== */
:root { --nav-h: 64px; }

html.js,
html.js body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
html.js body { position: fixed; inset: 0; width: 100%; }   /* iOS: stops rubber-band scrolling */
.js .stage { height: 100vh; height: 100dvh; min-height: 0; }
.js .scroll-cue,
.js .footer,
.js .skip-link { display: none; }

/* Panel layer + dimmed backdrop */
.js .details {
  position: fixed;
  inset: 0;
  z-index: 85;
  pointer-events: none;
}
.js .details::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 40%, rgba(61, 11, 20, .32), rgba(42, 6, 12, .58));
  opacity: 0;
  transition: opacity 600ms var(--ease-silk);
}
.js:not([data-panel="card"]) .details { pointer-events: auto; }
.js:not([data-panel="card"]) .details::before { opacity: 1; }

/* Each section becomes a centred sheet */
.js .panel {
  position: absolute;
  left: 50%;
  top: calc((100% - var(--nav-h)) / 2);
  width: min(780px, calc(100vw - 32px));
  max-height: calc(100% - var(--nav-h) - 36px);
  overflow-y: auto;                    /* safety net on very small screens only */
  scrollbar-width: thin;
  padding: clamp(26px, 4.4vh, 48px) clamp(20px, 4vw, 52px);
  border-radius: 4px;
  outline: 1px solid rgba(207, 163, 90, .55);
  outline-offset: -10px;
  box-shadow: 0 30px 70px rgba(42, 6, 12, .4), 0 6px 18px rgba(42, 6, 12, .2);
  translate: -50% -50%;
  opacity: 0;
  visibility: hidden;
  transform: translateX(calc(var(--panel-dir, 1) * 36px)) scale(.985);
  transition: opacity 450ms var(--ease-silk), transform 650ms var(--ease-lift), visibility 0s 650ms;
}
.js .panel.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 500ms var(--ease-silk) 80ms, transform 750ms var(--ease-lift) 80ms, visibility 0s;
}
.js .panel .section__head { margin-bottom: clamp(16px, 3.4vh, 34px); }
.js .panel .section__title { font-size: clamp(28px, 5vh, 48px); }
.js .panel .eyebrow { margin-bottom: 6px; }
.js .panel .divider { margin-top: clamp(8px, 1.6vh, 18px); }
.js .panel .countdown__note { margin-top: 18px; }

.panel__close {
  position: absolute;
  top: 14px; right: 14px;
  width: 40px; height: 40px;
  display: none;
  place-items: center;
  border: 0; border-radius: 50%;
  background: transparent;
  color: inherit;
  opacity: .7;
  cursor: pointer;
  transition: opacity 200ms, background-color 200ms;
}
.panel__close svg { width: 20px; height: 20px; }
.panel__close:hover { opacity: 1; background: rgba(207, 163, 90, .18); }
.js .panel__close { display: grid; }

/* RSVP inside its sheet: no second box */
.js .panel .rsvp { padding: 0; border: 0; background: none; gap: 14px 20px; }
.js .panel .field textarea { min-height: 64px; }
.js .panel .rsvp__submit { margin-top: 2px; }

/* Bottom navigation */
.panel-nav {
  position: fixed;
  z-index: 95;
  left: 50%;
  bottom: max(12px, env(safe-area-inset-bottom));
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border: 1px solid rgba(207, 163, 90, .7);
  border-radius: 999px;
  background: rgba(61, 11, 20, .9);
  box-shadow: 0 10px 28px rgba(42, 6, 12, .32);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  visibility: hidden;
  translate: -50% 16px;
  transition: opacity 600ms var(--ease-silk), translate 600ms var(--ease-silk), visibility 0s 600ms;
}
[data-invite="open"] .panel-nav {
  opacity: 1;
  visibility: visible;
  translate: -50% 0;
  transition: opacity 700ms var(--ease-silk), translate 700ms var(--ease-silk), visibility 0s;
}
.panel-nav__item,
.panel-nav__replay {
  min-height: 42px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--gold-200);
  cursor: pointer;
  transition: background-color 250ms, color 250ms;
  -webkit-tap-highlight-color: transparent;
}
.panel-nav__item {
  padding: 0 16px;
  font-size: 13px;
  letter-spacing: .16em;
  text-transform: uppercase;
  white-space: nowrap;
}
.panel-nav__item:hover { background: rgba(207, 163, 90, .16); }
.panel-nav__item[aria-current="true"] { background: var(--gold-foil); color: var(--burgundy-900); font-weight: 600; }
.panel-nav__replay {
  width: 42px;
  display: grid; place-items: center;
  margin-left: 4px;
  border-left: 1px solid rgba(207, 163, 90, .3);
  border-radius: 0 999px 999px 0;
}
.panel-nav__replay svg { width: 18px; height: 18px; }
.panel-nav__replay:hover { color: var(--cream-50); }
.no-js .panel-nav { display: none; }
.js .replay-fab { display: none; }

/* Short desktop screens: tighten the sheets so they fit without inner scrolling */
@media (max-height: 820px) and (min-width: 761px) {
  .js .panel .section__lao { display: none; }
  .js .panel .person__monogram { width: 92px; height: 92px; margin-bottom: 14px; }
  .js .panel .person__monogram span { font-size: 42px; }
  .js .panel .schedule__item { padding-bottom: 22px; }
  .js .panel .field input[type="text"], .js .panel .field select { min-height: 42px; padding-block: 7px; }
  .js .panel .field textarea { min-height: 52px; }
  .js .panel .field label, .js .panel .field legend { margin-bottom: 5px; }
}

/* Phones */
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  :root { --nav-h: 62px; }
  .panel-nav { width: calc(100vw - 16px); max-width: 520px; justify-content: space-between; }
  .panel-nav__item { flex: 1 1 0; min-width: 0; padding: 0 2px; font-size: 10.5px; letter-spacing: .05em; overflow: hidden; text-overflow: ellipsis; }
  .panel-nav__replay { width: 38px; flex: 0 0 38px; }

  .js .panel { width: calc(100vw - 20px); padding: 26px 18px 22px; outline-offset: -7px; }
  .js .panel .section__lao { font-size: 14px; margin-top: 4px; }
  .js .panel .eyebrow { font-size: 11px; }
  /* Couple: monogram beside the text instead of stacked */
  .js .panel .couple { gap: 14px; }
  .js .panel .person { display: grid; grid-template-columns: 64px 1fr; gap: 0 16px; text-align: left; align-items: start; }
  .js .panel .person__monogram { width: 64px; height: 64px; margin: 4px 0 0; box-shadow: 0 0 0 3px var(--cream-100), 0 0 0 4px var(--gold-400); }
  .js .panel .person__monogram span { font-size: 30px; }
  .js .panel .person__name { font-size: 23px; margin-top: 2px; }
  .js .panel .person__lao { font-size: 14px; }
  .js .panel .person__parents { font-size: 15px; margin-top: 6px; }
  .js .panel .person__bio { font-size: 15px; margin: 4px 0 0; max-width: none; }
  .js .panel .couple__amp { font-size: 34px; justify-self: center; }
  /* Schedule & venue */
  .js .panel .schedule__item { padding-bottom: 20px; }
  .js .panel .schedule__desc { font-size: 15px; }
  .js .panel .venue { padding: 22px 16px; }
  .js .panel .venue__address, .js .panel .venue__note { font-size: 16px; }
  /* RSVP: keep guests + events side by side to save height */
  .js .panel .rsvp { grid-template-columns: 1fr 1fr; gap: 10px 14px; }
  .js .panel .field--half { grid-column: span 1; }
  .js .panel .field input[type="text"], .js .panel .field select { min-height: 42px; padding: 7px 12px; font-size: 16px; }
  .js .panel .field label, .js .panel .field legend { font-size: 12px; margin-bottom: 5px; }
  .js .panel .choice { font-size: 15px !important; min-height: 32px; }
  .js .panel .field--choice { gap: 0 16px; }
  .js .panel .field textarea { min-height: 52px; }
  .js .panel .rsvp__submit { min-width: 180px; }
  .js .panel .rsvp__demo-note { font-size: 12.5px; }
  .js .panel .countdown__unit { width: calc((100% - 30px) / 4); }
  .js .panel .countdown { flex-wrap: nowrap; gap: 10px; }
}

/* RSVP: name + contact share a row on wider screens so the form fits without inner scrolling */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .js .panel .rsvp > .field--name,
  .js .panel .rsvp > .field--contact { grid-column: span 1; }
  .js .panel .field textarea { min-height: 56px; }
  .js .panel .field input[type="text"], .js .panel .field select { min-height: 44px; padding-block: 8px; }
  .js #rsvp .section__head { margin-bottom: 18px; }
}
/* Short phones (e.g. 360 × 640): drop secondary lines so each panel fits on one screen */
@media (max-height: 720px) and (max-width: 760px) {
  .js .panel { padding: 20px 16px 16px; }
  .js .panel .eyebrow,
  .js .panel .section__lao,
  .js .panel .divider { display: none; }
  .js .panel .section__head { margin-bottom: 12px; }
  .js .panel .section__title { font-size: 28px; }
  .js .panel .person__bio { display: none; }
  .js .panel .couple__amp { font-size: 26px; }
  .js .panel .schedule__item { padding-bottom: 12px; }
  .js .panel .schedule__lao { display: none; }
  .js .panel .venue__note { margin-block: 8px 16px; }
  .js .panel .rsvp { gap: 8px 12px; }
  .js .panel .field textarea { min-height: 44px; }
  .js .panel .rsvp__demo-note { display: none; }
}

/* Desktop RSVP on a 4-column grid: Name | Contact / Attend | Guests | Events / Note */
@media (min-width: 761px) and (min-aspect-ratio: 4/5) {
  .js .panel .rsvp { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .js .panel .rsvp > .field { grid-column: 1 / -1; }
  .js .panel .rsvp > .field--name,
  .js .panel .rsvp > .field--contact,
  .js .panel .rsvp > .field--choice:not(.field--half) { grid-column: span 2; }
  .js .panel .rsvp > .field--half { grid-column: span 1; }
  .js .panel .field--choice:not(.field--half) { flex-direction: column; gap: 0; }
  .js .panel .field--half.field--choice { flex-direction: column; gap: 0; }
}
@media (max-height: 820px) and (min-width: 761px) {
  .js .panel .schedule__item { padding-bottom: 16px; }
  .js .panel { padding-block: 22px; }
}
@media (max-width: 760px) and (max-height: 900px) {
  .js #rsvp .section__head { margin-bottom: 12px; }
  .js .panel .field textarea { min-height: 44px; }
  .js .panel .rsvp { gap: 8px 14px; }
}

/* Nav label swap: "Schedule" on wide screens, the shorter "Agenda" on phones */
.nav-short { display: none; }
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .nav-long { display: none; }
  .nav-short { display: inline; }
  .js .panel .section__head { padding-inline: 30px; }   /* keep long headings clear of the close button */
}

/* 15. PHONE DESIGN — "tableau" card + full-screen detail pages ==============
   Matches the mobile reference: after opening, the sealed envelope stays as a
   full-height strip on the left (seal on its edge), the cream card sits to the
   right with a sheer ribbon over its left edge, faint date numerals and a thin
   gold rule. Detail pages are full-screen cream pages with a hanging sprig and
   a burgundy/blush wave. Desktop is unaffected.
   ========================================================================== */

/* Phone-only pieces are hidden on desktop */
.card-watermark, .card-vline, .schedule__icon, .venue__map { display: none; }

@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  :root { --d-card: 1050ms; --d-ornament: 1900ms; --d-text: 1950ms; --t-total: 3700ms; }

  /* ---------- Tableau geometry once opened (envelope → left strip) ---------- */
  [data-invite="opening"] .stage,
  [data-invite="open"] .stage {
    --env-h: calc(var(--stage-h) * 1.02);
    --env-x: calc(56vw - var(--env-w));       /* right edge tucks under the card */
    --env-y: calc(var(--stage-h) * -.01);
    --seal: min(27vw, 15svh, 130px);
  }
  .envelope, .wax-seal-wrap, .ribbon, .flower-branch {
    transition: left 1300ms var(--ease-silk), top 1300ms var(--ease-silk), right 1300ms var(--ease-silk), bottom 1300ms var(--ease-silk),
                width 1300ms var(--ease-silk), height 1300ms var(--ease-silk), rotate 1300ms var(--ease-silk), opacity 800ms;
  }
  [data-invite="opening"] :is(.envelope, .wax-seal-wrap, .ribbon, .flower-branch) { transition-delay: 250ms; }
  .wax-seal-wrap { --seal: min(24vw, 13svh, 130px); }

  /* The flap stays closed and the seal stays on — as in the reference */
  [data-invite="opening"] .envelope__flap,
  [data-invite="open"] .envelope__flap { transform: none; }
  [data-invite="opening"] .envelope__pocket,
  [data-invite="open"] .envelope__pocket { opacity: 0; }
  [data-invite="opening"] .wax-seal,
  [data-invite="open"] .wax-seal {
    opacity: 1;
    transform: scale(.94);
    transition: transform 900ms var(--ease-lift);
  }
  [data-invite="opening"] .wax-seal-wrap,
  [data-invite="open"] .wax-seal-wrap { z-index: 68; }

  /* Ribbon drapes vertically over the card's left edge */
  [data-invite="opening"] .ribbon--lower,
  [data-invite="open"] .ribbon--lower {
    z-index: 66;
    height: calc(var(--stage-h) * 1.15);
    left: 22vw;
    top: calc(var(--stage-h) * -.08);
    rotate: 25deg;
  }
  [data-invite="opening"] .ribbon--lower img,
  [data-invite="open"] .ribbon--lower img { transform: none; opacity: .9; }

  /* Background pieces step away */
  [data-invite="opening"] :is(.temple, .ornament--print, .ornament--corner),
  [data-invite="open"] :is(.temple, .ornament--print, .ornament--corner) { opacity: 0 !important; }

  /* Sprigs re-arranged around the tableau */
  [data-invite="opening"] .flower-branch--upper-left,
  [data-invite="open"] .flower-branch--upper-left { left: -4vw; top: 3svh; width: 40vw; }
  [data-invite="opening"] .flower-branch--lower-left,
  [data-invite="open"] .flower-branch--lower-left { left: -14vw; bottom: -4svh; width: 46vw; }
  [data-invite="opening"] .flower-branch--center-left,
  [data-invite="open"] .flower-branch--center-left { z-index: 67; left: 21vw; right: auto; top: 13svh; width: 25vw; rotate: -4deg; }
  [data-invite="opening"] .flower-branch--lower-right,
  [data-invite="open"] .flower-branch--lower-right { z-index: 67; right: -9vw; bottom: calc(var(--nav-h) - 3svh); width: 34vw; }

  /* ---------- The card (right side) ---------- */
  .invitation-card {
    --card-top: max(16px, 3svh);
    left: 31vw;
    right: 0;
    width: auto;
    top: var(--card-top);
    height: calc(100% - var(--card-top) - var(--nav-h) - 10px);
  }
  .invitation-card__paper {
    border-radius: 3px 0 0 3px;
    background-color: #f8efe3;
    box-shadow: -10px 0 26px rgba(61, 11, 20, .28), -2px 0 6px rgba(61, 11, 20, .15);
  }
  .invitation-card__paper::before,
  .invitation-card__paper::after,
  .ornament--card-top,
  .ornament--card-corner { display: none; }

  .card-watermark {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    position: absolute;
    z-index: 0;
    top: 3svh;
    right: 10vw;
    font-family: var(--font-serif);
    font-weight: 300;
    font-size: min(21vw, 11svh);
    line-height: .86;
    letter-spacing: -.02em;
    color: rgba(150, 105, 60, .13);
    pointer-events: none;
  }
  .card-vline {
    display: block;
    position: absolute;
    z-index: 0;
    right: 5.5vw;
    top: 9%;
    bottom: 9%;
    width: 1px;
    background: linear-gradient(transparent, var(--gold-400) 12%, var(--gold-400) 88%, transparent);
  }
  .card-vline::before, .card-vline::after {
    content: "";
    position: absolute;
    left: -3px;
    width: 7px; height: 7px;
    rotate: 45deg;
    background: var(--gold-400);
  }
  .card-vline::before { top: 6%; }
  .card-vline::after { bottom: 6%; }

  .invitation-card__content {
    padding: 4svh 12vw 3svh 13vw;
    gap: 0;
  }
  .card-eyebrow { font-size: 10px; letter-spacing: .24em; line-height: 1.6; }
  .card-lao { font-size: 11px; }
  .card-names {
    margin-top: 2.2svh !important;
    font-style: normal;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: .05em;
    font-size: clamp(22px, 7.6vw, 34px);
    line-height: 1.05;
  }
  /* "&" becomes an italic "and", like the reference */
  .card-names__amp { font-size: 0; line-height: 1; }
  .card-names__amp::before {
    content: "and";
    font-size: clamp(17px, 5.4vw, 24px);
    font-style: italic;
    text-transform: none;
    letter-spacing: 0;
    line-height: 1.5;
  }
  .card-names-lao { font-size: 13px; margin-top: 4px !important; }
  .gold-rule { width: 64px; margin: 1.6svh auto !important; }
  .card-message { font-size: 13px; font-style: normal; text-transform: uppercase; letter-spacing: .14em; line-height: 1.6; max-width: 22ch; }
  .card-message-lao { font-size: 11.5px; line-height: 1.55; }
  .card-date {
    margin-top: 2svh !important;
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    max-width: none;
  }
  .card-date__side { border: 0; padding: 0; font-size: 11px; letter-spacing: .26em; }
  .card-date__day { font-size: clamp(40px, 12vw, 54px); font-weight: 400; line-height: 1.05; }
  .card-time { font-size: 11.5px; font-style: normal; text-transform: uppercase; letter-spacing: .16em; margin-top: 1.2svh !important; }
  .card-venue { font-size: 11.5px; line-height: 1.5; margin-top: 1.4svh !important; }
  .card-venue strong { font-size: 12px; text-transform: uppercase; letter-spacing: .14em; font-weight: 600; }
  .card-rsvp { margin-top: 2.2svh !important; min-height: 40px; padding: .5em 1.6em; font-size: 13px; }
  .card-rsvp__chev { margin-left: .5em; font-size: 1.2em; line-height: 1; }
  .card-rsvp-by { font-size: 11px; }

  /* ---------- Full-screen detail pages ---------- */
  .js .panel {
    left: 0; top: 0;
    width: 100%; height: 100%;
    max-height: none;
    translate: none;
    border-radius: 0;
    outline: none;
    box-shadow: none;
    padding: max(54px, 8.5svh) 26px calc(var(--nav-h) + 9svh);
    color: var(--ink);
    background:
      radial-gradient(ellipse 90% 60% at 50% 25%, rgba(255, 250, 242, .9), transparent 70%),
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .42 0 0 0 0 .29 0 0 0 0 .18 0 0 0 .08 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
      #f3e4d3;
    display: flex; flex-direction: column; justify-content: safe center;
  }
  /* hanging sprig, top-right */
  .js .panel::before {
    content: "";
    position: absolute;
    z-index: 0;
    top: -1svh; right: -12vw;
    width: 46vw; height: 25svh;
    background: url("assets/web/branch-lower-right.webp") center / contain no-repeat;
    rotate: 180deg;
    filter: drop-shadow(-2px -4px 4px rgba(74, 34, 18, .2));
    pointer-events: none;
  }
  /* burgundy + blush wave, bottom */
  .js .panel::after {
    content: "";
    position: absolute;
    z-index: 0;
    left: 0; right: 0; bottom: 0;
    height: 17svh;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 140' preserveAspectRatio='none'%3E%3Cpath d='M0 46C70 18 140 92 230 62S350 22 400 40V140H0Z' fill='%23ead0c3'/%3E%3Cpath d='M0 84C80 58 160 124 260 94S370 64 400 76V140H0Z' fill='%236b1827'/%3E%3Cpath d='M0 84C80 58 160 124 260 94S370 64 400 76' fill='none' stroke='%23cfa35a' stroke-width='1.2'/%3E%3C/svg%3E") bottom / 100% 100% no-repeat;
    pointer-events: none;
  }
  .js .panel > :not(.panel__close) { position: relative; z-index: 1; }
  .js .panel__close { left: 10px; right: auto; top: 10px; z-index: 2; color: var(--burgundy-700); }

  .js .panel .section__head { padding-inline: 8px; }
  .js .panel .eyebrow { color: var(--gold-600); }
  .js .panel .section__title {
    color: var(--burgundy-700);
    text-transform: uppercase;
    letter-spacing: .08em;
    font-weight: 500;
    font-size: clamp(25px, 7.6vw, 34px);
    line-height: 1.15;
  }
  .js .panel .section__lao { color: var(--ink-soft); }

  /* Date page on cream */
  .js .panel .countdown__unit { background: rgba(255, 251, 244, .7); border-color: rgba(181, 134, 60, .55); }
  .js .panel .countdown__label { color: var(--ink-soft); }
  .js .panel .countdown__note { color: var(--ink); }

  /* Schedule: line icons on a dotted spine */
  .js .panel .schedule { max-width: 340px; }
  .js .panel .schedule::before {
    left: 22px; top: 24px; bottom: 30px; width: 1px;
    background: repeating-linear-gradient(to bottom, var(--gold-400) 0 3px, transparent 3px 7px);
  }
  .js .panel .schedule__item {
    grid-template-columns: 44px 1fr;
    grid-template-areas: "icon title" "icon time" "icon lao" "icon desc";
    gap: 0 18px;
    padding-bottom: 2.2svh;
  }
  .js .panel .schedule__item::before { display: none; }
  .js .panel .schedule__item > div { display: contents; }
  .js .panel .schedule__icon {
    grid-area: icon;
    display: grid; place-items: center;
    width: 44px; height: 44px;
    background: #f3e4d3;
    border-radius: 50%;
  }
  .js .panel .schedule__icon svg { width: 34px; height: 34px; fill: none; stroke: var(--gold-600); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
  .js .panel .schedule__title { grid-area: title; font-size: 14px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; }
  .js .panel .schedule__time { grid-area: time; text-align: left; padding: 0; font-size: 14px; color: var(--ink); line-height: 1.5; }
  .js .panel .schedule__lao { grid-area: lao; font-size: 13px; }
  .js .panel .schedule__desc { grid-area: desc; font-size: 14px; color: var(--ink-soft); margin-top: 2px; }

  /* Venue: name as the headline, drawn map, directions button */
  #venue .section__title, #venue .section__lao, #venue .divider { display: none; }
  #venue .section__head { margin-bottom: 6px; }
  .js .panel .venue { background: none; border: 0; outline: 0; box-shadow: none; padding: 0; }
  .js .panel .venue__name { text-transform: uppercase; letter-spacing: .08em; font-size: clamp(24px, 7.4vw, 32px); line-height: 1.15; }
  .venue__map { display: block; width: 100%; max-width: 340px; height: auto; max-height: 28svh; margin: 2svh auto 1svh; }
  .venue__map .m-bg { fill: #f8eee2; stroke: rgba(181, 134, 60, .5); }
  .venue__map .m-river { fill: rgba(181, 134, 60, .16); }
  .venue__map .m-road { fill: none; stroke: #b48a57; stroke-width: 1.6; opacity: .5; stroke-linecap: round; }
  .venue__map .m-road--main { stroke-width: 3.4; opacity: .55; }
  .venue__map .m-road--thin { stroke-width: 1; opacity: .4; }
  .venue__map .m-label { font: italic 11px var(--font-serif); fill: var(--gold-600); letter-spacing: .1em; }
  .venue__map .m-pin path { fill: var(--burgundy-700); }
  .venue__map .m-pin circle { fill: #f8eee2; }
  .js .panel .venue__note { margin: 1svh auto 2svh; }

  /* RSVP: two big choices first, the rest appears after choosing */
  .js .panel .field--attend { order: -1; grid-column: 1 / -1; display: flex; flex-direction: column; gap: 12px; }
  .js .panel .field--attend legend { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .js .panel .field--attend .choice {
    position: relative;
    justify-content: center;
    width: 100%;
    min-height: 50px !important;
    border: 1px solid var(--burgundy-700);
    border-radius: 999px;
    color: var(--burgundy-700) !important;
    font-size: 12.5px !important;
    letter-spacing: .16em !important;
    text-transform: uppercase !important;
    transition: background-color 250ms, color 250ms, box-shadow 250ms;
  }
  .js .panel .field--attend .choice input { position: absolute; opacity: 0; pointer-events: none; }
  .js .panel .field--attend .choice::before {
    content: "";
    width: 14px; height: 14px;
    background: url("assets/web/medallion-diamond.webp") center / contain no-repeat;
  }
  .js .panel .field--attend .choice:has(input[value="yes"]) { background: var(--burgundy-700); color: var(--cream-50) !important; }
  .js .panel .field--attend:has(input[value="no"]:checked) .choice:has(input[value="yes"]) { background: transparent; color: var(--burgundy-700) !important; }
  .js .panel .field--attend .choice:has(input:checked) { background: var(--burgundy-800); color: var(--cream-50) !important; box-shadow: 0 0 0 3px #f3e4d3, 0 0 0 4px var(--gold-400); }
  .js .panel .field--attend .choice:has(input:focus-visible) { outline: 2px solid var(--gold-500); outline-offset: 3px; }
  .js .panel .rsvp:not(:has(input[name="attending"]:checked)) > :not(.field--attend) { display: none; }
  .js .panel .rsvp:has(input[value="no"]:checked) > .field--half { display: none; }
  .js .panel .field label:not(.choice), .js .panel .field legend { color: var(--gold-600); }
  .js .panel .choice { color: var(--ink) !important; }
  .js .panel .field input[type="text"], .js .panel .field select, .js .panel .field textarea { background: #fffaf3; border-color: rgba(181, 134, 60, .55); }
  .js .panel .field__error { color: #a3261b; }
  .js .panel .rsvp__demo-note { color: var(--ink-soft); }
  .js .panel .rsvp-done { background: rgba(255, 251, 244, .6); border-color: rgba(181, 134, 60, .55); }
  .js .panel .rsvp-done__title { color: var(--burgundy-700); }
  .js .panel .rsvp-done__demo { color: var(--ink-soft); background: rgba(181, 134, 60, .08); }
  .js .panel .rsvp-done code { color: var(--burgundy-700); }
  .js .panel .rsvp-done .btn--outline-light { border-color: var(--gold-500); color: var(--burgundy-700); }
}
/* Short phones: trim secondary Lao lines on the card */
@media (max-width: 760px) and (max-height: 760px) {
  .card-lao, .card-message-lao, .card-rsvp-by { display: none; }
  .js .panel::before { height: 20svh; }
}

/* Phone tableau refinements: a narrower two-piece ribbon running down the card's left edge */
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  [data-invite="opening"] .wax-seal-wrap,
  [data-invite="open"] .wax-seal-wrap { --seal: min(27vw, 15svh, 130px); }

  [data-invite="opening"] .ribbon--lower,
  [data-invite="open"] .ribbon--lower {
    height: calc(var(--stage-h) * .6);
    left: 23vw;
    top: calc(var(--stage-h) * .44);
    rotate: 24deg;
    transform-origin: 10% 0%;
  }
  [data-invite="opening"] .ribbon--upper,
  [data-invite="open"] .ribbon--upper {
    z-index: 66;
    height: calc(var(--stage-h) * .58);
    left: 23vw;
    top: calc(var(--stage-h) * -.08);
    rotate: -24deg;
    transform-origin: 0% 100%;
  }
  [data-invite="opening"] .ribbon--upper img,
  [data-invite="open"] .ribbon--upper img { transform: none; opacity: .85; }
  [data-invite="opening"] .ribbon img,
  [data-invite="open"] .ribbon img { opacity: .82; }

  .invitation-card__content { padding-left: 14vw; padding-right: 12vw; }
  .card-names { font-size: clamp(22px, 7vw, 32px); }

  /* Detail pages: smaller corner sprig that stays clear of the headings */
  .js .panel::before { width: 34vw; height: 17svh; top: -1.5svh; right: -9vw; }
  .js .panel .section__head { padding-inline: 34px; }
  .js .panel .countdown__label { font-size: 9.5px; letter-spacing: .12em; }
  .js .panel .schedule__item { padding-bottom: 1.6svh; }
  .js .panel .schedule__desc { font-size: 13.5px; line-height: 1.4; }
  .panel-nav__item[aria-current="true"] { letter-spacing: .02em; }
}
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .invitation-card__content { padding-left: 16vw; padding-right: 12vw; }
}
@media (max-width: 760px) and (max-height: 700px) {
  .invitation-card__content { padding-top: 3svh; padding-bottom: 2svh; }
  .card-eyebrow { font-size: 9px; }
  .card-names { font-size: 22px; margin-top: 1.4svh !important; }
  .card-names__amp::before { font-size: 16px; }
  .card-names-lao { font-size: 12px; }
  .gold-rule { margin: 1.1svh auto !important; }
  .card-message { font-size: 10.5px; letter-spacing: .1em; line-height: 1.5; }
  .card-date { margin-top: 1.2svh !important; }
  .card-date__day { font-size: 34px; }
  .card-date__side { font-size: 9.5px; }
  .card-time, .card-venue { font-size: 10.5px; margin-top: .8svh !important; }
  .card-venue strong { font-size: 11px; }
  .card-rsvp { margin-top: 1.4svh !important; min-height: 36px; font-size: 12px; }
}
@media (max-width: 380px) {
  .panel-nav__item { font-size: 9.5px; letter-spacing: .02em; }
  .panel-nav__replay { width: 34px; flex-basis: 34px; }
}
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  [data-invite="opening"] .ribbon--upper,
  [data-invite="open"] .ribbon--upper { left: 17vw; }
}
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .js .panel .rsvp { width: 100%; }
  /* Once a choice is made, the header compacts so the whole form fits */
  #rsvp:has(input[name="attending"]:checked) .section__head .eyebrow,
  #rsvp:has(input[name="attending"]:checked) .section__head .section__lao,
  #rsvp:has(input[name="attending"]:checked) .section__head .divider,
  #rsvp:has(input[name="attending"]:checked) .rsvp__demo-note { display: none; }
  #rsvp:has(input[name="attending"]:checked) .section__head { margin-bottom: 10px; }
  #rsvp:has(input[name="attending"]:checked) .section__title { font-size: 24px; }
  #rsvp:has(input[name="attending"]:checked) .field--attend { gap: 8px; }
  #rsvp:has(input[name="attending"]:checked) .field--attend .choice { min-height: 42px !important; }
  #rsvp:has(input[name="attending"]:checked) { padding-top: max(44px, 6svh); }
  .js .panel .field textarea { min-height: 44px; height: 44px; }
}

/* Phone pages: footer curve uses the supplied artwork
   Image: assets/web/wave-ribbon.webp (source: ริบบิ้นคลื่นหรูสีเบอร์กันดีแต่งทอง.png) */
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .js .panel::after {
    height: min(34vw, 22svh);
    background: url("assets/web/wave-ribbon.webp") center bottom / 100% auto no-repeat;
    filter: drop-shadow(0 -4px 10px rgba(74, 34, 18, .12));
  }
}
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .js .panel::after {
    height: min(58vw, 26svh);
    background-size: 155% auto;
    background-position: left bottom;
  }
}

/* 16. GALLERY ============================================================== */
.gallery {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  max-width: 760px;
}
.gallery li { margin: 0; }
.gallery__item {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  padding: 0;
  border: 0;
  border-radius: 3px;
  overflow: hidden;
  background: var(--cream-200);
  cursor: zoom-in;
  box-shadow: 0 0 0 1px rgba(181, 134, 60, .45), 0 10px 22px rgba(61, 11, 20, .12);
  transition: transform 450ms var(--ease-lift), box-shadow 450ms var(--ease-silk);
}
.gallery__item::after {                       /* thin inset gold frame over the photo */
  content: "";
  position: absolute; inset: 6px;
  border: 1px solid rgba(241, 220, 170, .7);
  pointer-events: none;
}
.gallery__item:hover { transform: translateY(-3px); box-shadow: 0 0 0 1px var(--gold-400), 0 16px 30px rgba(61, 11, 20, .2); }
.gallery__img { width: 100%; height: 100%; object-fit: cover; }
/* Placeholder frame (no photo yet) */
.gallery__ph {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  background:
    radial-gradient(ellipse at 50% 35%, rgba(255, 250, 242, .9), transparent 70%),
    linear-gradient(160deg, #f1e2cf, #e6cfb4);
  color: var(--gold-600);
}
.gallery__ph img { width: 30%; max-width: 52px; opacity: .85; }
.gallery__ph span { font-size: 12px; letter-spacing: .26em; text-transform: uppercase; }
.gallery__hint { margin: 14px 0 0; font-size: 14px; font-style: italic; color: var(--ink-soft); }

/* Fit the 3×2 grid to the screen height so the panel never scrolls */
.js .panel .gallery { width: min(100%, calc((100dvh - var(--nav-h) - 370px) * .8 * 1.5 + 24px)); }

/* Lightbox */
.lightbox {
  position: fixed; inset: 0;
  z-index: 120;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px;
  padding: max(16px, env(safe-area-inset-top)) 12px max(16px, env(safe-area-inset-bottom));
  background: rgba(30, 4, 9, .94);
  opacity: 0;
  transition: opacity 300ms var(--ease-silk);
}
.lightbox[hidden] { display: none !important; }
.lightbox.is-open { opacity: 1; }
.lightbox__figure { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 14px; min-width: 0; }
.lightbox__frame {
  position: relative;
  width: min(100%, 72vh * .8, 720px);
  aspect-ratio: 4 / 5;
  border: 1px solid rgba(207, 163, 90, .6);
  outline: 1px solid rgba(207, 163, 90, .3);
  outline-offset: 6px;
  background: #241015;
  transform: scale(.97);
  transition: transform 400ms var(--ease-lift);
}
.lightbox.is-open .lightbox__frame { transform: none; }
.lightbox__img { width: 100%; height: 100%; object-fit: contain; }
.lightbox__frame .gallery__ph span { font-size: 14px; }
.lightbox__caption { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; color: var(--gold-200); font-size: 18px; font-style: italic; }
.lightbox__count { font-size: 12px; font-style: normal; letter-spacing: .3em; color: var(--champagne); opacity: .8; }
.lightbox__nav, .lightbox__close {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border: 1px solid rgba(207, 163, 90, .55);
  border-radius: 50%;
  background: rgba(61, 11, 20, .6);
  color: var(--gold-200);
  cursor: pointer;
  transition: background-color 200ms;
}
.lightbox__nav:hover, .lightbox__close:hover { background: var(--burgundy-700); }
.lightbox__nav svg, .lightbox__close svg { width: 22px; height: 22px; }
.lightbox__close { position: absolute; top: max(14px, env(safe-area-inset-top)); right: 14px; }

@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .gallery__item { aspect-ratio: 1; }
  .js .panel .gallery { width: min(100%, calc((100dvh - var(--nav-h) - 9svh - 300px) / 3 * 2 + 10px)); }
  .gallery__hint { font-size: 13px; margin-top: 10px; }
  .gallery__ph span { font-size: 10px; }
  /* Lightbox: arrows sit under the photo on phones */
  .lightbox { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr auto; align-content: center; }
  .lightbox__figure { grid-column: 1 / -1; grid-row: 1; }
  .lightbox__frame { width: min(100%, 64svh * .8); }
  .lightbox__nav--prev { grid-row: 2; justify-self: end; margin-right: 10px; }
  .lightbox__nav--next { grid-row: 2; justify-self: start; margin-left: 10px; }
  /* 7 nav items: tighter labels */
  .panel-nav__item { font-size: 9.5px; letter-spacing: .02em; }
}
@media (max-width: 380px) {
  .panel-nav__item { font-size: 8.8px; letter-spacing: 0; }
  .panel-nav__replay { width: 30px; flex-basis: 30px; }
  .panel-nav { padding: 3px; }
}
@media (max-width: 760px) and (max-height: 720px) {
  .gallery__hint { display: none; }
}
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .panel-nav { gap: 0; padding: 3px; }
  .panel-nav__item { padding: 0; text-overflow: clip; }
  .panel-nav__item[aria-current="true"] { font-weight: 500; letter-spacing: 0; }
  .panel-nav__replay { width: 32px; flex: 0 0 32px; margin-left: 2px; }
}
