/* ==========================================================================
   Jennifer & Benjie — Wedding
   styles.css
   ========================================================================== */

/* ---------- 1. TOKENS ---------- */
:root{
  /* palette */
  --bg:            #F8F1E5;
  --fg:            #14284B;
  --accent:        #92515B;   /* rose gold */
  --ivory:         #FFF9EF;
  --header-green:  #8E4E58;   /* rose gold on ivory */

  /* derived (foreground at opacity) */
  --fg-70: rgba(20,40,75,.70);
  --fg-60: rgba(20,40,75,.60);
  --fg-50: rgba(20,40,75,.50);
  --fg-40: rgba(20,40,75,.40);
  --fg-20: rgba(20,40,75,.20);
  --fg-15: rgba(20,40,75,.15);
  --fg-10: rgba(20,40,75,.10);
  --fg-03: rgba(20,40,75,.03);

  /* type */
  --font-display: "Cormorant Garamond", "Times New Roman", serif;
  --font-script:  "Pinyon Script", cursive;
  --font-body:    "Jost", "Helvetica Neue", Arial, sans-serif;

  --fs-display-xl: clamp(3.5rem, 12vw, 8rem);
  --fs-display-lg: clamp(2.75rem, 8vw, 4.5rem);
  --fs-display-md: clamp(2.25rem, 6.5vw, 3.75rem);
  --fs-display-sm: clamp(2rem, 5.5vw, 3rem);

  /* layout */
  --section-y: clamp(5rem, 12vw, 7rem);
  --radius:    1rem;

  /* motion */
  --ease:      cubic-bezier(.22,.61,.36,1);
  --ease-soft: cubic-bezier(.16,.84,.32,1);   /* longer, gentler settle */
}

/* ---------- 2. RESET ---------- */
*,*::before,*::after{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
::selection{ background:var(--ivory, #f3ead9); color:inherit; }
::-moz-selection{ background:var(--ivory, #f3ead9); color:inherit; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body{
  margin:0;
  background:var(--bg);
  color:var(--fg);
  font-family:var(--font-body);
  font-weight:300;
  line-height:1.6;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
}
img,video,svg{ display:block; max-width:100%; }
h1,h2,h3,p,figure,fieldset,legend{ margin:0; padding:0; }
fieldset{ border:0; min-width:0; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
a{ color:inherit; }
:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:4px; }

/* ---------- 3. TYPE HELPERS ---------- */
.display{
  font-family:var(--font-display);
  font-weight:400;
  font-size:var(--fs-display-lg);
  line-height:1.05;
  letter-spacing:.01em;
}
.display--md{ font-size:var(--fs-display-md); }
.display--sm{ font-size:var(--fs-display-sm); }

/* section headers (Countdown, The Celebrations, Our Day, etc.) */
h2.display{
  font-family:var(--font-script);
  color:var(--header-green);
  letter-spacing:normal;
}

.eyebrow{
  font-size:.8125rem;
  letter-spacing:.25em;
  text-transform:uppercase;
  color:var(--fg-50);
}
.muted{ color:var(--fg-50); }
.small{ font-size:.875rem; }
.center{ text-align:center; }
.lead{
  font-size:clamp(1.125rem,2.5vw,1.35rem);
  font-style:italic;
  color:var(--fg-70);
  line-height:1.7;
  margin-bottom:1rem;
}
.date-line{ font-style:italic; color:var(--fg-60); letter-spacing:.02em; }
.attire{ font-size:1.125rem; letter-spacing:.1em; }
.note{
  max-width:19rem; margin:.75rem auto 0;
  font-style:italic; color:var(--fg-60);
}

.link-underline{
  display:inline-block; margin-top:1.25rem;
  font-size:.875rem; letter-spacing:.15em; text-transform:uppercase;
  color:var(--fg-50); text-decoration:none;
  border-bottom:1px solid var(--fg-20); padding-bottom:.25rem;
  transition:color .25s, border-color .25s;
}
.link-underline:hover{ color:var(--fg); border-color:var(--fg-50); }

/* ---------- 4. LAYOUT ---------- */
.section{ position:relative; padding:var(--section-y) 1.5rem; overflow:hidden; }
.wrap{ margin-inline:auto; width:100%; }
.wrap--sm{ max-width:36rem; }
.wrap--md{ max-width:42rem; }
.wrap--lg{ max-width:52rem; }

.stack-md > * + *{ margin-top:2rem; }
.stack-lg > * + *{ margin-top:3rem; }

.rule{
  width:2.5rem; height:1px; margin:0 auto;
  border:0; background:var(--fg-15);
}
.rule--tight{ margin:1.25rem auto; }

/* full-bleed photo dividers between sections — shown at their own
   natural size (landscape), never cropped or forced to a fixed height */
.divider-photo{
  width:100%;
  line-height:0;
}
.divider-photo__img{
  display:block;
  width:100%;
  height:auto;
}

.card{
  background:var(--fg-03);
  border:1px solid var(--fg-10);
  border-radius:var(--radius);
  padding:clamp(2rem,6vw,3.5rem) clamp(1.5rem,5vw,2.5rem);
}
.card .eyebrow{ margin-bottom:.75rem; }
.card .display--md{ margin-bottom:.5rem; }

/* cards with a photo background holder — the image sits behind the
   content with a soft scrim over it for legibility. If the file is
   missing, [data-optional] hides it and the card just shows its
   normal solid background, so nothing ever looks broken. */
.card--photo{ position:relative; overflow:hidden; }
.card__bg{ position:absolute; inset:0; z-index:0; }
.card__bg-img{ width:100%; height:100%; object-fit:cover; display:block; }
.card__bg::after{
  content:''; position:absolute; inset:0;
  background:var(--bg); opacity:.2;
}
.card--photo > *:not(.card__bg){ position:relative; z-index:1; }

/* decorative art */
.deco{ pointer-events:none; user-select:none; -webkit-user-select:none; }
.deco--inline{ margin-inline:auto; }

/* white rose corner sprays */
.corner{ position:absolute; z-index:0; width:clamp(8rem,28vw,13rem); }
.corner--tl{ top:-1rem; left:-2.5rem; }
.corner--br{ bottom:-1rem; right:-2.5rem; }
.corner--faint{ opacity:.45; }
.footer{ position:relative; overflow:hidden; }
.footer > *:not(.corner){ position:relative; z-index:1; }

/* ---------- 4b. INTRO GATE ---------- */
body.is-locked{ overflow:hidden; }

.intro{
  position:fixed; inset:0; z-index:200;
  display:flex; align-items:center; justify-content:center;
  background:#000; cursor:pointer;
  transition:opacity .8s cubic-bezier(.4,0,.2,1);
}
.intro__video{
  width:100%; height:100%; object-fit:cover;
}
.intro__pulse{
  position:absolute;
  width:4.5rem; height:4.5rem; border-radius:50%;
  border:1px solid rgba(255,255,255,.5);
  transition:opacity .4s ease;
  animation:introPulse 2.4s ease-out infinite;
}
.intro__pulse::after{
  content:""; position:absolute; inset:calc(50% - .1875rem);
  border-radius:50%; background:rgba(255,255,255,.85);
}
@keyframes introPulse{
  0%   { transform:scale(.85); opacity:.9; }
  70%  { transform:scale(1.4);  opacity:0;  }
  100% { transform:scale(1.4);  opacity:0;  }
}
.intro.is-playing .intro__pulse{ opacity:0; }
.intro.is-out{ opacity:0; pointer-events:none; }

@media(prefers-reduced-motion:reduce){
  .intro__pulse{ animation:none; opacity:.8; }
}

/* ---------- 4c. TRANSITION VIDEO ---------- */
/* Plays once, right after the intro video ends, then dissolves into the
   hero underneath. No loop; skips itself instantly if the file is
   missing or reduced motion is requested. */
.vgate{
  position:fixed; inset:0; z-index:150; overflow:hidden;
  background:#000;
  transition:opacity 1300ms cubic-bezier(.4,0,.2,1);
}
.vgate[hidden]{ display:none; }
.vgate.is-out{ opacity:0; }
.vgate__video{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
}

/* the site itself eases in behind the gate — a soft blur-to-focus
   crossfade so the handoff from video to static hero feels continuous
   rather than a hard cut. */
main.fg-enter{
  transform:scale(.965); opacity:0; filter:blur(14px);
  transition:
    transform 2600ms cubic-bezier(.30,.72,.22,1),
    opacity 2000ms ease-out,
    filter 2200ms ease-out;
}
main.fg-enter.is-in{ transform:none; opacity:1; filter:blur(0); }

/* poster keeps drifting inward for a few seconds after it appears, so
   the stillness of the photo doesn't feel abrupt right after video */
main.fg-enter .hero__poster{
  transform:scale(1.07);
  transition:transform 3400ms cubic-bezier(.16,.84,.32,1);
}
main.fg-enter.is-in .hero__poster{ transform:scale(1); }

/* scroll cue settles in last, once everything else has landed. Color
   is listed too (0 delay) so hover feedback stays instant afterwards —
   main.fg-enter never gets removed, so this rule stays in effect. */
main.fg-enter .hero__scroll{
  opacity:0; transform:translateY(10px);
  transition:
    opacity 900ms ease-out 1500ms,
    transform 900ms ease-out 1500ms,
    color .25s ease 0s;
}
main.fg-enter.is-in .hero__scroll{ opacity:1; transform:none; }

@media(prefers-reduced-motion:reduce){
  main.fg-enter,
  main.fg-enter .hero__poster,
  main.fg-enter .hero__scroll{ transition-duration:1ms !important; filter:none !important; }
}

@media (prefers-reduced-motion:reduce){
  .vgate{ transition-duration:420ms !important; }
}

/* ---------- 4d. FALLING LEAVES ---------- */
/* Fixed over the full viewport (not the document), so the leaves drift
   over whatever section is currently in view as the guest scrolls.
   Populated by initLeaves() in script.js — pale sage green, inline SVG. */
.leaves{
  position:fixed; inset:0;
  z-index:30;
  overflow:hidden;
  pointer-events:none;
}
.leaf{
  position:absolute;
  top:-8%;
  width:var(--leaf-size);
  height:var(--leaf-size);
  animation:leafFall var(--leaf-dur) linear infinite;
  animation-delay:var(--leaf-delay);
  will-change:transform;
}
.leaf__sway{
  width:100%; height:100%;
  animation:leafSway var(--sway-dur) ease-in-out infinite alternate;
  animation-delay:var(--sway-delay);
}
.leaf__sway svg{
  width:100%; height:100%;
  filter:drop-shadow(0 3px 4px rgba(20,40,75,.10));
}
@keyframes leafFall{
  0%   { transform:translate3d(0,0,0) rotate(0deg); }
  25%  { transform:translate3d(calc(var(--drift) * .35), 27vh, 0) rotate(90deg); }
  50%  { transform:translate3d(calc(var(--drift) * -.25), 56vh, 0) rotate(180deg); }
  75%  { transform:translate3d(calc(var(--drift) * .45), 85vh, 0) rotate(270deg); }
  100% { transform:translate3d(calc(var(--drift) * -.15), 118vh, 0) rotate(360deg); }
}
@keyframes leafSway{
  0%   { transform:rotate(-16deg) translateX(-6px); }
  100% { transform:rotate(16deg) translateX(6px); }
}
@media(prefers-reduced-motion:reduce){
  .leaves{ display:none; }
}

/* ---------- 5. HERO ---------- */
.hero{
  position:relative;
  min-height:100svh;
  display:flex; flex-direction:column; justify-content:flex-end;
  overflow:hidden; background:#000;
}
.hero__media{ position:absolute; inset:0; overflow:hidden; }
.hero__poster{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
}
.hero__scrim{
  position:absolute; inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,.10) 0%,rgba(0,0,0,0) 35%,rgba(0,0,0,.42) 100%);
}

.hero__scroll{
  position:relative; z-index:10;
  display:flex; flex-direction:column; align-items:center; gap:.25rem;
  padding-bottom:2.5rem; color:rgba(255,255,255,.8);
  transition:color .25s;
}
.hero__scroll:hover{ color:#fff; }
.hero__scroll span{
  font-size:.75rem; font-weight:600;
  letter-spacing:.3em; text-transform:uppercase;
  text-shadow:0 2px 8px rgba(0,0,0,.4);
}
.hero__chevron{
  width:1.25rem; height:1.25rem; margin-top:.25rem;
  animation:bob 2s var(--ease) infinite;
}
@keyframes bob{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(6px) } }

/* ---------- 5b. PHOTO STRIP (no title, sits under the hero) ---------- */
/* Auto-scrolls infinitely — script.js clones the track once so the
   loop is seamless, then this animation slides it exactly -50%. */
.photostrip{
  background:var(--bg);
  padding:.75rem 0;
  overflow:hidden;
}
.photostrip__track{
  display:flex; gap:.75rem;
  width:max-content;
  animation:photostripScroll 32s linear infinite;
  transform:translate3d(0,0,0);
}
/* Once JS takes over the scroll it drives transform in pixels — iOS
   Safari drops the composited layer on very wide percentage-based
   marquees, which is what made the strip vanish there. */
.photostrip__track.is-js{ animation:none; }
.photostrip__img{
  flex:none;
  height:clamp(15rem, 62vw, 26rem);
  width:auto; max-width:none;
  object-fit:cover;
  border-radius:calc(var(--radius) * .5);
  box-shadow:0 6px 20px rgba(20,40,75,.10);
}
@keyframes photostripScroll{
  from{ transform:translate3d(0,0,0); }
  to{ transform:translate3d(-50%,0,0); }
}
@media (min-width:900px){
  .photostrip__img{ height:clamp(20rem, 28vw, 30rem); }
}
@media (prefers-reduced-motion: reduce){
  .photostrip__track{ animation:none; }
  .photostrip{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
}

/* ---------- 5c. PRENUP VIDEO ---------- */
.prenup__frame{
  position:relative;
  border-radius:var(--radius); overflow:hidden;
  box-shadow:0 12px 34px rgba(20,40,75,.14);
  background:var(--fg-03);
}
.prenup__video{
  display:block; width:100%; aspect-ratio:16/10;
  object-fit:cover; background:var(--fg-03);
}
/* Tap-to-play — only appears when the browser blocks autoplay (iOS Low
   Power Mode is the usual culprit). initPrenupVideo() adds .is-blocked. */
.prenup__play{
  position:absolute; inset:0; z-index:2;
  display:none; align-items:center; justify-content:center;
  width:100%; background:rgba(20,40,75,.18);
}
.prenup__frame.is-blocked .prenup__play{ display:flex; }
.prenup__play svg{
  width:3.25rem; height:3.25rem; padding:.9rem;
  border-radius:50%; color:var(--fg);
  background:rgba(255,255,255,.92);
  box-shadow:0 6px 18px rgba(20,40,75,.22);
}

/* ---------- 6. COUNTDOWN ---------- */
.countdown__column{
  position:absolute; top:-1%; height:100%; width:auto; max-width:none;
  opacity:.9;
}
.countdown__column--left{ left:-8%; }
.countdown__column--right{ right:-8%; }
.countdown .wrap{ position:relative; z-index:10; }

/* white rose arch — dense frame around the opening panel */
.arch{ position:absolute; z-index:1; }
.arch--top{
  top:0; left:50%; margin-left:-60vw;
  width:120vw; max-width:none;
}
.arch--l, .arch--r{ top:0; width:clamp(6rem,24vw,13rem); }
.arch--l{ left:0; }
.arch--r{ right:0; }
@media(min-width:768px){
  .arch--top{ margin-left:-45rem; width:90rem; }
}
.countdown .display{ margin-bottom:.5rem; }
.countdown .eyebrow{ margin-bottom:3rem; }

.countdown__grid{ display:flex; align-items:center; justify-content:center; }
.countdown__unit{
  display:flex; flex-direction:column; align-items:center;
  padding-inline:clamp(1rem,4vw,2rem);
}
.countdown__value{
  font-family:var(--font-display);
  font-size:var(--fs-display-lg); line-height:1;
  font-variant-numeric:tabular-nums;
}
.countdown__label{
  margin-top:.75rem; font-size:.75rem;
  letter-spacing:.25em; text-transform:uppercase; color:var(--fg-50);
}
.countdown__rule{ width:1px; height:2rem; background:var(--fg-15); }

/* ---------- 7. CELEBRATIONS ---------- */
.event__art{ position:relative; z-index:2; display:flex; justify-content:center; }
.event__img--chapel{ width:clamp(12rem,40vw,16rem); margin-bottom:-1.5rem; }
.event__img--venue{ width:clamp(14rem,46vw,18rem); margin-bottom:-2rem; }
.event .card{ position:relative; z-index:1; }

.notice{
  display:flex; align-items:flex-start; gap:.625rem;
  max-width:20rem; margin:2rem auto 0; padding-top:1.5rem;
  border-top:1px solid var(--fg-10);
  text-align:left; font-size:.875rem; font-style:italic;
  line-height:1.55; color:var(--fg-60);
}
.notice svg{ width:1.125rem; height:1.125rem; flex:none; margin-top:.15rem; color:var(--accent); }

/* ---------- 8. ITINERARY ---------- */
.itinerary{ padding-inline:1.5rem; }
.curtain{
  position:absolute; max-width:none; z-index:3;
}
.curtain--left { top:2%; left:0;  width:50%; transform-origin:left top; }
.curtain--right{ top:2%; right:0; width:50%; transform-origin:right top; }
.curtain--center{
  top:2.2%; left:50%; width:68%; height:auto; z-index:4;
  transform-origin:center top; transform:translateX(-50%);
}
@media(min-width:768px){
  .curtain--left,.curtain--right{ width:32%; }
  .curtain--center{ width:50%; }
}

.itinerary__inner{
  position:relative; z-index:5;
  max-width:17rem; margin-inline:auto;
  padding-top:clamp(8rem,20vw,11rem);
}
.itinerary__day{ position:relative; }
.itinerary__day + .itinerary__day{ margin-top:4rem; }
.itinerary__day .muted{ margin-bottom:1rem; }
.itinerary__vase{
  position:absolute; right:-3rem; bottom:-1rem; width:9rem;
}

.timeline{
  position:relative; list-style:none;
  max-width:17.5rem; margin:0 auto; padding:0 0 0 1.75rem;
}
.timeline__item{ position:relative; }
.timeline__item + .timeline__item{ margin-top:1.5rem; }
.timeline__item::before{           /* dot */
  content:""; position:absolute; left:-1.7rem; top:.35rem;
  width:.5rem; height:.5rem; border-radius:50%;
  background:rgba(20,40,75,.3);
}
.timeline__item:not(:last-child)::after{  /* connecting line */
  content:""; position:absolute; left:-1.48rem; top:.5rem;
  width:1px; height:calc(100% + 1.5rem); background:var(--fg-15);
}
.timeline__time{
  font-size:.875rem; font-weight:600;
  letter-spacing:.15em; text-transform:uppercase;
  color:var(--fg-70); margin-bottom:.25rem;
}
.timeline__text{ letter-spacing:.05em; }
.timeline__text--soft{ color:var(--fg-50); font-style:italic; }

/* ---------- 9. DRESS CODE ---------- */
.dresscode__split{
  display:grid; gap:1.75rem;
}
.dresscode__split .eyebrow{ margin-bottom:.35rem; }
@media(min-width:520px){
  .dresscode__split{ grid-template-columns:1fr 1fr; gap:1.5rem; }
}

.dresscode{ position:relative; }
.dresscode > .reveal{ position:relative; z-index:2; }
.dresscode__bouquet{
  position:absolute; top:2rem; left:-2.5rem;
  width:clamp(11rem,30vw,13rem); z-index:3;
}
.dresscode__stand{
  position:absolute; top:45%; right:-3rem;
  width:clamp(7rem,20vw,9rem); z-index:3;
}
.dresscode__cypress{
  position:absolute; bottom:-4rem; left:-2rem;
  width:clamp(9rem,26vw,12rem); z-index:3;
}
@media(min-width:768px){
  .dresscode__bouquet{ left:-4rem; }
  .dresscode__stand{ right:-5rem; }
  .dresscode__cypress{ left:-4rem; }
}

/* motif swatches */
.swatches{
  list-style:none; margin:1.25rem 0 0; padding:0;
  display:grid; grid-template-columns:1fr 1fr; gap:1rem .75rem;
  font-size:.8125rem; letter-spacing:.06em; color:var(--fg-60);
}
.swatch{ display:flex; flex-direction:column; align-items:center; gap:.5rem; }
.swatch__chip{
  width:2.75rem; height:2.75rem; border-radius:50%;
  border:1px solid var(--fg-10);
  box-shadow:0 4px 12px rgba(20,40,75,.08);
}
@media(min-width:520px){
  .swatches{ grid-template-columns:repeat(4,1fr); }
}

/* attire reference photos */
.attire-guide{
  display:grid; grid-template-columns:1fr 1fr; gap:1rem;
  margin-top:2rem;
}
.attire-fig{ margin:0; }
.attire-fig__frame{
  position:relative; overflow:hidden;
  aspect-ratio:3 / 4; border-radius:var(--radius);
  background:var(--ivory); border:1px solid var(--fg-10);
}
.attire-fig__frame img{
  display:block; width:100%; height:100%; object-fit:contain;
}
.attire-fig__cap{
  margin-top:.875rem;
  font-size:.6875rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--fg-50);
}
@media(min-width:520px){
  .attire-guide{ gap:1.5rem; }
}

/* ---------- 10. ENTOURAGE (printed-program layout) ---------- */
/* Ported from the Cory & Rose entourage: two <ul> columns, the left one
   right-aligned and the right one left-aligned, with every name forced onto a
   single line. The nowrap is the whole trick — a name that wraps to two lines
   is what knocks the left and right columns out of step. Columns are
   overflow:visible so a very long name spills OUTWARD, away from its partner,
   instead of into the gutter between them. */
.ent{ max-width:860px; margin-inline:auto; }

.ent__card{
  padding:clamp(1.5rem,5vw,2.5rem) clamp(1.25rem,5vw,2.75rem);
}
.ent__card .ent__group:first-child{ margin-top:0; }

.ent__group{ margin-top:clamp(1.25rem,3vw,2rem); text-align:center; }
.ent__group--tight{ margin-top:clamp(.5rem,1.4vw,.85rem); }

.ent__label{
  font-family:var(--font-display); font-style:italic; font-weight:400;
  font-size:clamp(1.5rem,4.2vw,2rem); line-height:1.45;
  color:var(--fg); margin-bottom:.6rem; padding-block:.1em;
}
.ent__label--plain{
  font-family:var(--font-body); font-size:.6875rem;
  letter-spacing:.22em; text-transform:uppercase;
  color:var(--fg-70); margin-bottom:.4rem;
}

.ent__names li,
.ent__duo li{
  font-family:var(--font-display);
  font-size:clamp(.82rem,1.9vw,.95rem);
  font-weight:600; color:var(--fg-70);
  line-height:1.75; white-space:nowrap;
}
.ent__group--featured .ent__duo li{ font-size:clamp(1.02rem,2.6vw,1.28rem); }

.ent__names{ list-style:none; margin:0; padding:0; }

.ent__duo{
  display:grid; grid-template-columns:1fr 1fr;
  gap:0 clamp(1rem,4vw,2.6rem); overflow:visible;
}
.ent__duo ul{ list-style:none; margin:0; padding:0; }
.ent__duo .ent__head{
  font-family:var(--font-body); font-size:.6875rem;
  letter-spacing:.22em; text-transform:uppercase;
  color:var(--fg-70); margin-bottom:.4rem;
}
.ent__duo .col-l{ text-align:right; overflow:visible; }
.ent__duo .col-r{ text-align:left;  overflow:visible; }

@media (max-width:520px){
  .ent__duo{ gap:0 .8rem; }
  .ent__names li,
  .ent__duo li{ font-size:.74rem; line-height:1.85; }
  .ent__group--featured .ent__duo li{ font-size:clamp(.92rem,3.4vw,1.05rem); }
  .ent__duo .ent__head,
  .ent__label--plain{ font-size:.62rem; letter-spacing:.14em; }
}

/* gift registry QR codes */
.qr-grid{
  display:grid; grid-template-columns:1fr 1fr; gap:1.25rem;
  max-width:22rem; margin:2.25rem auto 0;
}
.qr-fig{ margin:0; }
.qr-fig__frame{
  position:relative; overflow:hidden;
  aspect-ratio:1 / 1; border-radius:var(--radius);
  background:#fff; border:1px solid var(--fg-10);
  padding:.75rem;
}
.qr-fig__frame img{
  display:block; width:100%; height:100%; object-fit:contain;
}
.qr-fig__cap{
  margin-top:.75rem; text-align:center;
  font-size:.6875rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--fg-50);
}

/* ---------- 10b. GIFT ---------- */
.gift{ position:relative; }
.gift .card{ position:relative; z-index:2; }
.gift__roses{ position:absolute; z-index:3; width:clamp(9rem,26vw,11rem); }
.gift__roses--tl{ top:-2rem; left:-3rem; }
.gift__roses--br{ bottom:-2rem; right:-3rem; }
@media(min-width:768px){
  .gift__roses--tl{ left:-4rem; }
  .gift__roses--br{ right:-4rem; }
}

/* ---------- 10b-2. PHOTO SHARING ---------- */
.photoshare{ position:relative; }
.soon-badge{
  display:inline-block; margin-bottom:1.25rem;
  padding:.4rem 1rem; border-radius:999px;
  background:var(--fg-03); border:1px solid var(--fg-15);
  font-size:.625rem; letter-spacing:.22em; text-transform:uppercase;
  color:var(--fg-60);
}
.reminders{
  list-style:none; margin:1.5rem 0 0; padding:0;
  display:flex; flex-direction:column; gap:1rem;
  text-align:left;
}
.reminder{
  display:flex; align-items:flex-start; gap:.75rem;
  font-size:.9375rem; line-height:1.6; color:var(--fg-70);
}
.reminder svg{
  width:1.125rem; height:1.125rem; flex:none;
  margin-top:.2rem; color:var(--accent);
}
@media(min-width:768px){
  .reminders{ max-width:30rem; margin-inline:auto; }
}

/* ---------- 10c. FAQ ---------- */
/* Each question is its own rounded card (not a bordered list) with a
   circular plus-icon badge that rotates into an "×" on expand — ported
   from the Friendell & Cha FAQ reference. */
.faq-list{ display:flex; flex-direction:column; gap:.9rem; }
.faq-item{
  background:var(--fg-03);
  border:1px solid var(--fg-10);
  border-radius:1.25rem;
  overflow:hidden;
}

.faq-item__q{
  width:100%; display:flex; align-items:center; justify-content:space-between;
  gap:1rem; padding:1.25rem 1.5rem; text-align:left;
  font-family:var(--font-body); font-size:1rem; font-weight:500;
  letter-spacing:.01em; color:var(--fg);
}
.faq-item__q > span{ min-width:0; overflow-wrap:break-word; }

.faq-item__icon{
  flex:none; width:2.25rem; height:2.25rem; border-radius:50%;
  background:var(--ivory);
  display:flex; align-items:center; justify-content:center;
}
.faq-item__plus{
  width:1rem; height:1rem; color:var(--accent);
  transition:transform .3s var(--ease);
}
.faq-item__q[aria-expanded="true"] .faq-item__plus{ transform:rotate(45deg); }

.faq-item__a{
  display:grid; grid-template-rows:0fr; grid-auto-rows:0fr; overflow:hidden;
  visibility:hidden;
  transition:grid-template-rows .35s var(--ease-soft), grid-auto-rows .35s var(--ease-soft), visibility 0s linear .35s;
}
.faq-item__a > *{ min-height:0; }
.faq-item__a > p{
  min-height:0; overflow-wrap:break-word;
  padding:0 1.5rem 1.375rem; padding-right:2rem;
  color:var(--fg-70); font-size:.9375rem; line-height:1.65;
}
.faq-hashtag{
  font-weight:500; letter-spacing:.02em;
  color:var(--header-green);
  white-space:nowrap;
}
.faq-item__q[aria-expanded="true"] + .faq-item__a{
  grid-template-rows:1fr; grid-auto-rows:auto; visibility:visible;
  transition:grid-template-rows .35s var(--ease-soft), visibility 0s linear 0s;
}

/* no-JS fallback: keep every answer readable */
.no-js .faq-item__a{ display:block; grid-template-rows:none; visibility:visible; }

/* ---------- 11. RSVP FORM ---------- */
.form > * + *{ margin-top:2rem; }
.field__label{
  display:block; font-weight:500;
  letter-spacing:.02em; color:var(--fg);
}
.field__label--icon{ display:flex; align-items:center; gap:.5rem; }
.field__label--icon svg{ width:1rem; height:1rem; color:var(--fg-50); flex:none; }

.hp{ position:absolute; left:-9999px; opacity:0; height:0; overflow:hidden; }

.choices{ display:flex; flex-direction:column; gap:.75rem; margin-top:.75rem; }
.choices--tight{ gap:.5rem; }

.choice{ display:flex; align-items:flex-start; gap:.625rem; cursor:pointer; }
.choice input{ position:absolute; opacity:0; width:0; height:0; }
.choice__dot,.choice__box{
  flex:none; width:1rem; height:1rem; margin-top:.3rem;
  border:1px solid var(--fg-20); background:transparent;
  transition:background .2s, border-color .2s;
}
.choice__dot{ border-radius:50%; position:relative; }
.choice__dot::after{
  content:""; position:absolute; inset:.25rem;
  border-radius:50%; background:var(--fg);
  transform:scale(0); transition:transform .18s var(--ease);
}
.choice input:checked ~ .choice__dot{ border-color:var(--fg); }
.choice input:checked ~ .choice__dot::after{ transform:scale(1); }

.choice__box{ border-radius:.25rem; position:relative; }
.choice__box::after{
  content:""; position:absolute; left:.28rem; top:.08rem;
  width:.28rem; height:.55rem; border:solid var(--bg);
  border-width:0 1.5px 1.5px 0; transform:rotate(45deg) scale(0);
  transition:transform .18s var(--ease);
}
.choice input:checked ~ .choice__box{ background:var(--fg); border-color:var(--fg); }
.choice input:checked ~ .choice__box::after{ transform:rotate(45deg) scale(1); }
.choice input:focus-visible ~ .choice__dot,
.choice input:focus-visible ~ .choice__box{ outline:2px solid var(--accent); outline-offset:2px; }
.choice__text{ line-height:1.5; }

.search{ position:relative; margin-top:.75rem; }
.search__icon{
  position:absolute; left:.75rem; top:50%; transform:translateY(-50%);
  width:1.125rem; height:1.125rem; color:var(--fg-40); pointer-events:none;
}
.search__input{ padding-left:2.25rem; }

.search__results{
  list-style:none; margin:.5rem 0 0; padding:.35rem;
  background:var(--bg); border:1px solid var(--fg-15); border-radius:.75rem;
  max-height:14rem; overflow-y:auto;
  box-shadow:0 8px 24px rgba(20,40,75,.08);
}
.search__result{
  padding:.625rem .75rem; border-radius:.5rem;
  font-size:.9375rem; cursor:pointer;
  transition:background .15s;
}
.search__result:hover,
.search__result.is-active{ background:var(--fg-03); }
.search__result mark{ background:none; color:inherit; font-weight:700; }
.search__result--empty{ color:var(--fg-50); cursor:default; font-style:italic; }
.search__result--empty:hover{ background:none; }

.input{
  width:100%; padding:.625rem .75rem;
  background:transparent; color:var(--fg);
  border:1px solid var(--fg-20); border-radius:.5rem;
  font-family:inherit; font-size:1rem;
  transition:border-color .2s;
}
.input::placeholder{ color:var(--fg-40); }
.input:focus{ outline:none; border-color:var(--fg-50); }
.input:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
.input--area{ min-height:6.25rem; margin-top:.5rem; resize:vertical; }
.input.is-invalid{ border-color:#B4462F; }
.input.is-valid{ border-color:#3F6B4F; }
.input.is-checking{ border-color:var(--fg-30, var(--fg-20)); opacity:.75; }

.guest__hint{
  display:flex; align-items:center; gap:.4em;
  margin:.5rem 0 0; font-size:.8125rem; line-height:1.4;
}
.guest__hint[data-state="valid"]{ color:#3F6B4F; }
.guest__hint[data-state="invalid"]{ color:#B4462F; }
.guest__hint[data-state="checking"]{ color:var(--fg-50); }

.form__submit{ position:relative; }
.form__vase{
  position:absolute; bottom:-10rem; width:clamp(9rem,26vw,12rem); z-index:2;
}
.form__vase--l{ left:-5rem; }
.form__vase--r{ right:-5rem; }
@media(min-width:768px){
  .form__vase--l{ left:-8rem; }
  .form__vase--r{ right:-8rem; }
}

.btn{
  position:relative; z-index:3; width:100%;
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  padding:1.125rem 1rem; border-radius:.5rem;
  background:var(--fg); color:var(--bg);
  border:1px solid rgba(183,110,121,.3);
  font-size:.875rem; letter-spacing:.15em; text-transform:uppercase;
  transition:background .25s, opacity .25s;
}
.btn svg{ width:1rem; height:1rem; flex:none; }
.btn:hover:not(:disabled){ background:rgba(20,40,75,.9); }
.btn:disabled{ opacity:.5; cursor:not-allowed; }
.btn--cta{ width:auto; margin-top:1.75rem; padding-left:2.75rem; padding-right:2.75rem; }

.thanks{ padding:2rem 0; }
.thanks__mark{ width:5rem; margin:0 auto 1.5rem; }
.thanks .display--md{ margin-bottom:.75rem; }

/* ---------- 11b. RSVP STANDALONE PAGE ---------- */
/* RSVP now lives on its own page (rsvp.html) instead of a modal —
   the "RSVP Now" button on the homepage is a plain link to it. */
.rsvp-page{
  position:relative;
  min-height:100vh;
  display:flex; align-items:center;
  padding-block:4rem;
}
.rsvp-page__back{
  display:inline-block; margin-bottom:2rem;
  font-size:.875rem;
}

/* ---------- 12. FOOTER ---------- */
.footer{ padding:5rem 1.5rem; }
.footer__mark{ width:6rem; margin:0 auto 2rem; }
.footer .display--md{ margin-bottom:1rem; }
.footer__amp{
  font-size:.6em; font-style:italic; color:var(--fg-50);
}
.credit{ margin-top:4rem; font-size:.875rem; color:var(--fg-40); }
.credit a{ text-decoration:underline; text-underline-offset:2px; transition:color .25s; }
.credit a:hover{ color:var(--fg); }

/* ---------- 13. SOUND TOGGLE ---------- */
/* smoother interactive transitions */
.link-underline, .btn, .stepper__btn, .choice__dot, .choice__box, .input{
  transition:all .45s var(--ease-soft);
}

.sound{
  position:fixed; right:1.5rem; bottom:1.5rem; z-index:40;
  width:3rem; height:3rem; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:rgba(251,245,243,.9);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  border:1px solid var(--fg-10);
  box-shadow:0 8px 24px rgba(20,40,75,.12);
  transition:transform .3s var(--ease), background .3s;
}
.sound:hover{ transform:scale(1.1); background:var(--ivory); }
.sound svg{ width:1.25rem; height:1.25rem; }
.sound__on{ display:none; }
.sound.is-on .sound__off{ display:none; }
.sound.is-on .sound__on{ display:block; }

/* ---------- 14. TOASTS ---------- */
.toasts{
  position:fixed; left:50%; bottom:5.5rem; z-index:100;
  transform:translateX(-50%);
  display:flex; flex-direction:column; gap:.5rem;
  width:min(24rem,calc(100vw - 2rem));
  pointer-events:none;
}
.toast{
  padding:.875rem 1rem; border-radius:.625rem;
  background:var(--fg); color:var(--bg);
  font-size:.875rem; line-height:1.45;
  box-shadow:0 10px 30px rgba(20,40,75,.2);
  opacity:0; transform:translateY(10px);
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.toast.is-in{ opacity:1; transform:translateY(0); }
.toast--error{ background:#8E2F1E; }

/* ---------- 15. SCROLL REVEAL ---------- */
.reveal{
  opacity:0; transform:translateY(28px) scale(.985);
  transition:opacity 1.1s var(--ease-soft),
             transform 1.1s var(--ease-soft);
  will-change:opacity, transform;
}
.reveal.is-visible{ opacity:1; transform:none; }

/* ---------- 15b. TEXT REVEAL (word-by-word) ---------- */
/* .text-reveal elements are split into per-word spans by initTextReveal()
   in script.js. The block itself stays visible — only the words animate,
   each with its own JS-assigned delay for a soft cascading effect.
   Triggered either by its own .is-visible (added directly to the
   element) or by an ancestor .reveal becoming visible. */
.text-reveal{ opacity:1; transform:none; }
.text-reveal .word{
  display:inline-block;
  overflow:hidden;
  vertical-align:top;
  padding-bottom:.08em;   /* keeps descenders (g, y, p) from clipping */
  margin-bottom:-.08em;
}
.text-reveal .word__inner{
  display:inline-block;
  transform:translateY(115%);
  opacity:0;
  transition:transform 900ms var(--ease-soft), opacity 700ms var(--ease-soft);
  will-change:transform, opacity;
}
.text-reveal.is-visible .word__inner,
.reveal.is-visible .text-reveal .word__inner{
  transform:translateY(0);
  opacity:1;
}


/* ---------- 16. RESPONSIVE / A11Y ---------- */
@media(max-width:380px){
  .countdown__unit{ padding-inline:.75rem; }
  .itinerary__vase{ right:-2rem; width:7rem; }
}

/* Bigger, more visible scroll-reveal on phones — more travel + a soft
   blur-in so the entrance actually reads on a small screen. */
@media(max-width:640px){
  .reveal{
    transform:translateY(48px) scale(.92);
    filter:blur(4px);
    transition:opacity 1.05s var(--ease-soft),
               transform 1.05s var(--ease-soft),
               filter 1.05s var(--ease-soft);
  }
  .reveal.is-visible{ filter:blur(0); }

  .text-reveal .word__inner{
    transform:translateY(115%) rotate(3deg);
    transition:transform 950ms var(--ease-soft), opacity 750ms var(--ease-soft);
  }
  .text-reveal.is-visible .word__inner,
  .reveal.is-visible .text-reveal .word__inner{
    transform:translateY(0) rotate(0deg);
  }
}

@media(prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{ opacity:1; transform:none; }
}
/* ---------- 17. ADMIN PANEL ---------- */
/* Opened from rsvp.js by typing the admin password into the guest
   search field. Talks to the same Apps Script endpoint / Guests sheet
   as the RSVP form, so changes sync to every device instantly — there
   is no local/offline copy of the list. */
.admin-overlay{
  position:fixed; inset:0; z-index:300;
  background:rgba(20,40,75,.55);
  display:flex; align-items:center; justify-content:center;
  padding:1.5rem;
}
.admin-overlay[hidden]{ display:none; }

.admin-panel{
  width:min(38rem, 100%); max-height:85vh;
  background:var(--bg); border-radius:var(--radius);
  border:1px solid var(--fg-15);
  box-shadow:0 24px 60px rgba(20,40,75,.25);
  display:flex; flex-direction:column;
  overflow:hidden;
}
.admin-panel__head{
  display:flex; align-items:center; justify-content:space-between;
  padding:1.25rem 1.5rem; border-bottom:1px solid var(--fg-10);
  flex:none;
}
.admin-panel__head h3{ font-family:var(--font-display); font-size:1.5rem; font-weight:400; }
.admin-close{ font-size:1.75rem; line-height:1; color:var(--fg-50); }
.admin-close:hover{ color:var(--fg); }

.admin-add{ display:flex; gap:.5rem; padding:1.1rem 1.5rem 0; flex:none; }
.admin-add input{
  flex:1; padding:.6rem .75rem;
  border:1px solid var(--fg-20); border-radius:.5rem;
  background:transparent; color:var(--fg); font-family:inherit; font-size:.9375rem;
  transition:border-color .2s;
}
.admin-add input:focus{ outline:none; border-color:var(--fg-50); }

.btn--sm{ width:auto; padding:.6rem 1.15rem; font-size:.75rem; flex:none; }

.admin-status{
  min-height:1.1rem; margin:.65rem 1.5rem 0;
  font-size:.8125rem; color:var(--fg-50); flex:none;
}
.admin-status[data-state="error"]{ color:#B4462F; }
.admin-status[data-state="ok"]{ color:#3F6B4F; }

.admin-list-wrap{ overflow-y:auto; margin-top:.75rem; padding:0 1.5rem 1.5rem; }

.admin-table{ width:100%; border-collapse:collapse; font-size:.875rem; }
.admin-table th{
  text-align:left; padding:.5rem .5rem; color:var(--fg-50);
  font-weight:400; font-size:.6875rem; letter-spacing:.08em; text-transform:uppercase;
  border-bottom:1px solid var(--fg-15);
  position:sticky; top:0; background:var(--bg);
}
.admin-table td{ padding:.4rem .5rem; border-bottom:1px solid var(--fg-10); vertical-align:middle; }

.admin-table__name{
  border:1px solid transparent; background:transparent; color:var(--fg);
  font-family:inherit; font-size:.875rem; width:100%; padding:.3rem .4rem; border-radius:.4rem;
  transition:border-color .2s, background .2s;
}
.admin-table__name:hover{ background:var(--fg-03); }
.admin-table__name:focus{ outline:none; border-color:var(--fg-20); background:var(--fg-03); }
.admin-table__name.is-saving{ opacity:.6; }

.admin-badge{
  display:inline-block; padding:.2rem .55rem; border-radius:99px; white-space:nowrap;
  font-size:.6875rem; letter-spacing:.03em; text-transform:uppercase;
}
.admin-badge--yes{ background:rgba(63,107,79,.12); color:#3F6B4F; }
.admin-badge--no{ background:rgba(180,70,47,.12); color:#B4462F; }
.admin-badge--pending{ background:var(--fg-10); color:var(--fg-50); }

.admin-row__del{
  color:var(--fg-40); font-size:1.2rem; line-height:1; padding:.25rem;
  transition:color .2s;
}
.admin-row__del:hover{ color:#B4462F; }

.admin-empty{ text-align:center; color:var(--fg-50); padding:2rem 0; font-style:italic; font-size:.9375rem; }

/* ---------- 18. PHOTO SESSION SLIDESHOW ---------- */
.slideshow{ position:relative; max-width:30rem; margin-inline:auto; }
.slideshow__viewport{
  position:relative; aspect-ratio:4 / 5; overflow:hidden;
  border-radius:var(--radius); background:var(--ivory);
  box-shadow:0 12px 34px rgba(20,40,75,.14);
}
.slideshow__slide{
  position:absolute; inset:0; margin:0;
  opacity:0; transition:opacity 1s ease;
}
.slideshow__slide.is-active{ opacity:1; }
.slideshow__slide img{ width:100%; height:100%; object-fit:cover; display:block; }
.slideshow__nav{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:2.5rem; height:2.5rem; border-radius:50%;
  background:rgba(251,245,243,.85); color:var(--fg);
  font-size:1.5rem; line-height:1;
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 4px 14px rgba(20,40,75,.18);
}
.slideshow__nav--prev{ left:.75rem; }
.slideshow__nav--next{ right:.75rem; }
.slideshow__dots{ display:flex; justify-content:center; gap:.5rem; margin-top:1rem; }
.slideshow__dot{
  width:.5rem; height:.5rem; border-radius:50%; padding:0;
  background:var(--fg-20); transition:background .3s, transform .3s;
}
.slideshow__dot.is-active{ background:var(--accent); transform:scale(1.3); }

/* ---------- 19. GIFT — BANK DETAILS SIDE BY SIDE ---------- */
.bank-grid{
  display:grid; grid-template-columns:1fr 1fr; gap:.75rem;
  margin-top:2rem; text-align:left;
}
.bank-card{
  background:var(--fg-03); border:1px solid var(--fg-10);
  border-radius:.75rem; padding:.85rem .75rem;
  font-size:.6875rem; line-height:1.55; color:var(--fg-70);
  min-width:0; overflow-wrap:anywhere;
}
.bank-card .eyebrow{ font-size:.625rem; letter-spacing:.16em; margin-bottom:.5rem; }
.bank-card__code{ font-variant-numeric:tabular-nums; word-break:break-all; }
@media(min-width:520px){
  .bank-card{ font-size:.75rem; padding:1rem; }
}

/* ---------- 20. RSVP LANGUAGE TOGGLE ---------- */
.lang-toggle{
  display:inline-flex; gap:.25rem; padding:.25rem; margin-bottom:1.75rem;
  border:1px solid var(--fg-15); border-radius:999px; background:var(--fg-03);
}
.lang-toggle__btn{
  padding:.4rem 1.1rem; border-radius:999px;
  font-size:.75rem; letter-spacing:.15em; text-transform:uppercase;
  color:var(--fg-60); transition:background .3s, color .3s;
}
.lang-toggle__btn.is-active{ background:var(--fg); color:var(--bg); }
fieldset legend.field__label{ padding:0; }


/* ---------- 21. COUNTDOWN PILLARS — keep them to the edges ---------- */
.countdown__column{ z-index:0; opacity:1; }
@media(max-width:640px){
  .countdown__column--left{ left:-15%; }
  .countdown__column--right{ right:-15%; }
}


/* ---------- 22. INVITATION FRAME (gold ornamental border) ---------- */
/* Transparent PNG; the text sits inside the oval. Sizes are tuned so the
   whole letter fits within the frame on a phone. */
.frame{
  position:relative; width:100%;
  aspect-ratio:642 / 978;
}
.frame__img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:fill; max-width:none;
}
.frame__content{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:19% 17%; text-align:center;
}
.frame__content .lead{ font-size:clamp(.95rem,3.6vw,1.1rem); line-height:1.6; margin-bottom:.75rem; }
.frame__content .muted{ font-size:clamp(.8rem,3vw,.9rem); line-height:1.6; }
.frame__content .eyebrow{ font-size:.6875rem; letter-spacing:.2em; }
.frame__content .display--sm{ font-size:clamp(1.75rem,7vw,2.5rem); }


/* ---------- 23. PORTRAIT DIVIDERS ---------- */
/* The divider photos are portrait; full-bleed is right on phones, but on
   wide screens cap the width so they don't become a wall of picture. */
@media(min-width:768px){
  .divider-photo__img{ max-width:34rem; margin-inline:auto; }
}

/* ---------- 24. DIVIDER EDGE FADE ---------- */
/* Each divider photo dissolves into the page background at its top and
   bottom (and at the sides once it's narrower than the screen), so the
   change between sections is soft instead of a hard edge. A mask is used
   rather than a coloured overlay, so it works with any background. */
.divider-photo__img{
  -webkit-mask-image:linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%);
          mask-image:linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%);
}
@media(min-width:768px){
  .divider-photo__img{
    -webkit-mask-image:
      linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%),
      linear-gradient(to right,  transparent 0, #000 14%, #000 86%, transparent 100%);
    -webkit-mask-composite:source-in;
            mask-image:
      linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%),
      linear-gradient(to right,  transparent 0, #000 14%, #000 86%, transparent 100%);
            mask-composite:intersect;
  }
}


/* ---------- 25. HEART + SWAN ORNAMENTS ---------- */
.dresscode__heart{
  width:clamp(5rem,22vw,7.5rem); height:auto;
  margin-bottom:1.25rem;
  filter:drop-shadow(0 6px 10px rgba(20,40,75,.18));
  animation:heartbeat 3s ease-in-out infinite;
  transform-origin:center;
}
@keyframes heartbeat{
  0%,38%,100%{ transform:scale(1); }
  10%        { transform:scale(1.07); }
  20%        { transform:scale(1); }
  28%        { transform:scale(1.05); }
}
.rsvp__swan{
  width:clamp(9rem,46vw,14rem); height:auto;
  margin-bottom:1rem;
  filter:drop-shadow(0 6px 10px rgba(20,40,75,.15));
}


/* ---------- 26. SINGLE LANDSCAPE ATTIRE GUIDE ---------- */
.attire-guide--single{ grid-template-columns:1fr; }
.attire-guide--single .attire-fig__frame{ aspect-ratio:3 / 2; }
.attire-guide--single .attire-fig__frame img{ object-fit:cover; }


/* ---------- 27. ATTIRE GUIDE TOP OVERLAY ---------- */
.attire-fig__overlay{
  position:absolute; top:0; left:0; right:0; z-index:2;
  padding:1.1rem 1rem 3.5rem; text-align:center; pointer-events:none;
  background:linear-gradient(to bottom, rgba(20,40,75,.62) 0%, rgba(20,40,75,.28) 55%, rgba(20,40,75,0) 100%);
}
.attire-fig__overlay span{
  font-size:.75rem; letter-spacing:.3em; text-transform:uppercase;
  color:#fff; text-shadow:0 1px 6px rgba(0,0,0,.25);
}

/* ---------- 28. TWO-COLOUR MOTIF ---------- */
.swatches--two{
  grid-template-columns:repeat(2, max-content);
  justify-content:center; gap:1rem 2.5rem;
}
.swatches--two .swatch__chip{ width:3.25rem; height:3.25rem; border-color:var(--fg-20); }
@media(min-width:520px){
  .swatches--two{ grid-template-columns:repeat(2, max-content); }
}


/* ---------- 28. ATTIRE LINEUP (semi-animated) ---------- */
/* Two poses alternate on a short loop: each is held for ~0.8s, then a
   soft ~0.3s crossfade swaps to the other (2.2s per full A -> B -> A). */
.attire-lineup{ max-width:40rem; margin:0 auto 1.75rem; }
.attire-lineup__stage{
  position:relative; width:100%; aspect-ratio:1100 / 579;
  animation:lineupFloat 7s ease-in-out infinite;
  filter:drop-shadow(0 10px 14px rgba(20,40,75,.16));
}
.attire-lineup__stage img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:fill; max-width:none;
}
.attire-lineup__a{ animation:lineupA 2.2s ease-in-out infinite; }
.attire-lineup__b{ opacity:0; animation:lineupB 2.2s ease-in-out infinite; }

@keyframes lineupA{
  0%,36%  { opacity:1; }
  50%,86% { opacity:0; }
  100%    { opacity:1; }
}
@keyframes lineupB{
  0%,36%  { opacity:0; }
  50%,86% { opacity:1; }
  100%    { opacity:0; }
}
@keyframes lineupFloat{
  0%,100%{ transform:translateY(0); }
  50%    { transform:translateY(-5px); }
}


/* ---------- 29. INTRO -> HERO HANDOFF ---------- */
/* The intro video ends on its last frame, then drifts forward and
   dissolves while the invitation settles into focus underneath
   (main.fg-enter -> .is-in, defined in 4c). */
.intro{
  transition:opacity 1.6s cubic-bezier(.4,0,.2,1),
             transform 2s cubic-bezier(.3,.7,.2,1);
}
.intro.is-out{ transform:scale(1.05); }

/* Opacity comes up quickly so the light page background never shows
   through mid-dissolve; the blur, zoom and poster drift stay slow. */
main.fg-enter{
  transition:
    transform 2600ms cubic-bezier(.30,.72,.22,1),
    opacity 600ms ease-out,
    filter 2200ms ease-out;
}
main.fg-enter .hero__scroll{
  transition:
    opacity 900ms ease-out 1400ms,
    transform 900ms ease-out 1400ms,
    color .25s ease 0s;
}

@media(prefers-reduced-motion:reduce){
  .intro{ transition-duration:.4s !important; }
  .intro.is-out{ transform:none; }
}
/* Navy, rose gold and ivory */
:root {
  --navy: #101d35;
  --rose-gold: #dea798;
  --ivory-light: #fff5e5;
}

.hero, #celebrations, #entourage, #rsvp {
  background: radial-gradient(ellipse at 50% 10%, #243957, var(--navy) 72%);
  color: var(--ivory-light);
  --fg: var(--ivory-light);
  --accent: var(--rose-gold);
  --header-green: var(--rose-gold);
  --fg-70: #eee0d5;
  --fg-60: #e4d2c7;
  --fg-50: #dbc5b8;
  --fg-40: #cfb6a9;
  --fg-20: #dea79866;
  --fg-15: #dea79859;
  --fg-10: #dea79844;
  --fg-03: #fff5e50d;
}
.hero { display: grid; place-items: center; isolation: isolate; }
.hero__frame {
  position: absolute; inset: clamp(14px, 4vw, 42px);
  border: 1px solid #dea79891; outline: 1px solid #dea79845;
  outline-offset: -7px; pointer-events: none;
}
.hero__title { z-index: 1; padding: 5rem 1.75rem; }
.hero__title h1 {
  font: 400 clamp(3.45rem, 10vw, 8rem)/1.1 var(--font-script);
  margin: .35em 0 .28em; text-shadow: 0 2px 20px #101d35;
}
.hero__title h1 span, .hero__date { color: var(--rose-gold); }
.hero__title .eyebrow { letter-spacing: .24em; }
.hero__floral { position: absolute; width: clamp(9rem, 27vw, 25rem); }
.hero__floral--left { left: 0; top: 0; }
.hero__floral--right { right: 0; bottom: 0; }
.hero__scroll { position: absolute; bottom: clamp(1.4rem, 5vw, 3.5rem); padding: .4rem; }
.intro { background: var(--navy); }
.intro__video { object-fit: contain; }
.intro__hint {
  position: absolute; bottom: max(2.5rem, env(safe-area-inset-bottom));
  padding: .6rem 1.3rem; color: var(--ivory-light); background: #101d35e6;
  border: 1px solid var(--rose-gold); border-radius: 2rem;
  font-size: .72rem; letter-spacing: .18em; text-transform: uppercase;
}
.intro.is-playing .intro__hint { visibility: hidden; }
#invite, #lovestory, #faq, #gift { background: var(--ivory); }
.section { border-top: 1px solid #b77d7040; }
.card, .ent__card, .faq-item { border-color: #b77d7066; }
.btn { border: 1px solid #b77d70; }
#celebrations .btn { background: var(--rose-gold); color: var(--navy); }
#celebrations .btn:hover { background: var(--ivory-light); color: var(--navy); }
.footer--photo.footer { background: var(--navy); border-top: 1px solid var(--rose-gold); }
.footer--photo .display { color: var(--ivory-light); }
.footer--photo .footer__amp, .footer__initials { color: var(--rose-gold); }
.footer__initials { font: 2.8rem/1.2 var(--font-script); margin-bottom: .6rem; }
.countdown__column { opacity: .65; }

@media (max-width: 420px) {
  .hero__title h1 span { display: block; font-size: .65em; }
}
.hero__title {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding-inline: clamp(1.5rem, 7vw, 6rem);
}
.hero__title h1 { font-size: clamp(3.4rem, 9vw, 7.5rem); }
@media (max-width: 520px) {
  .hero__title h1 span { display: block; font-size: .65em; }
}

.attire-lineup a { display: block; border-radius: .75rem; }
.attire-lineup img {
  width: 100%; height: auto; border-radius: inherit;
  border: 1px solid #b77d7066;
}

.reception-photo {
  width: 100%; height: auto; border-radius: .65rem;
  margin: 0 auto 1.5rem;
}
#dresscode .wrap { max-width: 58rem; }
#dresscode .attire-lineup { max-width: 56rem; }
#dresscode .card { max-width: 42rem; margin-inline: auto; }

.card--photo > .venue-watercolor {
  position: relative; isolation: isolate; overflow: hidden;
  aspect-ratio: 2 / 1; margin: 0 auto 1.5rem; border-radius: .65rem;
  background: #ecddcc; border: 1px solid #dea79866;
}
.venue-watercolor img { width: 100%; height: 100%; object-fit: cover; }
.venue-watercolor--ceremony img { object-fit: contain; padding: .25rem; }
.venue-watercolor::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 62%, #101d3533);
}

.hero {
  container-type: inline-size;
  width: min(100%, 66svh);
  min-height: 100svh;
  margin-inline: auto;
  background: #f7ecdc url("assets/hero-watercolor.webp") center / cover no-repeat;
}
main:has(> .hero) { background: #101d35; }
.hero__title {
  inset: 24% 6% auto;
  padding: 0;
  color: #152c47;
  text-shadow: 0 1px 10px #fff8ed;
}
.hero__title h1 {
  font-size: clamp(3rem, 14cqw, 7.1rem);
  line-height: .96;
  margin: 0 0 .35em;
  text-shadow: inherit;
}
.hero__title h1 span {
  display: block;
  color: inherit;
  font-size: .57em;
  line-height: 1.22;
}
.hero__calendar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: .14em .65em;
  width: min(84%, 24rem);
  font-size: clamp(.65rem, 2.8cqw, 1rem);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.hero__calendar-month, .hero__calendar-year { grid-column: 1 / -1; }
.hero__calendar-day { font: 500 3.65em/.82 var(--font-display); letter-spacing: 0; }
.hero__calendar-side {
  border-block: 1px solid #926559;
  padding-block: .3em;
  white-space: nowrap;
}
.hero__scroll, .hero__scroll:hover {
  color: #152c47;
  background: #fff5e5e8;
  border-radius: 1.5rem;
  padding: .45rem 1rem;
}
.hero__scroll span { text-shadow: none; letter-spacing: .15em; }
@media (max-width: 600px) {
  .hero { width: 100%; }
}

/* Full-bleed hero with a navy backdrop and a readable countdown. */
.hero {
  width: 100%;
  margin: 0;
  background-color: #101d35;
  background-image: linear-gradient(90deg, #101d3538, transparent 30%, transparent 70%, #101d3538),
    url("assets/hero-watercolor.webp");
  background-position: center;
  background-size: cover;
}
.hero__title h1 { font-size: clamp(3rem, min(14cqw, 12svh), 7.1rem); }
#countdown {
  background: #101d35;
  color: #fff5e5;
  border-top: 0;
  --fg: #fff5e5;
  --fg-70: #fff5e5;
  --fg-60: #fff5e5;
  --fg-50: #fff5e5;
  --fg-40: #fff5e5;
  --fg-15: #fff5e566;
  --header-green: #fff5e5;
}
#countdown :is(.display, .eyebrow, .countdown__value, .countdown__label) {
  color: #fff5e5;
}

#itinerary, #dresscode { background-color: #fff5e5; }

#itinerary .itinerary__vase {
  position: static;
  width: clamp(4rem, 16vw, 6rem);
  margin: 1rem auto 0;
}
#itinerary .timeline__item.is-visible::before {
  background: #a96968;
  animation: itinerary-marker .65s var(--ease-soft) both;
}
@keyframes itinerary-marker {
  from { opacity: .35; transform: scale(.65); }
  55% { opacity: 1; transform: scale(1.35); }
  to { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  #itinerary .timeline__item.is-visible::before { animation: none; }
}

/* Fit the entire 9:16 intro within the viewport. */
.intro__video {
  width: min(100%, 56.25dvh);
  height: auto;
  max-height: 100dvh;
  aspect-ratio: 9 / 16;
}
