:root {
  --paper: #f7f3ee;
  --ink: #5b483f;
  --ink-soft: #6d564c;
  --blush: #e7b2aa;
  --blush-deep: #d98984;
  --rose: #c46d68;
  --gold: #c6a15e;
  --line: #f0d4cd;
  --script: "Invite Script", "Segoe Script", "Brush Script MT", cursive;
  --latin: "Invite Latin", "Palatino Linotype", Palatino, Georgia, serif;
  --serif: "Invite Serif", "Palatino Linotype", "Songti SC", "STSong", "PMingLiU", "SimSun", serif;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; height: 100%; }
body {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  color: var(--ink);
  font-family: var(--serif);
  background:
    radial-gradient(1200px 700px at 50% 0%, #f4f0ea, #e4ded7 72%);
  -webkit-tap-highlight-color: transparent;
}
button, input { font-family: inherit; }
button { cursor: pointer; }
a { color: inherit; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.stage {
  width: min(100vw, 440px);
  height: 100dvh;
  position: relative;
  overflow: hidden;
  background: var(--paper);
  box-shadow: 0 24px 70px rgba(72, 52, 40, 0.16);
}
.paper,
.slide::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.45;
  background-image: radial-gradient(rgba(150, 116, 90, 0.18) 0.55px, transparent 0.6px);
  background-size: 3px 3px;
  z-index: 0;
}
.deck {
  height: 100%;
  transform: translateY(0);
  transition: transform 0.72s cubic-bezier(0.77, 0, 0.18, 1);
}
.slide {
  height: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 13% 9% 12%;
  text-align: center;
  overflow: hidden;
}
.slide > *:not(.pos) { position: relative; z-index: 2; }

.pos { position: absolute; pointer-events: none; z-index: 1; }
.pos.front { z-index: 4; }
.pos svg { width: 100%; height: auto; display: block; }
.pos.tl { top: -18px; left: -28px; width: 68%; }
.pos.tr { top: -22px; right: -36px; width: 62%; }
.pos.bl { bottom: -28px; left: -40px; width: 86%; }
.pos.br { bottom: -24px; right: -32px; width: 74%; }
.pos.top { top: -36px; left: -8%; width: 116%; }
.pos.bottom { bottom: -34px; left: -10%; width: 120%; }
.pos.side { top: 8%; right: -48px; width: 46%; }
.pos.top svg { transform: scaleY(-1); }
.pos.tr svg, .pos.br svg, .pos.side svg { transform: scaleX(-1); }

.script-xl, .script-md, .script-sm, .whisper { font-family: var(--script); font-weight: 400; color: #6d574c; }
.script-xl { font-size: clamp(46px, 12vw, 64px); line-height: 0.9; }
.script-md { font-size: clamp(34px, 8.4vw, 46px); line-height: 1; }
.script-sm { font-size: clamp(20px, 5vw, 26px); line-height: 1.15; }
.whisper { font-size: clamp(16px, 4vw, 20px); color: #8a7368; margin: 0; }
.latin {
  font-family: var(--latin);
  letter-spacing: 0.14em;
  font-weight: 500;
}
.body {
  margin: 0;
  max-width: 20em;
  font-size: 14.5px;
  line-height: 1.95;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.sub {
  margin: 8px 0 0;
  font-size: 15px;
  letter-spacing: 0.12em;
}

.crest {
  width: min(78vw, 280px);
  height: 250px;
  position: relative;
  display: grid;
  place-items: center;
  margin-bottom: 6px;
}
.diamond {
  position: absolute;
  left: 50%;
  top: 50%;
  border: 1px solid rgba(198, 146, 124, 0.82);
  transform: translate(-50%, -50%) rotate(45deg);
}
.d1 { width: 124px; height: 124px; }
.d2 { width: 156px; height: 156px; }
.d3 { width: 190px; height: 190px; }
.crest-copy { position: relative; z-index: 3; }
.crest-copy h1 {
  margin: 6px 0 0;
  font-size: 31px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-indent: 0.28em;
}
.crest .bud { position: absolute; width: 48%; z-index: 2; }
.crest .bud.a { left: -8%; top: 4%; }
.crest .bud.b { right: -10%; top: 0; transform: scaleX(-1); }
.crest .bud.c { left: -12%; bottom: 0; transform: scaleY(-1); }
.crest .bud.d { right: -12%; bottom: -4%; transform: scale(-1); }

.names {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0 12px;
  font-size: 18px;
  letter-spacing: 0.04em;
}
.names svg { width: 22px; height: 22px; }
.when {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 10px;
}
.when span { font-size: 16px; letter-spacing: 0.16em; }
.when strong { font-size: 30px; font-weight: 500; letter-spacing: 0.04em; }
.when i { width: 1px; height: 14px; background: #cbb6aa; display: block; }
.clock { margin: 0 0 8px; letter-spacing: 0.08em; font-size: 13px; color: var(--ink-soft); }

.letter .kicker { margin: 0 0 4px; }
.letter .date-line {
  margin: 16px 0 14px;
  letter-spacing: 0.16em;
  font-size: 15px;
}
.letter .place { margin-top: 16px; letter-spacing: 0.14em; line-height: 1.8; }
.letter .enjoy { margin-top: 18px; }

.who {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 12px;
  margin-bottom: 12px;
}
.who .name { font-size: 22px; letter-spacing: 0.18em; }

.frame {
  margin: 0;
  border: 7px solid var(--line);
  background: #f4ebe4;
  overflow: hidden;
  width: 100%;
  min-height: 0;
}
.frame svg, .frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.letter { padding-top: 11%; padding-bottom: 16%; }
.letter-photo,
.frame.portrait,
.person-extra,
.banner,
.ring { flex-shrink: 0; }
.letter-photo {
  width: min(78%, 250px);
  aspect-ratio: 3 / 2;
  min-height: 150px;
  margin: 8px 0 4px;
}
.frame.portrait {
  width: min(calc(48% + 50px), 222px);
}
.person-extra {
  width: min(100%, 340px);
}
.person .frame img,
.album .frame img,
.locate .frame img {
  width: 100%;
  height: auto;
  object-fit: contain;
}
.person, .album, .mosaic, .story { gap: 10px; justify-content: flex-start; padding-top: 14%; }
.person .body, .album .body, .story .body { margin-top: 0; }
.person .body { font-size: 13.5px; line-height: 1.7; }
.person .whisper { line-height: 1.25; }

.pair, .trio, .mosaic-grid {
  width: 100%;
  flex: 1;
  min-height: 0;
  display: grid;
  gap: 8px;
}
.pair { grid-template-columns: 1fr 1fr; max-height: 46%; flex: none; width: 100%; aspect-ratio: 1.15 / 1; }
.album .banner,
.locate .banner { width: 100%; height: auto; aspect-ratio: auto; }
.album .pair { aspect-ratio: auto; max-height: none; height: auto; align-items: start; }
.album .pair .frame { height: auto; }
.trio { grid-template-columns: 1fr 1fr; grid-template-rows: 1.15fr 0.9fr; }
.trio .wide { grid-column: 1 / -1; }
.mosaic-grid {
  grid-template-columns: 1.2fr 0.8fr;
  grid-template-rows: 1.05fr 0.72fr 0.72fr;
}
.mosaic-grid .wide { grid-column: 1 / -1; }
.mosaic-grid .tall { grid-row: 2 / span 2; }
.album { padding-top: 14%; }
.album .script-md, .mosaic .script-md, .story .script-md { margin: 0; }
.album .whisper, .story .whisper { margin-bottom: 2px; }

.locate { justify-content: flex-start; padding-top: 12%; gap: 8px; }
.locate .script-xl { font-size: clamp(40px, 10vw, 52px); }
.locate .banner { width: min(100%, 320px); }
.map-card {
  width: min(100%, 320px);
  background: #fff;
  border: 6px solid #f3d7d1;
  box-shadow: 0 10px 24px rgba(90, 60, 50, 0.06);
}
.map-draw { height: 112px; background: #e7eef3; }
.map-draw svg { width: 100%; height: 100%; display: block; }
.map-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 10px 12px;
  text-align: left;
}
.map-meta strong, .map-meta p { display: block; margin: 0; }
.map-meta strong { font-size: 14px; letter-spacing: 0.04em; }
.map-meta p { margin-top: 3px; font-size: 12px; color: #8a7368; letter-spacing: 0.02em; }
.go {
  flex: none;
  text-decoration: none;
  background: #3d7fe8;
  color: #fff;
  border-radius: 999px;
  padding: 7px 12px;
  font-size: 13px;
  letter-spacing: 0.06em;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.nav-sheet {
  position: absolute;
  inset: 0;
  z-index: 8;
}
.nav-mask {
  position: absolute;
  inset: 0;
  border: 0;
  background: rgba(72, 52, 40, 0.35);
}
.nav-panel {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom));
  display: grid;
  gap: 8px;
}
.nav-panel button {
  height: 46px;
  border: 0;
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  font-size: 15px;
  letter-spacing: 0.12em;
}
.nav-panel button[data-nav="cancel"] { color: #8a7368; }
.facts { letter-spacing: 0.08em; line-height: 2; font-size: 15px; }
.facts p { margin: 0; }

.thanks { justify-content: flex-start; padding-top: 14%; gap: 8px; }
.thanks .body { margin-bottom: 8px; }
.rsvp-card { width: min(100%, 300px); position: relative; }
.rsvp-card form, .done {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 10px;
}
.rsvp-card input {
  height: 40px;
  border: 1.5px solid #e4b7af;
  background: rgba(255, 255, 255, 0.94);
  text-align: center;
  color: var(--ink);
  font-size: 14px;
  letter-spacing: 0.12em;
  outline: none;
}
.rsvp-card input::placeholder { color: #c3aaa4; }
.rsvp-card input:focus { border-color: var(--rose); }
.rsvp-card input.bad { border-color: #b4544c; background: #fff6f4; }
.rsvp-card button {
  height: 42px;
  border: 0;
  background: #e7b2aa;
  color: #fff;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  font-size: 16px;
}
.rsvp-card button:hover { background: #dea79e; }
.form-msg { min-height: 1em; margin: 0; font-size: 12px; color: #a15a52; }
.photo-under {
  margin: 14px 0 0;
  height: 196px;
  border: 7px solid #fff;
  overflow: hidden;
  position: relative;
  z-index: 1;
}
.photo-under svg, .photo-under img { width: 100%; height: 100%; display: block; object-fit: cover; }
.done { padding: 18px 8px 8px; }
.done .script-md { margin: 0; }
.done p { margin: 8px 0 0; letter-spacing: 0.12em; }
.rsvp-card .again {
  height: auto;
  border: 0;
  background: transparent;
  color: #a18478;
  letter-spacing: 0.18em;
  text-indent: 0;
  margin-top: 2px;
  font-size: 13px;
}

.bless-lane {
  position: absolute;
  z-index: 5;
  left: 0;
  bottom: 0;
  width: 60%;
  height: 50%;
  overflow: hidden;
  pointer-events: none;
}
.bless-track {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  animation: bless-rise linear infinite;
}
.bless-set {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  font-size: 12px;
  gap: 0.9em;
  padding: 0 0 1.8em 8px;
}
.bless-item {
  position: relative;
  box-sizing: border-box;
  width: max-content;
  max-width: calc(100% - 8px);
  margin: 0;
  padding: 4px 8px;
  border-radius: 12px;
  background: transparent;
  color: #c46d68;
  font-size: 12px;
  line-height: 1.35;
  letter-spacing: 0.04em;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-height: calc(1.35em * 2 + 8px);
  overflow: hidden;
  overflow-wrap: anywhere;
}
.bless-item:nth-child(6n + 2) { color: #8d6a3f; }
.bless-item:nth-child(6n + 3) { color: #9a5b6a; }
.bless-item:nth-child(6n + 4) { color: #6e7a62; }
.bless-item:nth-child(6n + 5) { color: #a15a52; }
.bless-item:nth-child(6n + 6) { color: #6d564c; }
@keyframes bless-rise {
  from { transform: translateY(0); }
  to { transform: translateY(calc(var(--shift, 0px) * -1)); }
}

.music, .next {
  position: absolute;
  z-index: 6;
  border: 0;
  background: rgba(255, 255, 255, 0.72);
  color: var(--ink);
}
.music {
  top: calc(14px + env(safe-area-inset-top));
  right: 14px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  box-shadow: 0 4px 14px rgba(90, 60, 50, 0.08);
}
.music svg { width: 16px; height: 16px; }
.music.on svg { animation: spin 4.8s linear infinite; }
.music.is-muted::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 1.5px;
  background: currentColor;
  transform: rotate(-42deg);
}
.dots {
  position: absolute;
  z-index: 6;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.dots button {
  width: 16px;
  height: 14px;
  border: 0;
  background: transparent;
  padding: 0;
}
.dots button::before {
  content: "";
  display: block;
  width: 4px;
  height: 4px;
  margin: 5px auto;
  border-radius: 4px;
  background: rgba(91, 72, 63, 0.28);
}
.dots button.on::before { height: 14px; margin: 0 auto; background: #c48b84; }
.next {
  left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(247, 243, 238, 0.82);
  border: 1px solid rgba(196, 139, 132, 0.45);
}
.next svg { width: 22px; height: 22px; animation: bob 1.5s ease-in-out infinite; }
.stage.is-end .next { display: none; }

[data-anim] { opacity: 0; }
.slide.seen [data-anim] { opacity: 1; }
.slide.is-active [data-anim] {
  animation-duration: 1.15s;
  animation-fill-mode: both;
  animation-timing-function: var(--ease);
  animation-delay: var(--d, 0s);
}
.slide.is-active [data-anim="zoomIn"] { animation-name: zoomIn; }
.slide.is-active [data-anim="fadeInUp"] { animation-name: fadeInUp; }
.slide.is-active [data-anim="fadeInDown"] { animation-name: fadeInDown; }
.slide.is-active [data-anim="fadeInLeft"] { animation-name: fadeInLeft; }
.slide.is-active [data-anim="fadeInRight"] { animation-name: fadeInRight; }
.slide.is-active [data-anim="rollIn"] { animation-name: rollIn; }
.slide.is-active [data-anim="flipInX"] { animation-name: flipInX; }
.slide.is-active [data-anim="flipInY"] { animation-name: flipInY; }

@keyframes zoomIn {
  from { opacity: 0; transform: scale(0.42); }
  to { opacity: 1; transform: none; }
}
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(78px); }
  to { opacity: 1; transform: none; }
}
@keyframes fadeInDown {
  from { opacity: 0; transform: translateY(-78px); }
  to { opacity: 1; transform: none; }
}
@keyframes fadeInLeft {
  from { opacity: 0; transform: translateX(-88px); }
  to { opacity: 1; transform: none; }
}
@keyframes fadeInRight {
  from { opacity: 0; transform: translateX(88px); }
  to { opacity: 1; transform: none; }
}
@keyframes rollIn {
  from { opacity: 0; transform: translateX(-110px) rotate(-24deg); }
  to { opacity: 1; transform: none; }
}
@keyframes flipInX {
  from { opacity: 0; transform: perspective(800px) translateY(40px) rotateX(110deg); }
  to { opacity: 1; transform: none; }
}
@keyframes flipInY {
  from { opacity: 0; transform: perspective(800px) translateX(56px) rotateY(110deg); }
  to { opacity: 1; transform: none; }
}
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(14px); }
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 480px) {
  body { display: block; background: var(--paper); }
  .stage { width: 100vw; box-shadow: none; }
}
@media (max-height: 700px) {
  .script-xl { font-size: 42px; }
  .frame.portrait { width: min(calc(40% + 50px), 182px); }
  .person-extra,
  .album .banner { width: min(92%, 280px); }
  .album .pair { width: 78%; margin-inline: auto; }
  .person, .album { gap: 6px; padding-top: 11%; }
  .locate { gap: 6px; padding-top: 10%; }
  .locate .banner { width: min(86%, 270px); }
  .map-draw { height: 88px; }
  .photo-under { height: 150px; }
}
@media (prefers-reduced-motion: reduce) {
  .deck, .next svg, .music.on svg { transition: none; animation: none; }
  [data-anim] { opacity: 1; animation: none !important; }
  .bless-track { animation: none; top: auto; bottom: 0; }
  .bless-set[aria-hidden="true"] { display: none; }
  .bless-set { padding-bottom: 12px; }
  .bless-item { animation: none; }
}
