/* AIRA crimson-royale stylesheet — FRAME-SCROLL (right edge rule corrected) */
:root{
    --crimson:#6E0D18; --crimson-deep:#2A0409; --crimson-mid:#4A0710;
    --gold:#C9A227; --gold-light:#E8C874; --ivory:#F5EFE3; --line:#7A2A30;
  }
  *{box-sizing:border-box;margin:0;padding:0;}
  body{font-family:'Cormorant Garamond', serif; background:var(--crimson-deep); color:var(--ivory); overflow-x:hidden;}
  h1,h2,.display{font-family:'Playfair Display', serif;}
  .section{padding:90px 24px; max-width:720px; margin:0 auto; text-align:center;}
  .divider{width:70px; height:2px; background:var(--gold); margin:28px auto; position:relative;}
  .divider::before,.divider::after{content:'✦'; position:absolute; top:-10px; color:var(--gold); font-size:15px;}
  .divider::before{left:-26px;} .divider::after{right:-26px;}

  /* CURTAIN REVEAL — realistic velvet drape */
  .curtain{position:fixed; inset:0; height:100vh; height:100dvh; z-index:999; display:flex; cursor:pointer; background:#1E0203; touch-action:none; overscroll-behavior:none;}
  .curtain.open{pointer-events:none; background:transparent;}
  .curtain-panel{
    flex:1; position:relative; transition:transform 1.5s cubic-bezier(.76,0,.24,1);
    background:
      repeating-linear-gradient(90deg,
        rgba(255,255,255,.09) 0 4px,
        rgba(0,0,0,.12) 4px 22px,
        rgba(255,255,255,.05) 22px 30px,
        rgba(0,0,0,.18) 30px 48px),
      linear-gradient(180deg,#7A121A 0%,#4A0810 55%,#2A0305 100%);
    box-shadow:0 0 60px rgba(0,0,0,.7) inset, 0 0 20px rgba(0,0,0,.5) inset;
  }
  .curtain-panel::before{
    content:''; position:absolute; inset:0;
    background:linear-gradient(115deg, transparent 30%, rgba(255,255,255,.08) 45%, transparent 60%);
  }
  .curtain-valance{position:absolute; top:0; left:0; right:0; height:38px;
    background:repeating-radial-gradient(circle at 50% -10px, #8C1E28 0 16px, #6B141C 16px 17px);
    box-shadow:0 4px 12px rgba(0,0,0,.4);
  }
  .curtain-tassels{position:absolute; bottom:0; left:0; right:0; height:22px; display:flex; justify-content:space-evenly;}
  .curtain-tassels::before{content:''; position:absolute; inset:0; background:repeating-linear-gradient(90deg, var(--gold) 0 3px, transparent 3px 16px); opacity:.55;}
  .curtain-left{transform:translateX(0);} .curtain-right{transform:translateX(0);}
  .curtain.open .curtain-left{transform:translateX(-100%);}
  .curtain.open .curtain-right{transform:translateX(100%);}
  .curtain-gold-edge{position:absolute; top:0; bottom:0; width:7px; background:linear-gradient(180deg,var(--gold-light),var(--gold)); box-shadow:0 0 10px rgba(201,162,39,.5);}
  .curtain-left .curtain-gold-edge{right:0;} .curtain-right .curtain-gold-edge{left:0;}
  .curtain-tap{position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); text-align:center; z-index:2; pointer-events:none; transition:opacity 0.6s ease;}
  .curtain.open .curtain-tap{opacity:0;}
  .curtain-tap .ct-icon{width:60px; height:60px; border-radius:50%; border:1.5px solid var(--gold); display:flex; align-items:center; justify-content:center; font-size:22px; color:var(--gold); margin:0 auto 16px; animation:pulseGate 2.2s ease-in-out infinite;}
  @keyframes pulseGate{0%,100%{transform:scale(1); opacity:.8;} 50%{transform:scale(1.08); opacity:1;}}
  .curtain-tap .ct-tap{letter-spacing:.35em; font-size:12px; text-transform:uppercase; color:var(--gold);}

  /* HERO */
  .hero{
    min-height:100vh; display:flex; flex-direction:column; align-items:center; justify-content:center;
    background:
      radial-gradient(ellipse at 50% 38%, rgba(150,20,36,.55), transparent 62%),
      linear-gradient(180deg, var(--crimson-mid) 0%, var(--crimson-deep) 100%);
    text-align:center; padding:64px 40px; position:relative; overflow:hidden;
  }

  /* The hero no longer carries its own frame — see .page-frame at the end
     of this file, which frames the whole invitation instead. Only the thin
     inner rule is kept here, the way a printed card is ruled. */
  .hero::after{
    content:''; position:absolute; inset:54px; pointer-events:none;
    border:1px solid var(--gold); opacity:.28;
  }

  /* Was a gold radial sitting right behind the names, which is what made
     them look washed out. Now a deep red bloom: it lifts the centre of the
     page without competing with the lettering. */
  .spotlight{
    position:absolute; top:-15%; left:50%; transform:translateX(-50%);
    width:760px; height:760px; pointer-events:none;
    background:radial-gradient(circle, rgba(176,26,45,.45), rgba(110,13,24,.18) 45%, transparent 68%);
  }
  .eyebrow{letter-spacing:.4em; font-size:13px; color:var(--gold); text-transform:uppercase; margin-bottom:18px;}
  .hero h1{
    font-size:clamp(42px,9vw,76px); font-weight:700; line-height:1.1;
    color:var(--ivory);
    text-shadow:0 1px 0 rgba(0,0,0,.45), 0 0 26px rgba(232,200,116,.22);
  }
  .amp{color:var(--gold); font-style:italic; font-size:0.6em; display:block; margin:8px 0;}
  .date-line{font-size:20px; letter-spacing:.15em; margin-top:22px; color:var(--gold-light);}

  .scratch-wrap{margin:34px auto 0; position:relative; width:280px; height:120px;}
  #scratchCanvas{border-radius:14px; touch-action:none; cursor:grab;}
  .scratch-under{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; border-radius:14px; background:var(--crimson-deep); border:1px solid var(--gold);}
  .scratch-under .d{font-family:'Playfair Display'; font-size:26px; color:var(--gold-light);}
  .scratch-hint{font-size:13px; letter-spacing:.2em; text-transform:uppercase; color:var(--gold); margin-top:10px;}
  #confettiCanvas{position:fixed; inset:0; pointer-events:none; z-index:500;}

  .countdown{display:flex; gap:20px; justify-content:center; margin-top:36px; flex-wrap:wrap;}
  .cd-num{font-family:'Playfair Display'; font-size:34px; color:var(--gold-light); font-weight:700;}
  .cd-label{font-size:12px; letter-spacing:.2em; text-transform:uppercase; color:var(--ivory); opacity:.65;}

  .section p.lead{font-size:20px; line-height:1.8; color:#D9C7C0;}

  .timeline{margin-top:30px; text-align:left; position:relative; padding-left:28px;}
  .timeline::before{content:''; position:absolute; left:6px; top:6px; bottom:6px; width:2px; background:var(--line);}
  .tl-item{position:relative; padding-bottom:28px;}
  .tl-item::before{content:''; position:absolute; left:-28px; top:4px; width:12px; height:12px; border-radius:50%; background:var(--gold); border:2px solid var(--crimson-deep);}
  .tl-time{font-family:'Playfair Display'; font-size:16px; color:var(--gold-light);}
  .tl-title{font-size:19px; color:var(--ivory); margin-top:2px;}

  .gallery{display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-top:30px;}
  .gallery div{aspect-ratio:1; border-radius:6px; display:flex; align-items:center; justify-content:center; color:var(--gold-light); font-size:12px; background:linear-gradient(135deg,var(--crimson),var(--crimson-deep)); border:1px solid var(--line); cursor:pointer;}

  .map-frame{width:100%; height:280px; border-radius:12px; overflow:hidden; margin-top:24px; border:1px solid var(--gold);}
  .map-frame iframe{width:100%; height:100%; border:0;}
  .map-editor{background:var(--crimson); border:1px solid var(--gold); border-radius:14px; padding:22px 20px; margin-top:26px; text-align:left;}
  .map-editor .me-label{font-size:13px; letter-spacing:.12em; text-transform:uppercase; color:var(--gold-light); margin-bottom:10px; font-family:'Playfair Display';}
  .map-editor .me-row{display:flex; gap:10px; flex-wrap:wrap;}
  .map-editor input{flex:1; min-width:180px; padding:12px 14px; border-radius:8px; border:1px solid var(--line); font-family:'Cormorant Garamond'; font-size:16px; background:var(--crimson-deep); color:var(--ivory);}
  .map-editor button{padding:12px 22px; border:none; border-radius:8px; background:var(--gold); color:var(--crimson-deep); font-family:'Playfair Display'; font-weight:700; cursor:pointer;}
  .me-hint{font-size:13px; color:#C9AFAC; margin-top:8px;}
  .me-error{font-size:13px; color:#E88A8A; margin-top:8px; display:none;}
  .me-success{font-size:13px; color:var(--gold-light); margin-top:8px; display:none;}

  .rsvp{background:var(--crimson); border-radius:16px; padding:44px 28px; border:1px solid var(--gold);}
  .rsvp input, .rsvp select, .rsvp textarea{width:100%; padding:13px 16px; margin-top:14px; border-radius:8px; border:1px solid var(--line); font-family:'Cormorant Garamond'; font-size:17px; background:var(--crimson-deep); color:var(--ivory);}
  .rsvp label{display:block; text-align:left; font-size:13px; letter-spacing:.1em; text-transform:uppercase; color:var(--gold-light); margin-top:18px;}
  .rsvp button{margin-top:26px; width:100%; padding:15px; border:none; border-radius:8px; background:var(--gold); color:var(--crimson-deep); font-family:'Playfair Display'; font-weight:700; font-size:16px; cursor:pointer;}
  .rsvp-success{display:none; margin-top:18px; color:var(--gold-light);}

  .music-toggle{position:fixed; bottom:22px; right:22px; width:52px; height:52px; border-radius:50%; background:var(--gold); color:var(--crimson-deep); border:none; font-size:20px; cursor:pointer; box-shadow:0 6px 20px rgba(0,0,0,.4); z-index:50; display:flex; align-items:center; justify-content:center;}
  .gallery img{width:100%; height:100%; object-fit:cover; border-radius:6px;}
  .gallery div{position:relative;}
  .photo-remove{position:absolute; top:4px; right:4px; width:20px; height:20px; border-radius:50%; background:rgba(0,0,0,.6); color:#fff; border:none; font-size:12px; cursor:pointer; line-height:1;}
  .gallery-editor{background:var(--crimson); border:1px solid var(--gold); border-radius:14px; padding:22px 20px; margin-top:20px; text-align:left;}
  .gallery-editor .ge-label{font-size:13px; letter-spacing:.12em; text-transform:uppercase; color:var(--gold-light); margin-bottom:10px; font-family:'Playfair Display';}
  .gallery-editor .ge-row{display:flex; gap:10px; flex-wrap:wrap;}
  .gallery-editor input{flex:1; min-width:180px; padding:12px 14px; border-radius:8px; border:1px solid var(--line); font-family:'Cormorant Garamond'; font-size:15px; background:var(--crimson-deep); color:var(--ivory);}
  .gallery-editor button{padding:12px 20px; border:none; border-radius:8px; background:var(--gold); color:var(--crimson-deep); font-family:'Playfair Display'; font-weight:700; cursor:pointer; font-size:14px;}
  .ge-hint{font-size:13px; color:#C9AFAC; margin-top:8px;}
  .music-toggle.playing{animation:spin 5s linear infinite;}
  @keyframes spin{to{transform:rotate(360deg);}}
  footer{padding:40px 24px; text-align:center; font-size:13px; letter-spacing:.2em; color:var(--gold); text-transform:uppercase; border-top:1px solid var(--line);}

  /* SPARKLE BURST on tap */
  .sparkle{position:fixed; pointer-events:none; z-index:1002; font-size:16px; animation:sparkleFly .9s ease-out forwards; will-change:transform,opacity;}
  @keyframes sparkleFly{ 0%{transform:translate(0,0) scale(.2) rotate(0deg); opacity:1;} 70%{opacity:1;} 100%{transform:translate(var(--dx),var(--dy)) scale(1.15) rotate(200deg); opacity:0;} }

/* ==========================================================
   SCRATCH-TO-REVEAL  (this block only - nothing above changed)
   ========================================================== */
/* ---------- royal wax seal ---------- */
.scratch-wrap{filter:drop-shadow(0 10px 22px rgba(0,0,0,.45));}
#scratchCanvas{position:absolute; inset:0; z-index:2; border-radius:14px; touch-action:none; cursor:grab;}
#scratchCanvas:active{cursor:grabbing;}
.scratch-under{z-index:1;}
.scratch-under .d{line-height:1.15;}

/* ---------- scratch material flecks (shared, body-level) ---------- */
.aira-fleck{
  position:fixed; z-index:1200; pointer-events:none; opacity:1;
  animation:airaFleck .95s cubic-bezier(.3,.7,.4,1) forwards;
}
@keyframes airaFleck{
  0%{opacity:.95; transform:translate(0,0) rotate(0deg) scale(1);}
  100%{opacity:0; transform:translate(var(--fx),var(--fy)) rotate(var(--fr)) scale(.5);}
}
@media (prefers-reduced-motion:reduce){ .aira-fleck{display:none;} }

/* ---------- staged date reveal: day, month, year, label, glow, continue ---------- */
/* the reveal panel stacks: date line, then the label, then Continue */
.scratch-under{flex-direction:column;}
.scratch-under .dr-day,.scratch-under .dr-month,.scratch-under .dr-year{
  display:inline-block; opacity:0; transform:translateY(10px) scale(.94);
  transition:opacity .62s ease, transform .62s cubic-bezier(.22,1,.36,1);
}
.scratch-under .dr-month{margin:0 .34em;}
.scratch-under.s1 .dr-day{opacity:1; transform:none;}
.scratch-under.s2 .dr-month{opacity:1; transform:none;}
.scratch-under.s3 .dr-year{opacity:1; transform:none;}
.scratch-under .dr-label{
  display:block; margin-top:7px; font-size:8px; letter-spacing:.3em;
  text-transform:uppercase; color:var(--gold);
  opacity:0; transform:translateY(8px);
  transition:opacity .6s ease, transform .6s cubic-bezier(.22,1,.36,1);
}
.scratch-under.s4 .dr-label{opacity:1; transform:none;}
.scratch-under .dr-cta{
  margin-top:9px; padding:6px 14px; font:inherit; font-size:9px; line-height:1;
  letter-spacing:.22em; text-transform:uppercase; cursor:pointer; border-radius:0;
  color:var(--gold-light); background:transparent; border:1px solid var(--gold);
  opacity:0; transform:translateY(8px);
  transition:opacity .6s ease, transform .6s cubic-bezier(.22,1,.36,1),
             background .35s ease, color .35s ease;
}
.scratch-under.s5 .dr-cta{opacity:1; transform:none;}
.scratch-under .dr-cta:hover{background:var(--gold); color:var(--crimson-deep);}
.scratch-under.s5{animation:drGlow9959 1.6s ease-out;}
@keyframes drGlow9959{
  0%{box-shadow:0 0 0 0 rgba(201,162,39,.55);}
  40%{box-shadow:0 0 34px 6px rgba(201,162,39,.55);}
  100%{box-shadow:0 0 0 0 rgba(0,0,0,0);}
}

/* the prompt steps back once the guest starts working the surface */
.is-scratching + .scratch-hint,.is-scratching ~ .scratch-hint{opacity:.35;}

/* ==========================================================================
   AIRA MOTION SYSTEM
   Appended block. Changes how things move, never what the template looks
   like - no colour, font family, layout or decoration is altered here.
   ========================================================================== */

:root{
  /* Authored easing. The default `ease` is symmetrical, which is why stock
     web motion reads as cheap: real objects accelerate hard and land soft. */
  --e-drape :cubic-bezier(.62,.02,.14,1);   /* heavy physical panels        */
  --e-silk  :cubic-bezier(.16,.86,.22,1);   /* long decelerate, big surfaces */
  --e-lift  :cubic-bezier(.19,1,.22,1);     /* type and cards arriving       */
  --e-settle:cubic-bezier(.40,.90,.30,1);   /* micro corrections             */
  /* Duration scale tied to how far a thing travels. */
  --t-1:260ms; --t-2:520ms; --t-3:820ms; --t-4:1250ms; --t-5:1900ms;
}

/* ---------- typographic rendering (quality only, no faces changed) ---------- */
html{-webkit-text-size-adjust:100%;}
body{
  text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  font-kerning:normal;
  font-variant-ligatures:common-ligatures contextual;
  font-synthesis-weight:none;
}
h1,h2,h3{text-wrap:balance;}
p,.lead{text-wrap:pretty;}

/* ---------- masked word reveal for display type ---------- */
.aira-w{
  display:inline-block; overflow:hidden; vertical-align:top;
  padding-bottom:.18em; margin-bottom:-.18em;   /* room for descenders */
}
.aira-w.aira-w-block{display:block;}
.aira-w > i{
  display:inline-block; font-style:inherit; color:inherit;
  transform:translate3d(0,112%,0) rotate(1.6deg); opacity:0; filter:blur(9px);
  transition:transform var(--t-4) var(--e-lift),
             opacity 900ms var(--e-lift),
             filter 900ms var(--e-lift);
  transition-delay:calc(var(--wi,0) * 105ms + 170ms);
}
.aira-w > i.aira-w-block{display:block;}
.aira-w.on > i{transform:none; opacity:1; filter:blur(0);}

/* ---------- hero beats ---------- */
.aira-beat{
  opacity:0; transform:translate3d(0,var(--beat-rise,22px),0);
  filter:blur(var(--beat-blur,5px));
  transition:opacity var(--t-3) var(--e-lift),
             transform var(--t-3) var(--e-lift),
             filter var(--t-3) var(--e-lift);
  transition-delay:calc(var(--bi,0) * 135ms);
}
.aira-beat.aira-on{opacity:1; transform:none; filter:blur(0);}

/* ---------- scroll storytelling ---------- */
.aira-rise{
  opacity:0; transform:translate3d(0,34px,0);
  transition:opacity var(--t-3) var(--e-lift), transform var(--t-3) var(--e-lift);
}
.aira-rise.aira-in{opacity:1; transform:none;}
.aira-stagger{
  opacity:0; transform:translate3d(0,18px,0);
  transition:opacity var(--t-3) var(--e-lift), transform var(--t-3) var(--e-lift);
  transition-delay:calc(var(--i,0) * 85ms + 110ms);
}
.aira-in > .aira-stagger,
.in > .aira-stagger,
.visible > .aira-stagger{opacity:1; transform:none;}

/* ---------- the opening: weight, then release ---------- */
.aira-gate.aira-press{transform:scale(.9955); transition:transform 200ms var(--e-settle);}
.aira-seam{
  position:absolute; top:0; bottom:0; left:50%; width:2px; margin-left:-1px;
  z-index:6; pointer-events:none; opacity:0; filter:blur(1px);
  background:linear-gradient(180deg,transparent,rgba(255,255,255,.92),transparent);
}
.aira-seam.aira-seam-h{
  top:50%; bottom:auto; left:0; right:0; width:auto; height:2px; margin:-1px 0 0;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.92),transparent);
}
.aira-gate.aira-opening .aira-seam{animation:airaSeamV 950ms var(--e-silk) forwards;}
.aira-gate.aira-opening .aira-seam.aira-seam-h{animation:airaSeamH 950ms var(--e-silk) forwards;}
@keyframes airaSeamV{0%{opacity:0;transform:scaleY(.15);}20%{opacity:1;}100%{opacity:0;transform:scaleY(1.2);}}
@keyframes airaSeamH{0%{opacity:0;transform:scaleX(.15);}20%{opacity:1;}100%{opacity:0;transform:scaleX(1.2);}}

@media (prefers-reduced-motion:reduce){
  .aira-w > i,.aira-beat,.aira-rise,.aira-stagger{
    transition:none !important; transform:none !important;
    opacity:1 !important; filter:none !important;
  }
  .aira-seam{display:none;}
}

/* ---------- Crimson Royale: velvet drape, re-timed ---------- */
/* 1.5s `cubic-bezier(.76,0,.24,1)` moved both panels in lockstep. Real
   drapes never part symmetrically, so the right panel now leaves 110ms
   later and both carry the heavier drape curve over a longer travel. */
.curtain-panel{transition:transform var(--t-5) var(--e-drape) !important;}
.curtain.open .curtain-right{transition-delay:110ms;}
.curtain-tap{transition:opacity 480ms var(--e-settle), transform 700ms var(--e-lift);}
.curtain.open .curtain-tap{transform:translate(-50%,-50%) scale(1.14);}
/* optical tracking: Playfair at 76px needs to be pulled in, not spaced out */
.hero h1{letter-spacing:-.012em; line-height:1.03;}
.hero .amp{letter-spacing:.04em;}
.eyebrow,.scratch-hint,.cd-label,footer{font-feature-settings:"case" 1;}

/* ============================================================
   EXTRA SECTIONS  —  couple details, pre-wedding events,
   dress code, accommodation, closing
   ------------------------------------------------------------
   Every one of these sections is optional. aira-bind.js removes
   the whole <section data-aira-section="..."> when the couple
   left that detail blank, so nothing here needs a "hidden"
   state — on the preview page they are all simply shown with
   their demo wording.
   ============================================================ */

/* ---- the couple, formally introduced ---- */
.couple-details{
  display:flex; align-items:center; justify-content:center;
  gap:28px; margin-top:34px; flex-wrap:wrap;
}
.cd-person{flex:1 1 240px; min-width:220px;}
.cd-name{
  font-family:'Pinyon Script', cursive;
  font-size:52px; line-height:1.1; color:var(--gold-light);
  text-shadow:0 2px 14px rgba(201,162,39,.28);
  margin-bottom:12px;
}
.cd-parents{
  font-size:18px; color:var(--ivory); font-style:italic;
  letter-spacing:.01em;
}
.cd-line{font-size:16px; color:#D9C7C0; margin-top:4px;}
.cd-amp{
  font-family:'Pinyon Script', cursive;
  font-size:44px; color:var(--gold); flex:0 0 auto; opacity:.85;
}

/* ---- pre-wedding events ---- */
.pre-events{margin-top:30px; display:grid; gap:16px;}
.pe-item{
  border:1px solid var(--line); border-radius:12px;
  padding:20px 18px;
  background:linear-gradient(135deg,var(--crimson),var(--crimson-deep));
}
.pe-name{
  font-family:'Playfair Display', serif; font-size:22px;
  color:var(--gold-light); letter-spacing:.01em;
}
.pe-when{font-size:16px; color:var(--ivory); margin-top:6px;}
.pe-dot{color:var(--gold); margin:0 8px;}
.pe-place{font-size:15px; color:#D9C7C0; margin-top:4px; font-style:italic;}

/* ---- dress code ---- */
.dress-code{
  display:flex; gap:24px; margin-top:30px; flex-wrap:wrap;
  justify-content:center;
}
.dc-col{flex:1 1 240px; min-width:220px;}
.dc-head{
  font-family:'Playfair Display', serif; font-size:19px;
  color:var(--gold-light); letter-spacing:.08em; text-transform:uppercase;
  padding-bottom:10px; margin-bottom:12px;
  border-bottom:1px solid var(--line);
}
.dc-col p{font-size:17px; line-height:1.7; color:#D9C7C0;}

/* ---- accommodation booking code ---- */
.stay-code{
  display:inline-block; margin-top:18px;
  padding:10px 22px; border:1px dashed var(--gold);
  border-radius:8px; color:var(--gold-light);
  font-family:'Playfair Display', serif;
  letter-spacing:.16em; font-size:16px;
}

/* ---- closing ---- */
.closing{padding-top:40px; padding-bottom:50px;}
.closing-rule{
  width:180px; height:1px; margin:0 auto;
  background:linear-gradient(90deg,transparent,var(--gold),transparent);
}
.closing-text{
  font-family:'Playfair Display', serif; font-size:26px;
  color:var(--ivory); line-height:1.5; margin:28px 0 14px;
}
.closing-names{
  font-family:'Pinyon Script', cursive;
  font-size:46px; color:var(--gold-light); margin-bottom:28px;
}

/* ============================================================
   GALLERY SLIDESHOW
   ------------------------------------------------------------
   #galleryGrid keeps its id and stays the direct parent of the
   slides, because aira-bind.js writes the couple's photos into
   exactly that element. Only its layout changes: from a 3-up
   grid to a horizontal track that is moved by transform.
   ============================================================ */
.slideshow{
  position:relative; margin-top:30px;
  border-radius:10px; overflow:hidden;
  border:1px solid var(--line);
  background:var(--crimson-deep);
  touch-action:pan-y;
}
.gallery{
  display:flex; grid-template-columns:none; gap:0; margin-top:0;
  transition:transform 720ms cubic-bezier(.4,0,.2,1);
  will-change:transform;
}
.gallery > div{
  flex:0 0 100%; width:100%; aspect-ratio:1/1;
  border-radius:0; border:none;
  display:flex; align-items:center; justify-content:center;
  color:var(--gold-light); font-size:13px;
  background:linear-gradient(135deg,var(--crimson),var(--crimson-deep));
  position:relative; cursor:default;
}
.gallery img{width:100%; height:100%; object-fit:cover; border-radius:0;}

.ss-arrow{
  position:absolute; top:50%; transform:translateY(-50%);
  width:42px; height:42px; border-radius:50%;
  border:1px solid var(--gold); background:rgba(30,2,3,.62);
  color:var(--gold-light); font-size:24px; line-height:1;
  cursor:pointer; z-index:2; padding:0;
  display:flex; align-items:center; justify-content:center;
  transition:background 220ms ease, opacity 220ms ease;
}
.ss-arrow:hover{background:rgba(30,2,3,.9);}
.ss-prev{left:12px;} .ss-next{right:12px;}
.slideshow.ss-single .ss-arrow{display:none;}

.ss-dots{
  display:flex; gap:9px; justify-content:center;
  margin-top:16px; flex-wrap:wrap;
}
.ss-dot{
  width:9px; height:9px; border-radius:50%; padding:0;
  border:1px solid var(--gold); background:transparent;
  cursor:pointer; transition:background 260ms ease, transform 260ms ease;
}
.ss-dot.on{background:var(--gold); transform:scale(1.25);}
.ss-dots:empty{display:none;}

@media (max-width:560px){
  .cd-name{font-size:42px;}
  .cd-amp{font-size:34px; flex-basis:100%;}
  .closing-names{font-size:38px;}
  .ss-arrow{width:36px; height:36px; font-size:20px;}
  .ss-prev{left:8px;} .ss-next{right:8px;}
}

/* The slideshow animates by transform. Anyone who has asked their system
   to reduce motion gets an instant change instead. */
@media (prefers-reduced-motion: reduce){
  .gallery{transition:none;}
}



/* ============================================================
   PAGE FRAME
   ------------------------------------------------------------
   A single gold frame held at the edges of the screen while the
   invitation scrolls behind it, so the whole page reads as one
   card rather than a run of separate blocks.

   border-image slices the drawing into nine and places the four
   corners itself. The slice is 92 because that is exactly where
   the corner artwork ends in the SVG; slicing anywhere else
   leaves part of the flourish in the edge strip, which then
   repeats down the sides as broken fragments.

   The edge strip is two plain parallel rules, so however many
   times it tiles it still reads as one unbroken line.
   ============================================================ */
/* body is the containing block, so the frame is as tall as the whole
   invitation and travels with it rather than staying pinned to the screen. */
body{position:relative;}
.page-frame{
  position:absolute; inset:10px; z-index:40; pointer-events:none;
  border:30px solid transparent;
  border-image:url("./assets/frame.svg") 34 round;
}

@media (max-width:560px){
  .page-frame{inset:6px; border-width:20px;}
  .hero{padding:44px 30px;}
  .hero::after{inset:34px;}
}

/* Printing an invitation should not print a screen-edge frame. */
@media print{ .page-frame{display:none;} }

/* ---- hero names ---- */
.hero h1{
  font-family:'Pinyon Script', cursive;
  font-weight:400;
  font-size:clamp(54px,11.5vw,96px);
  line-height:1.16;
  letter-spacing:.01em;
}
.hero h1 .amp{
  font-family:'Playfair Display', serif;
  font-weight:700; font-size:.34em; letter-spacing:.04em;
}
