:root {
  color-scheme: dark;
  --bg: #1a0710;
  --bg-2: #2b0b1b;
  --rose: #ff3d7a;
  --rose-deep: #c2124f;
  --blush: #ffc2d4;
  --cream: #fff4ee;
  --ink: #3a1222;
  --text: #ffe9f0;
  --muted: rgba(255, 233, 240, .62);
  --serif: "Fraunces", Georgia, "Times New Roman", serif;
  --hand: "Caveat", "Segoe Script", "Bradley Hand", cursive;
  --sans: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
}

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

html { scroll-behavior: smooth; -webkit-tap-highlight-color: transparent; }

body {
  margin: 0;
  min-height: 100svh;
  background: radial-gradient(120% 80% at 50% 0%, var(--bg-2), var(--bg) 60%);
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
body.locked { overflow: hidden; height: 100svh; }

button { font: inherit; color: inherit; border: 0; background: none; cursor: pointer; }
:focus-visible { outline: 2px dashed var(--blush); outline-offset: 6px; border-radius: 8px; }

/* ---------- ambient layers ---------- */
#sky { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }

.glow {
  position: fixed; z-index: 0; pointer-events: none;
  width: 70vmax; height: 70vmax; border-radius: 50%;
  filter: blur(80px); opacity: .35; mix-blend-mode: screen;
}
.glow-a { background: #ff2d6f; top: -30vmax; left: -20vmax; animation: drift-a 22s ease-in-out infinite alternate; }
.glow-b { background: #8a2bff; bottom: -35vmax; right: -25vmax; opacity: .22; animation: drift-b 26s ease-in-out infinite alternate; }
@keyframes drift-a { to { transform: translate(18vmax, 22vmax) scale(1.15); } }
@keyframes drift-b { to { transform: translate(-20vmax, -18vmax) scale(1.1); } }

.grain {
  position: fixed; inset: -50%; z-index: 1; pointer-events: none; opacity: .07;
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  animation: grain 1.2s steps(6) infinite;
}
@keyframes grain {
  0% { transform: translate(0, 0); } 20% { transform: translate(-3%, 2%); }
  40% { transform: translate(2%, -3%); } 60% { transform: translate(-2%, -1%); }
  80% { transform: translate(3%, 3%); } 100% { transform: translate(0, 0); }
}

.fx { position: fixed; inset: 0; z-index: 50; pointer-events: none; overflow: hidden; }
.fx .p {
  position: absolute; left: 0; top: 0;
  will-change: transform, opacity;
  line-height: 1; user-select: none;
}

/* ---------- gate ---------- */
.gate {
  position: fixed; inset: 0; z-index: 20;
  display: grid; place-items: center;
  padding: 24px;
  transition: opacity 1s var(--ease-out), visibility 1s, filter 1s;
}
.gate.gone { opacity: 0; visibility: hidden; filter: blur(12px); }
.gate-inner { display: grid; justify-items: center; gap: 34px; text-align: center; }

.gate-kicker {
  font-family: var(--hand); font-size: clamp(26px, 6vw, 34px); margin: 0; color: var(--blush);
  animation: float-y 4s ease-in-out infinite;
}
.gate-hint {
  display: inline-flex; align-items: center; gap: 10px; margin: 0;
  font-size: 13px; letter-spacing: .28em; text-transform: uppercase; color: var(--muted);
}
.tap-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--rose); box-shadow: 0 0 0 0 rgba(255, 61, 122, .7); animation: ping 1.6s infinite; }
@keyframes ping { 70% { box-shadow: 0 0 0 14px rgba(255, 61, 122, 0); } 100% { box-shadow: 0 0 0 0 rgba(255, 61, 122, 0); } }
@keyframes float-y { 50% { transform: translateY(-8px); } }

/* envelope */
.envelope {
  --w: min(78vw, 300px);
  position: relative; width: var(--w); aspect-ratio: 3 / 2;
  perspective: 900px;
  animation: env-bob 3.2s ease-in-out infinite;
  transition: transform .4s var(--ease-spring);
}
.envelope:hover { transform: scale(1.04) rotate(-1.5deg); }
@keyframes env-bob { 50% { translate: 0 -10px; rotate: 1deg; } }
.envelope > span { position: absolute; inset: 0; border-radius: 10px; }
.env-back { background: linear-gradient(160deg, #e2456f, #a50f43); box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .6), 0 0 80px -10px rgba(255, 61, 122, .45); }
.env-letter {
  inset: 8% 7% 6% !important; background: var(--cream); border-radius: 6px !important;
  z-index: 1;
  display: grid; place-items: start center; padding-top: 12%;
  transition: transform 1s var(--ease-out) .35s;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .15);
}
.env-letter-heart { color: var(--rose); font-size: 28px; }
.env-front {
  background:
    linear-gradient(to top right, rgba(0, 0, 0, .06) 49.6%, transparent 50%) left / 50.5% 100% no-repeat,
    linear-gradient(170deg, #f25a84, #d8386a);
  clip-path: polygon(0 0, 50% 56%, 100% 0, 100% 100%, 0 100%);
  z-index: 2;
}
.env-flap {
  z-index: 3; transform-origin: top center;
  background: linear-gradient(to bottom, #ff6b93, #d9346a);
  clip-path: polygon(0 0, 100% 0, 50% 58%);
  transition: transform .7s var(--ease-out), z-index 0s .35s;
}
.env-seal {
  inset: auto !important; left: 50% !important; top: 52% !important; z-index: 4;
  width: 54px; height: 54px; border-radius: 50% !important; translate: -50% -50%;
  background: radial-gradient(circle at 35% 30%, #ff8db0, var(--rose-deep));
  display: grid; place-items: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .35), inset 0 -3px 6px rgba(0, 0, 0, .25);
  transition: transform .5s var(--ease-out), opacity .4s;
}
.env-seal svg { width: 24px; fill: var(--cream); animation: beat 1.3s ease-in-out infinite; }

.envelope.open { animation: none; }
.envelope.open .env-seal { transform: scale(0) rotate(90deg); opacity: 0; }
.envelope.open .env-flap { transform: rotateX(180deg); z-index: 0; }
.envelope.open .env-letter { transform: translateY(-62%); }

/* ---------- main ---------- */
.main { position: relative; z-index: 2; opacity: 0; transition: opacity 1.2s var(--ease-out); }
.main.show { opacity: 1; }

.section {
  min-height: 100svh;
  padding: clamp(80px, 12vh, 140px) 20px;
  display: grid; place-items: center; align-content: center; gap: 40px;
}

.eyebrow {
  margin: 0; font-size: 12px; letter-spacing: .32em; text-transform: uppercase; color: var(--muted);
}

/* hero */
.hero {
  min-height: 100svh; padding: 80px 20px 40px;
  display: grid; place-items: center; align-content: center; text-align: center; gap: 18px;
  position: relative;
}
.headline {
  margin: 0; font-family: var(--serif); font-weight: 400;
  font-size: clamp(72px, 22vw, 200px); line-height: .88; letter-spacing: -.035em;
  font-variation-settings: "opsz" 144;
}
.headline .line { display: block; }
.headline .accent { font-style: italic; font-weight: 500; padding-bottom: .06em; }
.accent .ch {
  background: linear-gradient(100deg, #ffd0dd 0%, #ff4f86 30%, #ff9ab8 55%, #ffd0dd 80%, #ff4f86 100%);
  background-size: 400% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  padding: 0 .04em .08em;
}
@keyframes shimmer { from { background-position: 0 0; } to { background-position: 400% 0; } }

.ch {
  display: inline-block; opacity: 0;
  transform: translateY(.6em) rotate(8deg) scale(.6);
  filter: blur(10px);
}
[data-split].in .ch {
  animation: ch-in 1.1s var(--ease-out) forwards;
  animation-delay: calc(var(--i) * 70ms + var(--base, .1s));
}
.accent[data-split].in .ch {
  animation: ch-in 1.1s var(--ease-out) forwards, shimmer 6s linear infinite;
  animation-delay: calc(var(--i) * 70ms + var(--base, .1s)), calc(var(--i) * -.3s);
}
@keyframes ch-in { to { opacity: 1; transform: none; filter: blur(0); } }
.ch.sp { width: .26em; }

.beat-wrap { margin-top: 8px; }
.beat { width: 46px; fill: var(--rose); filter: drop-shadow(0 0 18px rgba(255, 61, 122, .9)); animation: beat 1.2s ease-in-out infinite; }
@keyframes beat {
  0%, 100% { transform: scale(1); }
  15% { transform: scale(1.22); }
  30% { transform: scale(.96); }
  45% { transform: scale(1.14); }
  60% { transform: scale(1); }
}

.sub { margin: 4px 0 0; min-height: 1.6em; font-family: var(--hand); font-size: clamp(24px, 5.2vw, 34px); color: var(--blush); }
.caret { display: inline-block; margin-left: 2px; color: var(--rose); animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

.scroll-cue {
  position: absolute; bottom: max(28px, env(safe-area-inset-bottom)); left: 50%; translate: -50% 0;
  display: grid; justify-items: center; gap: 10px;
  color: var(--muted); text-decoration: none; font-size: 11px; letter-spacing: .3em; text-transform: uppercase;
}
.scroll-cue i { width: 1px; height: 44px; background: linear-gradient(var(--blush), transparent); position: relative; overflow: hidden; }
.scroll-cue i::after { content: ""; position: absolute; left: 0; top: -40%; width: 100%; height: 40%; background: var(--cream); animation: drip 1.8s var(--ease-out) infinite; }
@keyframes drip { to { top: 110%; } }

/* reveal helpers */
.reveal { opacity: 0; transform: translateY(14px); }
.show .reveal { animation: rise 1s var(--ease-out) forwards; animation-delay: var(--d, 0s); }
@keyframes rise { to { opacity: 1; transform: none; } }

.reveal-up { opacity: 0; transform: translateY(50px) scale(.97); filter: blur(6px); transition: opacity 1.1s var(--ease-out), transform 1.1s var(--ease-out), filter 1.1s var(--ease-out); transition-delay: var(--d, 0s); }
.reveal-up.in { opacity: 1; transform: none; filter: none; }

/* letter */
.paper {
  position: relative; width: min(100%, 620px);
  background:
    repeating-linear-gradient(transparent 0 37px, rgba(194, 18, 79, .09) 37px 38px),
    linear-gradient(170deg, #fffaf6, var(--cream));
  color: var(--ink);
  padding: clamp(36px, 7vw, 64px) clamp(26px, 6vw, 56px);
  border-radius: 4px;
  box-shadow: 0 50px 90px -30px rgba(0, 0, 0, .7), 0 0 0 1px rgba(255, 255, 255, .4) inset;
  rotate: -1.2deg;
}
.paper.in { animation: paper-sway 9s ease-in-out infinite 1.2s; }
@keyframes paper-sway { 50% { rotate: .6deg; } }
.tape {
  position: absolute; top: -14px; left: 50%; translate: -50% 0; rotate: 3deg;
  width: 120px; height: 30px; background: rgba(255, 182, 204, .7);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .12);
  clip-path: polygon(3% 0, 97% 4%, 100% 100%, 0 96%);
}
.hand { font-family: var(--hand); }
.greet { font-size: clamp(34px, 7vw, 46px); margin: 0 0 12px; color: var(--rose-deep); }
.letter-body p {
  font-family: var(--serif); font-size: clamp(17px, 3.6vw, 20px); line-height: 1.9; margin: 0 0 1em;
}
.letter-body .w { opacity: 0; display: inline-block; transform: translateY(6px); filter: blur(4px); transition: opacity .5s, transform .5s var(--ease-out), filter .5s; }
.letter-body .w.in { opacity: 1; transform: none; filter: none; }
.sign { font-size: clamp(28px, 6vw, 38px); margin: 18px 0 0; text-align: right; color: var(--rose-deep); opacity: 0; transform: translateX(20px); transition: opacity 1s, transform 1s var(--ease-out); }
.sign.in { opacity: 1; transform: none; }

/* section heads */
.sec-head { text-align: center; display: grid; gap: 14px; }
.sec-head h2 {
  margin: 0; font-family: var(--serif); font-weight: 400;
  font-size: clamp(36px, 8vw, 68px); line-height: 1.02; letter-spacing: -.02em;
}
.sec-head em { font-style: italic; color: var(--rose); }

/* cards */
.cards {
  width: min(100%, 980px);
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px;
}
@media (min-width: 760px) { .cards { grid-template-columns: repeat(3, 1fr); gap: 22px; } }
.card {
  position: relative; aspect-ratio: 3 / 4; perspective: 1000px; text-align: center;
  opacity: 0; transform: translateY(60px) rotate(var(--r, 0deg));
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
  transition-delay: calc(var(--i) * 90ms);
}
.card.in { opacity: 1; transform: translateY(0) rotate(var(--r, 0deg)); }
.card-in {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform: translateY(var(--lift, 0)) rotateY(var(--flip, 0deg));
  transition: transform .9s var(--ease-spring);
}
.card.flipped { --flip: 180deg; }
@media (hover: hover) { .card:hover { --lift: -8px; } }
.face {
  position: absolute; inset: 0; border-radius: 22px;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  display: grid; place-items: center; align-content: center; gap: 12px; padding: 16px;
}
.face.front {
  background: linear-gradient(155deg, rgba(255, 255, 255, .12), rgba(255, 255, 255, .03));
  border: 1px solid rgba(255, 194, 212, .22);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, .6);
}
.face.front .num { font-family: var(--serif); font-style: italic; font-size: clamp(44px, 10vw, 64px); line-height: 1; color: var(--rose); }
.face.front .lbl { font-size: 11px; letter-spacing: .3em; text-transform: uppercase; color: var(--muted); }
.face.back {
  transform: rotateY(180deg);
  background: linear-gradient(155deg, #ff6c98, #c2124f);
  box-shadow: 0 24px 60px -20px rgba(255, 61, 122, .7);
  font-family: var(--hand); font-size: clamp(22px, 5.4vw, 32px); line-height: 1.15; color: #fff;
}

/* tapper */
.tapper-sec { gap: 26px; }
.big-heart {
  position: relative; width: min(58vw, 240px); aspect-ratio: 32 / 29;
  transition: transform .25s var(--ease-spring);
  touch-action: manipulation;
}
.big-heart svg { width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 20px 40px rgba(255, 61, 122, .55)); animation: beat 1.4s ease-in-out infinite; }
.big-heart.in { transform: scale(var(--s, 1)); }
.big-heart:active svg { animation-play-state: paused; }
.big-heart.pop { animation: pop .35s var(--ease-spring); }
@keyframes pop { 40% { transform: scale(calc(var(--s, 1) * .86)); } }
.ring { position: absolute; inset: -10%; border-radius: 50%; border: 2px solid var(--rose); opacity: 0; pointer-events: none; }
.ring.go { animation: ring .7s var(--ease-out); }
@keyframes ring { from { opacity: .9; transform: scale(.6); } to { opacity: 0; transform: scale(1.5); } }

.counter { margin: 0; font-family: var(--serif); font-size: clamp(56px, 12vw, 92px); line-height: 1; display: flex; align-items: baseline; gap: 12px; font-variant-numeric: tabular-nums; }
.counter small { font-family: var(--hand); font-size: .4em; color: var(--blush); }
.counter span { display: inline-block; }
.counter span.bump { animation: bump .3s var(--ease-spring); }
@keyframes bump { 50% { transform: translateY(-10px) scale(1.15); color: var(--rose); } }
.tap-msg { margin: 0; font-family: var(--hand); font-size: clamp(24px, 5vw, 30px); color: var(--blush); min-height: 1.3em; text-align: center; transition: opacity .3s; }
.tap-msg.swap { opacity: 0; }
.meter { width: min(80vw, 320px); height: 6px; border-radius: 99px; background: rgba(255, 255, 255, .1); overflow: hidden; }
.meter i { display: block; height: 100%; width: 0; border-radius: inherit; background: linear-gradient(90deg, var(--blush), var(--rose)); box-shadow: 0 0 14px var(--rose); transition: width .5s var(--ease-out); }

/* finale */
.finale { text-align: center; gap: 30px; }
.draw-heart { width: min(64vw, 280px); overflow: visible; }
.draw-heart path {
  fill: rgba(255, 61, 122, 0); stroke: var(--rose); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 0 10px rgba(255, 61, 122, .8));
  transition: stroke-dashoffset 2.6s cubic-bezier(.65, 0, .35, 1), fill 1.2s ease 2.4s;
}
.draw-heart.in path { stroke-dashoffset: 0 !important; fill: rgba(255, 61, 122, .9); }
.draw-heart.in { animation: beat 1.6s ease-in-out infinite 3.6s; }
.finale-text { margin: 0; font-weight: 400; display: grid; gap: 14px; }
.finale-text .big { font-size: clamp(56px, 13vw, 120px); line-height: 1; color: var(--cream); text-shadow: 0 0 40px rgba(255, 61, 122, .6); }
.finale-sub { font-family: var(--serif); font-style: italic; font-size: clamp(18px, 3.8vw, 24px); color: var(--muted); }

.kiss-btn {
  position: relative; display: inline-flex; align-items: center; gap: 12px;
  padding: 18px 30px; border-radius: 99px;
  background: linear-gradient(120deg, var(--rose), var(--rose-deep));
  font-weight: 500; letter-spacing: .04em; color: #fff;
  box-shadow: 0 16px 40px -12px rgba(255, 61, 122, .8), inset 0 1px 0 rgba(255, 255, 255, .3);
  overflow: hidden;
  transition: transform .35s var(--ease-spring), box-shadow .35s, opacity 1.1s var(--ease-out), filter 1.1s var(--ease-out);
}
.kiss-btn::before { content: ""; position: absolute; inset: 0; background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .45) 50%, transparent 70%); transform: translateX(-120%); animation: sheen 3.2s ease-in-out infinite; }
@keyframes sheen { 60%, 100% { transform: translateX(120%); } }
.kiss-btn svg { width: 18px; fill: #fff; animation: beat 1.2s ease-in-out infinite; }
.kiss-btn.in:hover { transform: translateY(-3px) scale(1.04); box-shadow: 0 22px 50px -12px rgba(255, 61, 122, .95); }
.kiss-btn.in:active { transform: scale(.96); }
.kiss-note { margin: 0; min-height: 1.4em; font-family: var(--hand); font-size: 28px; color: var(--blush); }

.foot { position: relative; z-index: 2; text-align: center; padding: 40px 20px calc(40px + env(safe-area-inset-bottom)); color: var(--muted); font-size: 13px; letter-spacing: .06em; }
.foot p { margin: 4px 0; }
.since { font-family: var(--hand); font-size: 20px; color: var(--blush); }

/* ---------- flying face ---------- */
.flyer {
  --size: clamp(78px, 20vw, 120px);
  position: fixed; left: 0; top: 0; z-index: 40;
  width: var(--size); height: var(--size);
  pointer-events: none; user-select: none;
  will-change: transform;
  opacity: 0; transition: opacity .4s;
}
.flyer.on { opacity: 1; }
.flyer-spin { width: 100%; height: 100%; will-change: transform; }
.flyer-spin img {
  width: 100%; height: 100%; display: block; border-radius: 50%;
  border: 3px solid #fff;
  box-shadow: 0 0 0 4px var(--rose), 0 14px 34px -8px rgba(0, 0, 0, .6), 0 0 40px rgba(255, 61, 122, .6);
}
.flyer-bubble {
  position: absolute; left: 50%; bottom: calc(100% + 14px);
  translate: -50% 0; white-space: nowrap;
  padding: 8px 14px; border-radius: 16px;
  background: var(--cream); color: var(--rose-deep);
  font-family: var(--hand); font-size: 22px; line-height: 1;
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, .5);
  opacity: 0; transform: translateY(8px) scale(.8);
  transition: opacity .25s, transform .35s var(--ease-spring);
}
.flyer-bubble::after {
  content: ""; position: absolute; left: 50%; top: 100%; translate: -50% -1px;
  border: 8px solid transparent; border-top-color: var(--cream);
}
.flyer-bubble.show { opacity: 1; transform: none; }

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; transition-delay: 0s !important; }
  .grain { display: none; }
}
.flyer-bubble.below { bottom: auto; top: calc(100% + 14px); }
.flyer-bubble.below::after { top: auto; bottom: 100%; translate: -50% 1px; border-top-color: transparent; border-bottom-color: var(--cream); }
