:root {
  --col: 480px;
  --gold: #c4a063;
  --gold-d: #9c7a45;
  --burgundy: #6a1626;
  --ink: #5a4134;
  --ink-soft: #8a6d5d;
  --script: 'Pinyon Script', 'Great Vibes', cursive;
  --serif: 'Cormorant Garamond', 'Cormorant', Garamond, Georgia, serif;
}

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

html {
  background: #1b0e08;
  -webkit-text-size-adjust: 100%;
  transition: background-color 1.6s ease;
}
html.opened { background: #e7d6c4; scroll-behavior: smooth; }
html.locked, html.locked body { overflow: hidden; height: 100%; }

body {
  margin: 0;
  font-family: var(--serif);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

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

#stage {
  position: relative;
  max-width: var(--col);
  margin: 0 auto;
  overflow-x: clip;
  background: #fbf3ea;
  box-shadow: 0 0 90px rgba(40, 20, 10, .28);
}

/* ---------- scene 2: hero ---------- */

.hero {
  position: relative;
  z-index: 1;
  height: 100svh;
  min-height: 540px;
  overflow: hidden;
  background: #e6d4be;
}
/* Covers the screen, but never zooms past 12% beyond fitting the height, so the arch's tip stays in view. */
.art {
  position: absolute;
  left: 50%;
  top: 50%;
  width: clamp(calc(100svh * 400 / 820), 100%, calc(100svh * 448 / 820));
  aspect-ratio: 400 / 820;
  transform: translate(-50%, -50%);
  container-type: inline-size;
}
.cam { position: absolute; inset: 0; transform-origin: 50% 42%; }
.layer { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; will-change: transform; }

.hero-text { position: absolute; inset: 0; text-align: center; color: var(--burgundy); pointer-events: none; }
.hero-text > * { position: absolute; left: 0; right: 0; margin: 0; opacity: 0; }
.kicker { top: 20.6%; font: 400 8.2cqw/1 var(--script); }
.date { top: 27.5%; font: 500 4.4cqw/1 var(--serif); letter-spacing: .22em; padding-left: .22em; color: var(--ink); }
.names { top: 33.4%; font: 400 18cqw/.98 var(--script); opacity: 1; }
.names span { display: block; opacity: 0; }
.names .amp { font: italic 400 .44em/1.3 var(--serif); color: #9a6a4c; }
.scroll-cue {
  top: 61.6%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.4cqw;
  font: 400 5.4cqw/1 var(--script);
  color: #7a3434;
  text-decoration: none;
  pointer-events: auto;
}
.scroll-cue svg { width: 5.2cqw; height: 3cqw; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; animation: nudge 2.4s ease-in-out infinite; }

html.opened .cam { animation: settle 3.6s cubic-bezier(.2, .65, .2, 1) both; }
html.opened .kicker { animation: rise 1.4s .5s both; }
html.opened .date { animation: rise 1.4s .85s both; }
html.opened .n1 { animation: write 1.9s 1.25s cubic-bezier(.5, .1, .3, 1) both; }
html.opened .names .amp { animation: rise 1.2s 2.55s both; }
html.opened .n2 { animation: write 1.6s 2.85s cubic-bezier(.5, .1, .3, 1) both; }
html.opened .scroll-cue { animation: rise 1.2s 4.2s both; }

.motes i {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, #fff7dc 0, rgba(246, 206, 130, .7) 40%, rgba(240, 190, 110, 0) 72%);
  animation: mote var(--t) linear var(--delay) infinite;
}

.shim { animation: shim 7s ease-in-out infinite alternate; }
.shim.s1 { animation-duration: 9s; animation-delay: -3s; }
.shim.s2 { animation-duration: 11s; animation-delay: -6s; }
.bob { animation: bob 6.5s ease-in-out infinite; }

/* ---------- paper sections ---------- */

.paper {
  --paper: #fbf3ea;
  position: relative;
  padding: 96px 30px 104px;
  text-align: center;
  background-color: var(--paper);
  background-image: var(--grain), radial-gradient(130% 55% at 15% 0%, rgba(255, 255, 255, .55), transparent 60%), radial-gradient(90% 60% at 100% 100%, rgba(232, 196, 176, .22), transparent 70%);
  background-size: 110px 110px, auto, auto;
}
.invite { --paper: #fcf3ea; z-index: 2; }
.countdown { --paper: #f8eee3; z-index: 3; padding-top: 104px; padding-bottom: 108px; }
.schedule { --paper: #fbf4eb; z-index: 4; }
.venue { --paper: #f5e0d1; z-index: 5; }
.finale { --paper: #fbf4ec; z-index: 6; }

.tear {
  position: absolute;
  left: 0;
  right: 0;
  top: -25px;
  height: 28px;
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 -2px 2.5px rgba(80, 48, 30, .2));
}
.tear i {
  position: absolute;
  inset: 0;
  background-color: var(--paper);
  background-image: var(--grain);
  background-size: 110px 110px;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
.tear .fibre { position: absolute; inset: 0; width: 100%; height: 100%; filter: blur(.35px); }

.content { position: relative; z-index: 2; max-width: 310px; margin: 0 auto; }

.script { font-family: var(--script); font-weight: 400; color: var(--burgundy); margin: 0; line-height: 1.08; }
.heading { font-size: 40px; }
.lead { margin: 0 0 18px; font: italic 400 21px/1.4 var(--serif); }
.body { margin: 26px 0 0; font: 400 20px/1.5 var(--serif); }
.name { font-size: 48px; }
.parent { margin: 8px 0 0; font: 500 17px/1.35 var(--serif); }
.parent span {
  display: block;
  margin-bottom: 3px;
  font-size: 11px;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.invite .amp { margin: 14px 0 4px; font: italic 400 30px/1 var(--serif); color: var(--gold-d); }
.couple .amp { font: italic 400 .5em/1 var(--serif); color: var(--gold-d); vertical-align: .18em; }
.divider { width: 200px; margin: 30px auto 0; }
.divider.small { width: 150px; margin-top: 12px; }
.divider svg, .ornament svg, .heart svg, .corner svg { display: block; width: 100%; height: auto; overflow: visible; }

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 1.15s ease, transform 1.15s cubic-bezier(.2, .7, .2, 1);
  transition-delay: var(--d, 0s);
}
[data-reveal].in { opacity: 1; transform: none; }

.flora, .emboss, .border { position: absolute; z-index: 1; pointer-events: none; line-height: 0; }
.flora svg, .emboss svg, .border svg { display: block; overflow: visible; }
.flora.tl, .emboss.tl { top: 0; left: 0; }
.flora.tr, .emboss.tr { top: 0; right: 0; }
.flora.bl, .emboss.bl { bottom: 0; left: 0; }
.flora.br, .emboss.br { bottom: 0; right: 0; }
.emboss { margin: 8px; opacity: .85; }
.emboss svg { width: 96px; height: 96px; }

.petal {
  position: absolute;
  top: -24px;
  z-index: 1;
  width: 16px;
  height: 16px;
  pointer-events: none;
  opacity: 0;
  animation: fall var(--t) linear var(--delay) infinite;
}
.petal svg { display: block; width: 100%; height: 100%; }

/* ---------- scene 4: countdown ---------- */

.count { display: flex; justify-content: center; align-items: flex-start; margin-top: 30px; }
.unit { display: flex; flex-direction: column; align-items: center; min-width: 62px; }
.num {
  font: 300 47px/1 var(--serif);
  font-variant-numeric: lining-nums tabular-nums;
  background: linear-gradient(180deg, #e7cf99 0%, #c29a58 46%, #8d6732 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 1px 0 rgba(255, 255, 255, .8));
}
.sep { font: 300 38px/1.08 var(--serif); color: var(--gold); }
.lbl { margin-top: 10px; font: 500 11px/1 var(--serif); letter-spacing: .22em; text-transform: uppercase; color: var(--ink-soft); }
.when { margin: 26px 0 0; font: italic 400 18px/1.45 var(--serif); }
.arrived-note { display: none; margin: 18px 0 0; font: italic 400 20px/1.4 var(--serif); color: var(--burgundy); }
.countdown.arrived .arrived-note { display: block; }

/* ---------- scene 5: schedule ---------- */

.day { margin: 14px 0 0; font: 500 13px/1.6 var(--serif); letter-spacing: .26em; text-transform: uppercase; color: var(--ink-soft); }
.timeline { position: relative; margin: 22px -16px 0; padding: 80px 0 60px; }
.timeline::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 62px;
  bottom: 36px;
  width: 1px;
  margin-left: -.5px;
  background: linear-gradient(to bottom, rgba(196, 160, 99, 0), #c4a063 14%, #c4a063 86%, rgba(196, 160, 99, 0));
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 1.9s cubic-bezier(.4, 0, .2, 1) .45s;
}
.timeline.in::before { transform: scaleY(1); }
.tl-rose, .tl-bud { position: absolute; left: 50%; z-index: 1; }
.tl-rose { top: 0; width: 70px; margin-left: -35px; }
.tl-bud { bottom: 0; width: 44px; margin-left: -22px; }
.tl-rose svg, .tl-bud svg { display: block; width: 100%; height: auto; overflow: visible; }
.events { list-style: none; margin: 0; padding: 0; }
.events li { display: grid; grid-template-columns: 1fr 36px 1fr; align-items: center; padding: 20px 0; }
.events time { text-align: right; font: 400 27px/1 var(--serif); }
.node {
  justify-self: center;
  width: 9px;
  height: 9px;
  transform: rotate(45deg);
  background: linear-gradient(135deg, #f2dca7, #ae8646);
  box-shadow: 0 0 0 5px var(--paper);
}
.what { text-align: left; font: 500 19px/1.25 var(--serif); white-space: nowrap; }

/* ---------- scene 6: venue ---------- */

.venue-name { margin: 22px 0 6px; font: 500 25px/1.25 var(--serif); letter-spacing: .03em; color: var(--burgundy); }
address { font: normal 400 19px/1.5 var(--serif); }
.venue .when { margin-top: 14px; }
.map {
  position: relative;
  margin: 28px 0 0;
  padding: 9px;
  border: 1px solid rgba(196, 160, 99, .85);
  background: rgba(255, 250, 244, .6);
  box-shadow: 0 12px 30px rgba(90, 55, 35, .14);
}
.map::before { content: ''; position: absolute; inset: 4px; border: 1px solid rgba(196, 160, 99, .45); pointer-events: none; }
.map iframe { display: block; width: 100%; height: 270px; border: 0; filter: sepia(.14) saturate(.92); }
.map .corner { position: absolute; width: 30px; height: 30px; pointer-events: none; }
.map .c1 { top: -9px; left: -9px; }
.map .c2 { top: -9px; right: -9px; transform: scaleX(-1); }
.map .c3 { bottom: -9px; left: -9px; transform: scaleY(-1); }
.map .c4 { bottom: -9px; right: -9px; transform: scale(-1); }
.actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 24px; }
.btn {
  display: inline-block;
  padding: 13px 20px 12px;
  border: 1px solid var(--gold);
  border-radius: 999px;
  font: 600 12px/1 var(--serif);
  letter-spacing: .2em;
  text-transform: uppercase;
  text-decoration: none;
  color: #fff8ee;
  background: linear-gradient(180deg, #7a2232, #5c1220);
  box-shadow: 0 6px 16px rgba(92, 18, 32, .22), inset 0 1px 0 rgba(255, 220, 200, .25);
}
.btn.ghost { color: var(--burgundy); background: rgba(255, 250, 244, .55); box-shadow: none; }
.border { top: 18px; bottom: 18px; width: 40px; }
.border.l { left: 0; }
.border.r { right: 0; }

/* ---------- scene 7: finale ---------- */

.finale { display: flex; align-items: center; justify-content: center; min-height: 100svh; padding-bottom: 120px; }
.ornament { width: 130px; margin: 0 auto 24px; }
.couple { margin: 4px 0 16px; font-size: 58px; }
.heart { width: 32px; margin: 38px auto 0; }
.heart span { display: block; animation: glow 3.4s ease-in-out infinite; }

/* ---------- scene 1: envelope ---------- */

#envelope {
  position: fixed;
  inset: 0;
  z-index: 50;
  width: min(100%, var(--col));
  margin: 0 auto;
  overflow: hidden;
  background: #1b0e08;
  cursor: pointer;
  touch-action: none;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 1.3s ease;
}
#envelope.gone { opacity: 0; pointer-events: none; }
.env-inside {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 70% 60% at 50% 50%, #fff7e4 0%, #f6d39a 22%, #c98a4f 48%, #6b3b22 75%, #2f170d 100%);
  opacity: 0;
  transition: opacity 1.2s ease 1.5s;
}
.opening .env-inside { opacity: 1; }
.env-canvas, .sparks { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.env-canvas { opacity: 0; transition: opacity 1.4s ease; }
#envelope.ready .env-canvas { opacity: 1; }

.seal {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 27%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  opacity: 0;
  filter: drop-shadow(0 5px 7px rgba(0, 0, 0, .5));
  transition: opacity 1.4s ease, filter 1.4s ease;
  will-change: transform;
}
.seal svg { display: block; width: 100%; height: 100%; overflow: visible; }
.opening .seal { filter: drop-shadow(0 4px 6px rgba(0, 0, 0, .3)) drop-shadow(0 0 16px rgba(255, 214, 150, .95)); }
.seal-sheen { transform: translateX(-130%); transform-box: fill-box; }
.opening .seal-sheen { animation: sheen 1.5s ease-in-out .15s both; }

.env-hint {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% + var(--w, 390px) * .22);
  margin: 0;
  text-align: center;
  font: italic 500 16px/1 var(--serif);
  letter-spacing: .12em;
  color: #f0dcb2;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .8);
  opacity: 0;
  pointer-events: none;
  transition: opacity .6s ease;
}
.env-hint::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: -1;
  width: 250px;
  height: 52px;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(22, 10, 5, .8), rgba(22, 10, 5, 0));
}
#envelope.ready .env-hint { animation: hint 2.8s ease-in-out 1.4s infinite both; }
#envelope.opening .env-hint { animation: none; opacity: 0; }
.bloom {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, #fffaf1 0%, #fdeedb 45%, #f6dcc4 100%);
  opacity: 0;
  pointer-events: none;
}
.opening .bloom { opacity: 1; transition: opacity 1.25s ease-in 3.2s; }

/* ---------- keyframes ---------- */

@keyframes sheen { from { transform: translateX(-130%); } to { transform: translateX(130%); } }
@keyframes hint { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes settle { from { transform: scale(1.1); } to { transform: none; } }
@keyframes rise { from { opacity: 0; transform: translateY(.9em); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
@keyframes write {
  from { opacity: 1; -webkit-clip-path: inset(-25% 104% -25% -10%); clip-path: inset(-25% 104% -25% -10%); }
  to { opacity: 1; -webkit-clip-path: inset(-25% -10% -25% -10%); clip-path: inset(-25% -10% -25% -10%); }
}
@keyframes nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@keyframes shim { from { transform: translateX(-5px); opacity: .7; } to { transform: translateX(6px); opacity: 1; } }
@keyframes bob { 50% { transform: translateY(1.6px); } }
@keyframes glow {
  0%, 100% { filter: drop-shadow(0 0 2px rgba(240, 200, 120, .45)); transform: scale(1); }
  50% { filter: drop-shadow(0 0 11px rgba(246, 206, 128, .95)); transform: scale(1.07); }
}
@keyframes mote {
  0% { transform: translate3d(0, 0, 0); opacity: 0; }
  15% { opacity: .9; }
  85% { opacity: .7; }
  100% { transform: translate3d(var(--dx), -140px, 0); opacity: 0; }
}
@keyframes fall {
  0% { transform: translate3d(0, 0, 0) rotate(0deg) scale(var(--s)); opacity: 0; }
  10% { opacity: .9; }
  50% { transform: translate3d(var(--sway), calc(var(--fall) * .5), 0) rotate(calc(var(--spin) * .5)) scale(var(--s)); }
  90% { opacity: .8; }
  100% { transform: translate3d(0, var(--fall), 0) rotate(var(--spin)) scale(var(--s)); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html.opened { scroll-behavior: auto; }
  .shim, .bob, .scroll-cue svg, .heart span, .motes i, .petal { animation: none !important; }
  html.opened .cam { animation: none; }
  html.opened .hero-text > *, html.opened .hero-text .names span { animation: rise .8s both !important; }
  [data-reveal] { transform: none; transition-duration: .6s; }
}
