:root {
  --ivory: #fbf8f4;
  --paper: #fffdf9;
  --blush: #f3dde1;
  --blush-deep: #e7c3cb;
  --sage: #a7b08a;
  --sage-deep: #6d7752;
  --plum: #7e2f50;
  --plum-deep: #5e1d39;
  --ink: #3a2f33;
  --muted: #776a6e;
  --line: #eadfe1;
  --error: #a3423a;

  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  /* Script accent: Allura, a calligraphy script with simpler loops than Pinyon Script */
  --script: "Allura", "Snell Roundhand", cursive;
  --sans: "Jost", system-ui, -apple-system, "Segoe UI", sans-serif;
  --radius: 3px;
  --nav-h: 60px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: var(--nav-h); overflow-x: clip; }
body {
  margin: 0;
  background: var(--ivory);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
body.intro-active { overflow: hidden; }
h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.15; margin: 0; }
a { color: var(--plum); }
[hidden] { display: none !important; }
.script { font-family: var(--script); font-weight: 400; font-style: normal; }

.container { max-width: 1080px; margin: 0 auto; padding: 0 20px; }
.narrow { max-width: 680px; }
.center { text-align: center; }
.lede { color: var(--muted); font-size: 1.05rem; margin: 0 0 2rem; }

/* Mixed caps + script headings, e.g. "WHERE TO Stay" */
.title {
  text-align: center; color: var(--plum);
  font-size: clamp(1.4rem, 3.6vw, 2rem); font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase;
  margin-bottom: 0.6rem;
}
.title em {
  display: inline-block; text-transform: none; letter-spacing: 0;
  font-size: 1.9em; line-height: 0.8; margin: 0 0.05em; vertical-align: -0.12em;
}
.title-sm { font-size: clamp(1.15rem, 2.8vw, 1.5rem); margin: 4.5rem 0 2rem; }

.sprig { display: block; width: min(280px, 70vw); height: auto; aspect-ratio: 977 / 217; margin: 0 auto 2.4rem; object-fit: contain; }

/* ---------- Envelope (shared by the intro and the hero) ---------- */
.envelope {
  position: relative; display: block;
  aspect-ratio: 10 / 7;
  padding: 0; border: 0; background: none; font: inherit; color: inherit;
  perspective: 1400px;
  -webkit-tap-highlight-color: transparent;
}
/* Paper and liner textures come from config.js (art.envelopePaper / envelopeLiner),
   set by app.js as --env-paper, --env-paper-inside and --env-liner. Each piece is
   the paper cut to shape with clip-path; the shadows sit on unclipped wrappers. */
.envelope {
  --env-color: #e1c3c6;
  --env-bg: var(--env-paper, none) center / cover, var(--env-color);
  --env-bg-inside: var(--env-paper-inside, var(--env-paper, none)) center / cover, var(--env-color);
}
.env-back {
  position: absolute; inset: 0; border-radius: 3px;
  background: var(--env-bg-inside);
  box-shadow: 0 1px 2px rgba(40, 30, 30, 0.14), 0 6px 12px -4px rgba(40, 30, 30, 0.16), 0 22px 40px -14px rgba(70, 30, 45, 0.38);
}
/* The liner is one sheet of print, as tall as the envelope is wide (times --liner-scale)
   and as wide as the image's shape makes it, shared by the open flap and the inside back
   panel so the print runs on unbroken. Its offset (--liner-x / --liner-y, in % of the
   sheet's width / height) picks which part shows; a wide print can slide left and right.
   The layout editor sets them (config.js → layout.liner). The inside panel sits 42.7% of
   the envelope's width below the flap's top once open (flap = 61% of a 10:7 envelope). */
.envelope {
  --lx: var(--liner-x, 0);
  --ly: var(--liner-y, -22.35);
  --ls: var(--liner-scale, 1);
  --la: var(--liner-aspect, 1); /* the liner image's width ÷ height, set by app.js */
}
.env-back-liner {
  position: absolute; left: 3.8%; right: 3.8%; top: 0; bottom: 4%;
  overflow: hidden; background: #f6f3e8;
}
.liner-img {
  position: absolute; left: 0; top: 0; width: calc(100% * var(--ls) * var(--la)); aspect-ratio: var(--la);
  background: var(--env-liner, none) center / cover no-repeat;
  translate: calc(var(--lx) * 1%) calc(var(--ly) * 1%);
}
/* this panel is 92.4% of the envelope's width and starts 3.8% in, so the print is
   widened and shifted to match the flap's sheet exactly */
.env-back-liner .liner-img {
  left: -4.113%; width: calc(108.23% * var(--ls) * var(--la));
  translate: calc(var(--lx) * 1%) calc((var(--ly) - 42.7 / var(--ls)) * 1%);
}
.env-front { position: absolute; inset: 0; z-index: 3; }
.env-fold { position: absolute; inset: 0; filter: drop-shadow(0 0 1.5px rgba(94, 29, 57, 0.28)); }
.env-fold-bottom { filter: drop-shadow(0 -1px 2.5px rgba(94, 29, 57, 0.22)); }
.env-fold > span { position: absolute; inset: 0; }
.env-side-l {
  clip-path: polygon(0 0, 50% 53.6%, 0 100%);
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.10), rgba(94, 29, 57, 0.05)), var(--env-bg);
}
.env-side-r {
  clip-path: polygon(100% 0, 50% 53.6%, 100% 100%);
  background: linear-gradient(270deg, rgba(255, 255, 255, 0.06), rgba(94, 29, 57, 0.07)), var(--env-bg);
}
.env-bottom {
  clip-path: polygon(0 100%, 50% 47.1%, 100% 100%);
  background: linear-gradient(rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02)), var(--env-bg);
}
.env-flap {
  position: absolute; left: 0; top: 0; width: 100%; height: 61%;
  z-index: 4; transform-origin: 50% 0;
  transform-style: preserve-3d;
  transition: transform 0.8s cubic-bezier(.4, 0, .2, 1) 0.35s, z-index 0s linear 0.75s;
}
.flap-face {
  position: absolute; inset: 0;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.flap-out { filter: drop-shadow(0 2px 2.5px rgba(94, 29, 57, 0.25)); }
.flap-in { filter: drop-shadow(0 0 3px rgba(94, 29, 57, 0.20)); }
.flap-paper, .flap-liner { position: absolute; inset: 0; }
.flap-paper { clip-path: polygon(0 0, 100% 0, 53.5% 95.3%, 50% 100%, 46.5% 95.3%); }
.flap-out .flap-paper { background: linear-gradient(rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0.16)), var(--env-bg); }
/* The inside face is turned over (rotateX 180°) on top of the flap's own turn, so it's
   drawn tip-up here: once the flap opens, its wide edge sits on the envelope's top edge
   and the point faces up, and the liner pattern reads the right way up. */
.flap-in .flap-paper {
  clip-path: polygon(0 100%, 100% 100%, 53.5% 4.7%, 50% 0, 46.5% 4.7%);
  background: var(--env-bg-inside);
}
/* Inset from the flap's slanted edges and tip (≈10 of the flap's 400 units) so a
   band of envelope paper frames the print; it still runs to the fold at the bottom. */
.flap-liner {
  clip-path: polygon(3.8% 100%, 96.2% 100%, 51.85% 9.1%, 50% 6.8%, 48.15% 9.1%);
  overflow: hidden; background: #f6f3e8;
}
.flap-in { transform: rotateX(180deg); }
.is-open .env-flap { transform: rotateX(180deg); z-index: 1; }

/* Putting everything back ("Click to go back to the envelope"): the opening in reverse.
   The card slides in first, then the flap folds down over it, then the seal returns. */
.envelope.closing .env-card { transition: transform 0.9s cubic-bezier(.4, 0, .2, 1) 0s; }
.envelope.closing .env-flap { transition: transform 0.8s cubic-bezier(.4, 0, .2, 1) 0.85s, z-index 0s linear 0.85s; }
.envelope.closing .seal { transition: transform 0.45s ease 1.6s, opacity 0.35s ease 1.6s; }
.envelope.no-anim, .envelope.no-anim * { transition: none !important; }

/* Card inside the opening envelope: slides up out of it once the flap is open */
.env-card {
  position: absolute; left: 7%; right: 7%; top: 9%; bottom: 9%; z-index: 2; /* card-envelope art is 3 : 2 */
  transition: transform 1s cubic-bezier(.3, .7, .2, 1) 1.05s;
}
.is-open .env-card { transform: translateY(-62%); }
.mini-card {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
  padding-top: 15%;
  background: var(--sage); color: var(--paper); border-radius: 2px;
  box-shadow: inset 0 0 0 5px var(--sage), inset 0 0 0 6px rgba(255, 253, 249, 0.6);
  container-type: inline-size;
}
.mini-card > span { position: relative; }
.mini-kicker { font-family: var(--serif); font-weight: 600; text-transform: uppercase; letter-spacing: 0.2em; font-size: 5cqw; }
.mini-names { font-size: 11cqw; line-height: 1.2; margin-top: 2cqw; }
.mini-names .amp { font-size: 0.8em; }
.mini-date { font-family: var(--serif); letter-spacing: 0.14em; font-size: 4.4cqw; margin-top: 1cqw; }

.seal {
  position: absolute; left: 50%; top: 61%; z-index: 5;
  width: 21%; aspect-ratio: 1; transform: translate(-50%, -50%);
  filter: drop-shadow(0 3px 4px rgba(60, 10, 30, 0.35));
  transition: transform 0.45s ease, opacity 0.35s ease;
  display: grid; place-items: center; container-type: inline-size;
}
.seal-art { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
/* Initials pressed into the wax: same color as the wax, shown only by their edges
   (shadow on the upper edge, light catching the lower one). The letters overlap into
   one interlocked mark with a small & tucked between them. The script font leans
   right, so the mark is nudged left to sit in the middle of the inner ring. */
.seal-mono {
  position: relative; color: #592e3f; font-size: 22cqw; line-height: 1; white-space: nowrap;
  letter-spacing: -0.14em;
  transform: translate(-1.5cqw, -0.5cqw);
  text-shadow: 0 -1px 0.5px rgba(25, 5, 15, 0.65), 0 1px 0.5px rgba(255, 215, 230, 0.35);
}
.seal-mono .amp { font-size: 0.42em; vertical-align: 0.35em; letter-spacing: 0; margin: 0 0.02em; }
/* Your own lettering image (config.js → art.waxSealLettering), centred in the inner ring */
.seal-lettering { position: absolute; left: 50%; top: 50%; width: 46%; height: 46%; transform: translate(-50%, -50%); object-fit: contain;
  filter: drop-shadow(0 -1px 0 rgba(255, 240, 246, 0.45)) drop-shadow(0 1.5px 1.5px rgba(30, 5, 15, 0.7)); }
.is-open .seal { transform: translate(-50%, -50%) scale(1.25) rotate(-12deg); opacity: 0; }

.env-bouquet { position: absolute; z-index: 6; pointer-events: none; object-fit: contain; }
.env-bouquet, .card-bouquet, .hero-bouquet, .form-bouquet {
  filter: drop-shadow(0 2px 2px rgba(50, 25, 35, 0.22)) drop-shadow(0 8px 10px rgba(50, 25, 35, 0.16));
}
.env-bouquet-tl { --base: -14deg; width: 44%; height: 47%; left: -13%; top: -20%; transform: rotate(-14deg); transform-origin: 55% 40%; animation: rustle-flowers 4.6s ease-in-out infinite; }
.env-bouquet-br { --base: 5deg; width: 36%; height: auto; aspect-ratio: 1; right: -11%; bottom: -24%; transform: rotate(5deg); transform-origin: 50% 40%; animation: rustle-flowers 5.3s ease-in-out -1.7s infinite; }
.intro.open .env-bouquet { animation: flutter 0.7s ease-out; }

/* ---------- Intro screen ---------- */
.intro {
  cursor: pointer;
  position: fixed; inset: 0; z-index: 100;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px 20px calc(24px + env(safe-area-inset-bottom));
  background: var(--paper);
  transition: opacity 0.9s ease, visibility 0s;
  /* Envelope width. The open flap rises 43% of it above the envelope, so the gap under
     the date is 46% of it; the whole column has to fit the screen (≈1.16 × width + text). */
  --env-w: min(88vw, 620px, calc((100svh - 270px) / 1.16));
}
.intro.done { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.9s ease, visibility 0s linear 0.9s; }
.intro-names { font-size: clamp(3rem, 12vw, 4.8rem); color: var(--ink); margin: 0; line-height: 1.1; }
.intro-names .amp { color: var(--plum); font-size: 0.8em; }
.intro-date { font-family: var(--serif); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); margin: 0.4rem 0 calc(var(--env-w) * 0.46); font-size: clamp(1.05rem, 3.2vw, 1.35rem); }
.intro .envelope { width: var(--env-w); cursor: pointer; animation: floaty 3.2s ease-in-out infinite; }
.intro .envelope:focus-visible { outline: 2px solid var(--plum); outline-offset: 10px; }
.intro.open .envelope { animation: rustle 0.45s ease-out; }
.intro-hint {
  font-family: var(--serif); text-transform: uppercase; letter-spacing: 0.24em;
  color: var(--ink); margin: clamp(44px, 7vh, 70px) 0 0; font-size: 0.95rem;
  animation: pulse 2.4s ease-in-out infinite;
}
.intro.open .intro-hint { opacity: 0; animation: none; transition: opacity 0.3s; }
@keyframes rustle {
  0% { transform: rotate(0); }
  25% { transform: translateY(-2px) rotate(-1.3deg); }
  55% { transform: rotate(0.9deg); }
  80% { transform: rotate(-0.4deg); }
  100% { transform: rotate(0); }
}
@keyframes floaty { 0%, 100% { transform: translateY(0) rotate(-1deg); } 50% { transform: translateY(-8px) rotate(1deg); } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }

/* ---------- Nav ---------- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50; height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between; padding: 0 22px;
  background: rgba(255, 253, 249, 0.94); box-shadow: 0 1px 0 var(--line);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.nav-brand { font-size: 2rem; color: var(--plum); text-decoration: none; line-height: 1; padding-top: 6px; }
.nav-links { display: flex; gap: 26px; align-items: center; }
.nav-links a {
  font-family: var(--serif); font-size: 0.95rem; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink); text-decoration: none;
}
.nav-links a:hover { color: var(--plum); }
.nav-links .nav-cta { background: var(--plum); color: var(--paper); padding: 6px 18px; border-radius: 99px; }
.nav-links .nav-cta:hover { background: var(--plum-deep); color: var(--paper); }
.nav-toggle { display: none; }

@media (max-width: 820px) {
  .nav-toggle {
    display: flex; flex-direction: column; justify-content: center; gap: 7px;
    width: 40px; height: 40px; background: none; border: 0; cursor: pointer; padding: 8px;
  }
  .nav-toggle span { display: block; height: 1.5px; background: var(--ink); transition: transform 0.25s; }
  .nav-toggle[aria-expanded="true"] span:first-child { transform: translateY(4.25px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] span:last-child { transform: translateY(-4.25px) rotate(-45deg); }
  .nav-links {
    position: fixed; top: var(--nav-h); left: 0; right: 0;
    flex-direction: column; gap: 0; background: var(--paper); border-bottom: 1px solid var(--line);
    max-height: 0; overflow: hidden; transition: max-height 0.3s ease;
  }
  .nav-links.open { max-height: 480px; }
  .nav-links a { padding: 15px; width: 100%; text-align: center; }
  .nav-links .nav-cta { background: none; color: var(--plum); border-radius: 0; padding: 15px; }
}

/* ---------- Hero: stationery collage ----------
   Laid out like the reference mockup. Pieces are placed in cqw (1% of the
   collage's width). The envelope, cards, badge and polaroids are containers too, so
   everything inside them is sized in cqw of the piece itself and scales with it. */
.hero {
  padding: calc(var(--nav-h) + 30px) 16px 70px;
  background:
    radial-gradient(ellipse at 20% 10%, rgba(167, 176, 138, 0.16), transparent 55%),
    radial-gradient(ellipse at 85% 80%, rgba(231, 195, 203, 0.35), transparent 55%),
    var(--ivory);
  overflow: hidden;
}
/* Up to 660px wide, but never taller than the window: the collage is 1.6× as tall as
   it is wide (1.88× with photos), plus the nav bar and the hero's padding above/below */
.hero-inner { max-width: min(660px, max(340px, calc((100svh - var(--nav-h) - 100px) / 1.6))); margin: 0 auto; }
.hero-inner:has(.stationery.has-video) { max-width: min(660px, max(340px, calc((100svh - var(--nav-h) - 100px) / 1.68))); }
.hero-inner:has(.stationery.has-photos) { max-width: min(660px, max(340px, calc((100svh - var(--nav-h) - 100px) / 1.88))); }
.stationery {
  position: relative; width: 100%; aspect-ratio: 100 / 160;
  container-type: inline-size;
}
.stationery.has-photos { aspect-ratio: 100 / 188; }
.stationery > * { position: absolute; }
.stationery > *:not(.envelope) { animation: deal 0.9s cubic-bezier(.2, .7, .2, 1) both; }

/* Envelope, open, flap up showing the liner (the flap rises above `top`) */
.envelope-static { left: 14cqw; top: 27cqw; width: 59cqw; container-type: inline-size; }
.envelope-static { cursor: pointer; }
/* Wide polaroid with a video, tucked in the envelope behind the front pocket; it slides
   up and out (with a slight tilt) once the collage has arrived. Its resting place is the
   "out" position, so the layout editor shows and saves where it ends up. */
.video-polaroid {
  position: absolute; z-index: 2; left: 18%; top: -24%; width: 64%;
  padding: 2.4% 2.4% 0; background: #fffefb; cursor: pointer;
  box-shadow: 0 1px 3px rgba(40, 30, 30, 0.2), 0 10px 22px -10px rgba(40, 30, 30, 0.35);
  transform: rotate(-4deg);
  animation: polaroid-out 1.3s cubic-bezier(.2, .7, .2, 1) 1.4s both;
  container-type: inline-size;
}
.video-polaroid-clip { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: #e9e4dc; }
.video-polaroid-caption { display: block; text-align: center; color: var(--ink); font-size: 7.5cqw; line-height: 1.2; padding: 1.5cqw 0 0; }
.video-polaroid::after { content: ""; display: block; height: 9cqw; } /* the thick bottom edge of a polaroid */
.video-polaroid:has(.video-polaroid-caption:not([hidden]))::after { height: 3cqw; }
@keyframes polaroid-out {
  from { translate: 0 62%; transform: rotate(0deg); }
  to { translate: 0 0; transform: rotate(-4deg); }
}
/* Video in a wooden picture frame in the stationery (layout editor: "video"). The frame is
   an image (config.js → art.videoFrame) drawn as a border-image; without one it's a plain
   white frame. The stationery grows a little to fit it (has-video). */
.stationery.has-video { aspect-ratio: 100 / 168; }
.stationery > .video-feature {
  left: 2cqw; top: 121cqw; width: 50cqw; z-index: 4; margin: 0; cursor: pointer; rotate: -4deg;
  container-type: inline-size; animation-delay: 0.6s !important;
  padding: 0; /* the video sits right inside the frame */
  border: 3.6cqw solid transparent;
  border-image: var(--video-frame, none) 64 stretch;
  background:
    linear-gradient(#fffefb, #fffefb) padding-box,
    linear-gradient(135deg, #ffffff 0%, #f1eeea 30%, #ffffff 52%, #e8e4dd 78%, #f7f5f1 100%) border-box;
  box-shadow:
    0 1px 2px rgba(40, 30, 30, 0.2), 0 18px 34px -14px rgba(40, 30, 30, 0.4);
}
.video-feature-clip {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: #e9e4dc;
}
.video-feature-caption { text-align: center; color: var(--ink); font-size: 8cqw; line-height: 1.2; padding: 2cqw 0 1cqw; }
.video-lightbox {
  position: fixed; inset: 0; z-index: 200; display: grid; place-items: center;
  padding: 24px; background: rgba(30, 18, 24, 0.82);
}
.video-lightbox-clip { width: min(960px, 100%); max-height: 86vh; background: #000; border-radius: 4px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); }
.video-lightbox-close {
  position: absolute; top: calc(12px + env(safe-area-inset-top, 0px)); right: 16px;
  width: 44px; height: 44px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 253, 249, 0.92); color: var(--ink); font-size: 1.8rem; line-height: 1;
}
.envelope-static .env-flap { transition: none; }
/* Every 3 seconds the open flap lifts and settles a little, a hint that the envelope
   can be tapped to close it */
.envelope-static.is-open .env-flap { animation: flap-flutter 3s ease-in-out 2.5s infinite; }
@keyframes flap-flutter {
  0%, 60%, 100% { transform: rotateX(180deg); }
  73% { transform: rotateX(155deg); }
  83% { transform: rotateX(185deg); }
  91% { transform: rotateX(177deg); }
}
.envelope-static .seal { width: 17%; top: 57%; transform: translate(-50%, -50%); opacity: 1; transition: none; }
.envelope-static .env-bouquet-tl {
  width: 52%; height: auto; aspect-ratio: 1; left: -20%; top: -36%; transform: rotate(-6deg);
  --base: -6deg; transform-origin: 60% 40%; animation: rustle-flowers 5.5s ease-in-out -0.8s infinite;
}

/* Optional card artwork (config.js → art.cardSage / art.cardIvory); text sits on top */
.card-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.card-sage {
  --w: 42cqw;
  left: 8cqw; top: 74cqw; width: var(--w); aspect-ratio: 1000 / 1491; z-index: 2; /* matches card-sage art */
  container-type: inline-size;
  animation-delay: 0.1s !important;
  background: var(--sage); color: var(--paper);
  box-shadow: 0 1px 2px rgba(40, 30, 30, 0.14), 0 6px 12px -4px rgba(40, 30, 30, 0.16), 0 22px 40px -14px rgba(50, 55, 35, 0.40);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: calc(var(--w) * 0.095) calc(var(--w) * 0.071) calc(var(--w) * 0.143);
}
.card-sage::before {
  content: ""; position: absolute; inset: 5.24cqw;
  border: 1px solid rgba(255, 253, 249, 0.55);
}
.arc { position: relative; width: 84%; overflow: visible; margin-bottom: 2.38cqw; }
.arc text { font-family: var(--serif); font-weight: 600; font-size: 22px; letter-spacing: 0.22em; text-transform: uppercase; fill: var(--paper); }
.names {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  font-size: 22.86cqw; line-height: 1.15; color: var(--paper); text-align: center;
}
.names .amp { font-size: 0.7em; opacity: 0.9; }

.card-ivory {
  --w: 43cqw;
  left: 45cqw; top: 57cqw; width: var(--w); aspect-ratio: 1000 / 1408; z-index: 3; /* matches card-ivory art */
  container-type: inline-size;
  animation-delay: 0.25s !important;
  background: var(--paper); color: var(--plum); text-align: center;
  box-shadow: 0 1px 2px rgba(40, 30, 30, 0.14), 0 6px 12px -4px rgba(40, 30, 30, 0.18), 0 22px 40px -14px rgba(70, 30, 45, 0.38);
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: 0 calc(var(--w) * 0.07) calc(var(--w) * 0.14);
}
.card-ivory::before {
  content: ""; position: absolute; inset: 4.19cqw;
  border: 1px solid rgba(126, 47, 80, 0.35);
}
.card-bouquet {
  position: absolute; z-index: 1; width: 69.77cqw; aspect-ratio: 1; left: 16.28cqw; top: -46.51cqw;
  object-fit: contain; pointer-events: none;
  transform-origin: 50% 40%; animation: rustle-flowers 4.9s ease-in-out -2.6s infinite;
}
.card-ivory p { margin: 0; position: relative; }
.dc-day { font-family: var(--serif); font-size: 14.42cqw; line-height: 1.1; }
.dc-day sup { font-size: 0.55em; }
.dc-month { font-size: 26.74cqw; line-height: 1.05; }
.dc-year { font-family: var(--serif); font-size: 14.42cqw; line-height: 1.1; margin-bottom: 6.98cqw !important; }
.dc-note { font-weight: 600; }
.dc-loc, .dc-note { font-family: var(--serif); text-transform: uppercase; letter-spacing: 0.06em; font-size: 6.05cqw; line-height: 1.35; }
.dc-dots { font-size: 4.19cqw; letter-spacing: 0.1em; margin: 2.79cqw 0 !important; }

/* Second bouquet tucked under the date card's bottom-left corner */
.hero-bouquet { z-index: 4; width: 28cqw; aspect-ratio: 1; left: 41cqw; top: 108cqw; object-fit: contain; pointer-events: none; animation-delay: 0.35s !important; }
.stationery > .hero-bouquet {
  transform-origin: 50% 40%;
  animation: deal 0.9s cubic-bezier(.2, .7, .2, 1) both, rustle-flowers 6.1s ease-in-out 1s infinite;
  animation-delay: 0.35s, 1.2s !important;
}

.badge {
  width: 33cqw; aspect-ratio: 1; border-radius: 50%; z-index: 6;
  left: 55cqw; top: 125cqw;
  background: var(--plum); color: #f6e3ea; border: 0; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center;
  font-family: var(--serif); text-transform: uppercase; letter-spacing: 0.1em; line-height: 1.1;
  container-type: inline-size;
  text-decoration: none; padding: 0;
  /* drop-shadow follows the circle, or the shape of your badge image */
  filter: drop-shadow(0 2px 2px rgba(40, 10, 25, 0.25)) drop-shadow(0 12px 16px rgba(60, 15, 35, 0.35));
  animation-delay: 0.45s !important;
  transition: background 0.2s, scale 0.2s;
}
.badge > span, .badge > em { position: relative; }
.badge > span { font-size: 11.52cqw; }
.badge em { font-size: 26.5cqw; line-height: 0.95; text-transform: none; letter-spacing: 0; }
.badge:hover { background: var(--plum-deep); scale: 1.03; }
/* Cues that the badges are buttons: a small arrow, a press effect, and a gentle nudge
   every 3 seconds (the second badge a moment after the first) once the collage is in */
.badge > .badge-arrow { font-size: 9cqw; line-height: 1; margin-top: 2.5cqw; opacity: 0.85; letter-spacing: 0; }
.badge-hotel > .badge-arrow { font-size: 7cqw; margin-top: 1.5cqw; }
/* The arrow made the words sit high: nudge words and arrow down a little */
.badge:not(.badge-hotel) > :not(.badge-bg) { translate: 0 4cqw; }
.badge-hotel > :not(.badge-bg) { translate: 0 3cqw; }
.badge:active { transform: scale(0.95); }
.stationery > .badge {
  animation: deal 0.9s cubic-bezier(.2, .7, .2, 1) both, badge-nudge 3s ease-in-out infinite;
  animation-delay: 0.45s, 1.8s !important;
}
.stationery > .badge-hotel { animation-delay: 0.5s, 2.6s !important; }
@keyframes badge-nudge {
  0%, 45%, 100% { transform: scale(1); }
  14% { transform: scale(1.12); }
  26% { transform: scale(0.96); }
  36% { transform: scale(1.03); }
}
/* Second badge, "More details": to the hotel section. Sage, a little smaller, on the names card's bottom-left
   corner so it balances the address badge. */
.badge-hotel {
  width: 25cqw; left: 1cqw; top: 121cqw; z-index: 5;
  background: var(--sage-deep); color: var(--paper);
  animation-delay: 0.5s !important;
}
.badge-hotel:hover { background: #59623f; }
/* Optional badge art (config.js → art.badge), with the words on top */
.badge-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.badge:has(> .badge-bg:not([hidden])) { background: none; }
@keyframes deal { from { opacity: 0; translate: 0 30px; } to { opacity: 1; translate: 0 0; } }
/* Bouquets rustle on their own, each at its own pace: small uneven turns around their
   resting angle (--base), like a breeze through the stems. Transform only, so the layout
   editor's rotate/scale still apply. */
@keyframes rustle-flowers {
  0%   { transform: rotate(calc(var(--base, 0deg) - 1.2deg)) translateY(0); }
  18%  { transform: rotate(calc(var(--base, 0deg) + 0.47deg)) translateY(-0.4%); }
  33%  { transform: rotate(calc(var(--base, 0deg) - 0.33deg)) translateY(-0.13%); }
  52%  { transform: rotate(calc(var(--base, 0deg) + 1.33deg)) translateY(-0.73%); }
  70%  { transform: rotate(calc(var(--base, 0deg) - 0.2deg)) translateY(-0.27%); }
  85%  { transform: rotate(calc(var(--base, 0deg) + 0.73deg)) translateY(-0.53%); }
  100% { transform: rotate(calc(var(--base, 0deg) - 1.2deg)) translateY(0); }
}
@keyframes flutter {
  0%   { transform: rotate(var(--base, 0deg)); }
  20%  { transform: rotate(calc(var(--base, 0deg) - 4deg)) translateY(-1%); }
  45%  { transform: rotate(calc(var(--base, 0deg) + 3deg)); }
  70%  { transform: rotate(calc(var(--base, 0deg) - 1.5deg)); }
  100% { transform: rotate(var(--base, 0deg)); }
}

@media (max-width: 640px) {
  .hero { padding-top: calc(var(--nav-h) + 10px); padding-bottom: 36px; }
}
}

/* Polaroid photos */
.photos { display: flex; justify-content: center; flex-wrap: wrap; gap: 22px; margin-top: 30px; }
.polaroid {
  margin: 0; background: #fff; padding: 10px 10px 34px; width: min(42vw, 210px);
  box-shadow: 0 14px 26px -14px rgba(0, 0, 0, 0.35);
}
.polaroid:nth-child(odd) { transform: rotate(-4deg); }
.polaroid:nth-child(even) { transform: rotate(3deg); }
.polaroid img { display: block; width: 100%; aspect-ratio: 1 / 1.1; object-fit: cover; }
.polaroid figcaption { font-family: var(--script); text-align: center; color: var(--ink); font-size: 1.3rem; margin-top: 6px; }
/* The first two photos join the collage, under the sage card */
.stationery .polaroid {
  --w: 32cqw; width: var(--w); padding: calc(var(--w) * 0.044) calc(var(--w) * 0.044) calc(var(--w) * 0.156);
  z-index: 3; transform: none; animation-delay: 0.55s !important; container-type: inline-size;
}
.stationery .polaroid figcaption { font-size: 12.5cqw; margin-top: 1.9cqw; }
.stationery .polaroid:nth-of-type(1) { left: 13cqw; top: 137.5cqw; rotate: -4deg; }
.stationery .polaroid:nth-of-type(2) { --w: 29cqw; left: 41cqw; top: 146.5cqw; rotate: 4deg; z-index: 4; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-block; cursor: pointer;
  font-family: var(--serif); font-size: 1rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; text-decoration: none;
  padding: 13px 34px; border-radius: 99px;
  border: 1px solid var(--plum);
  transition: background 0.2s, color 0.2s, opacity 0.2s;
}
.btn-primary { background: var(--plum); color: var(--paper); }
.btn-primary:hover { background: var(--plum-deep); border-color: var(--plum-deep); }
.btn-ghost { background: transparent; color: var(--plum); }
.btn-ghost:hover { background: var(--plum); color: var(--paper); }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.6; cursor: wait; }

/* ---------- Sections ---------- */
.section { padding: 100px 0; }
.section-alt { background: #f8eef0; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 440px)); justify-content: center; gap: 26px; }
.card {
  position: relative; background: var(--paper); border-radius: 2px;
  padding: 40px 32px 34px; display: flex; flex-direction: column;
  box-shadow: 0 14px 30px -20px rgba(94, 29, 57, 0.35);
}
.card::before {
  content: ""; position: absolute; inset: 9px; pointer-events: none;
  border: 1px solid rgba(126, 47, 80, 0.22);
}
.card > * { position: relative; }
.card h3 { font-size: 1.35rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--plum); margin-bottom: 0.2rem; }
.card-when { font-family: var(--script); font-size: 1.9rem; color: var(--sage-deep); margin: 0 0 0.9rem; line-height: 1.2; }
.card p { margin: 0 0 1rem; }
.card .meta { list-style: none; padding: 0; margin: 0 0 1.2rem; font-size: 0.95rem; }
.card .meta:last-child { margin-bottom: 0; }
.card .meta li { padding: 8px 0; border-top: 1px solid var(--line); display: flex; gap: 10px; }
.card .meta li:last-child { border-bottom: 1px solid var(--line); }
.card .meta strong {
  font-family: var(--serif); font-weight: 600; min-width: 82px; color: var(--muted);
  font-size: 0.85rem; letter-spacing: 0.14em; text-transform: uppercase; padding-top: 2px;
}
.card .actions { margin-top: auto; display: flex; gap: 18px; flex-wrap: wrap; }
.card .link {
  font-family: var(--serif); font-size: 0.95rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--plum); text-decoration: none; border-bottom: 1px solid var(--blush-deep); padding-bottom: 1px;
}
.card .link:hover { color: var(--plum-deep); border-color: var(--plum); }
.code-pill {
  display: inline-block; font-family: ui-monospace, Menlo, monospace; font-size: 0.85rem;
  background: var(--blush); padding: 2px 8px; border-radius: 3px; letter-spacing: 0.05em;
}

.hotels-note { max-width: 560px; margin-inline: auto; text-align: center; text-wrap: balance; }
.info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 34px 40px; }
.info-grid h4 { font-family: var(--serif); font-size: 1.15rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--plum); margin: 0 0 0.4rem; }
.info-grid p { margin: 0; color: var(--muted); }
.info-grid > div { border-top: 1px solid var(--blush-deep); padding-top: 18px; }

.registry-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; }

.faq details { border-bottom: 1px solid var(--line); }
.faq details:first-child { border-top: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; padding: 20px 36px 20px 0; position: relative;
  font-family: var(--serif); font-size: 1.3rem; font-weight: 500;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  font-family: var(--sans); font-weight: 300; font-size: 1.5rem; color: var(--plum); transition: transform 0.2s;
}
.faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq details p { margin: 0 0 22px; color: var(--muted); }

/* ---------- Address form ---------- */
.section-form { background: var(--blush); overflow: hidden; }
.form-card { position: relative; margin-top: 30px; }
.form-bouquet { position: absolute; z-index: 1; width: 170px; height: 180px; right: -40px; top: -70px; object-fit: contain; pointer-events: none; }
.address-form, .form-thanks {
  position: relative; background: var(--paper); color: var(--ink);
  padding: clamp(28px, 5vw, 48px); border-radius: 2px;
  box-shadow: 0 14px 30px -20px rgba(94, 29, 57, 0.35);
}
.preview-banner {
  background: #fff6e0; color: #6b5420; border: 1px solid #e8d49c;
  padding: 12px 16px; border-radius: var(--radius); margin-bottom: 18px; font-size: 0.92rem;
}
.field { margin: 0 0 22px; border: 0; padding: 0; }
.field label, .field legend {
  display: block; font-family: var(--serif); font-size: 1.05rem; font-weight: 500;
  color: var(--ink); margin-bottom: 6px; padding: 0;
}
.optional { color: var(--muted); font-size: 0.9em; }
.field input[type="text"], .field input[type="email"], .field select, .field textarea {
  width: 100%; font: inherit; font-weight: 400; color: var(--ink);
  background: #fff; border: 1px solid #e3d7d9; border-radius: var(--radius);
  padding: 12px 14px; transition: border-color 0.2s, box-shadow 0.2s;
}
.field textarea { resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--plum); box-shadow: 0 0 0 3px rgba(126, 47, 80, 0.15);
}
.field .invalid { border-color: var(--error) !important; }
.choice-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 480px) { .choice-row { grid-template-columns: 1fr; } }
.choice { position: relative; cursor: pointer; display: block; margin: 0 !important; }
.choice input { position: absolute; opacity: 0; pointer-events: none; }
.choice span {
  display: block; text-align: center; padding: 12px 10px;
  border: 1px solid #e3d7d9; border-radius: var(--radius); background: #fff;
  font-family: var(--serif); font-size: 1.15rem; color: var(--ink); transition: all 0.2s;
}
.choice input:checked + span { border-color: var(--plum); background: var(--plum); color: var(--paper); }
.choice input:focus-visible + span { box-shadow: 0 0 0 3px rgba(126, 47, 80, 0.25); }
.address-grid { display: grid; grid-template-columns: 2fr 1.3fr 1.2fr; gap: 10px; }
.address-grid .span-all { grid-column: 1 / -1; }
@media (max-width: 520px) { .address-grid { grid-template-columns: 1fr 1fr; } .address-grid #city { grid-column: 1 / -1; } }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.form-error { color: var(--error); margin: 0 0 16px; font-size: 0.95rem; }
.form-thanks { text-align: center; }
.form-thanks h3 { font-family: var(--script); font-weight: 400; font-size: 2.8rem; color: var(--plum); margin-bottom: 0.4rem; }
.form-thanks p { color: var(--muted); margin: 0 0 1.6rem; }

/* Note shown only in a browser that has an unsaved layout from the editor */
.draft-note {
  position: fixed; left: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); z-index: 90;
  max-width: min(360px, calc(100vw - 32px)); padding: 10px 14px; border-radius: 6px;
  background: #fff6e0; color: #6b5420; border: 1px solid #e8d49c; font-size: 0.85rem; line-height: 1.4;
  box-shadow: 0 8px 20px -10px rgba(60, 40, 10, 0.35);
}
.draft-note a { color: inherit; font-weight: 500; }

/* ---------- Footer ---------- */
.footer { background: #d6dcc4; text-align: center; padding: 64px 20px calc(54px + env(safe-area-inset-bottom)); color: var(--plum); }
/* A pale tint of the names card's sage, with the plum text */
.footer a { color: var(--plum); }
.footer p { margin: 0.15rem 0; }
.see-you { font-size: clamp(3.2rem, 12vw, 5rem); color: var(--plum); line-height: 1.1; }

/* Footer touches: bells that swing every few seconds, "See you soon…" writing itself
   in when the footer comes into view, and petals drifting down behind it all */
.footer { position: relative; overflow: hidden; }
.footer > :not(.petal) { position: relative; z-index: 1; }
.bells { display: block; width: clamp(78px, 16vw, 112px); margin: 0 auto 2px; overflow: visible; }
.bell { transform-box: fill-box; transform-origin: 50% 0; animation: bell-ring 4s ease-in-out 1s infinite; }
.bell-r { animation-name: bell-ring-r; animation-delay: 1.08s; }
@keyframes bell-ring {
  0%, 62%, 100% { transform: rotate(0); }
  68% { transform: rotate(14deg); }
  76% { transform: rotate(-11deg); }
  84% { transform: rotate(7deg); }
  92% { transform: rotate(-3deg); }
}
@keyframes bell-ring-r {
  0%, 62%, 100% { transform: rotate(0); }
  68% { transform: rotate(-14deg); }
  76% { transform: rotate(11deg); }
  84% { transform: rotate(-7deg); }
  92% { transform: rotate(3deg); }
}
/* "See you soon…" is drawn in like ink: each letter's outline is traced by a pen stroke,
   one after another, and the ink then fills in (timing set by app.js) */
.ink-text { display: block; height: 1.15em; width: auto; max-width: 100%; margin: 0 auto; overflow: visible; }
.ink { fill: currentColor; stroke: currentColor; stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.will-ink .ink { fill-opacity: 0; }
.will-ink.inked .ink {
  stroke-dashoffset: 0 !important; fill-opacity: 1;
  transition: stroke-dashoffset var(--dur) cubic-bezier(.45, 0, .3, 1) var(--delay),
              fill-opacity 0.5s ease calc(var(--delay) + var(--dur) * 0.75);
}
.see-you .ink-text { transition: opacity 0.6s ease; }
.see-you.ink-fade .ink-text { opacity: 0; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.petal {
  position: absolute; top: -5%; z-index: 0; pointer-events: none;
  border-radius: 150% 0 150% 0; opacity: 0.85;
  box-shadow: 0 1px 2px rgba(120, 60, 80, 0.15);
  animation-name: petal-fall, petal-sway;
  animation-timing-function: linear, ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: normal, alternate;
}
@keyframes petal-fall { from { top: -5%; } to { top: 105%; } }
@keyframes petal-sway { from { translate: -14px 0; rotate: -25deg; } to { translate: 14px 0; rotate: 35deg; } }
.countdown { display: flex; justify-content: center; align-items: flex-start; gap: clamp(6px, 2.4vw, 16px); margin: 0.6rem 0 2rem; }
.countdown b { font-family: var(--serif); font-weight: 400; font-size: clamp(2.4rem, 8.5vw, 3.8rem); line-height: 1; opacity: 0.6; }
.cd { display: flex; flex-direction: column; align-items: center; min-width: clamp(52px, 15vw, 76px); }
.cd span { font-family: var(--serif); font-size: clamp(2.6rem, 9.5vw, 4.2rem); line-height: 1; font-weight: 500; }
.cd small { font-family: var(--serif); font-size: clamp(0.75rem, 2.4vw, 0.95rem); letter-spacing: 0.2em; text-transform: uppercase; margin-top: 8px; opacity: 0.8; }
.countdown .today { font-family: var(--script); font-size: 2.4rem; }
.footer-names { font-family: var(--serif); font-size: 1.15rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.footer-date { font-family: var(--serif); letter-spacing: 0.3em; }
.hashtag { letter-spacing: 0.08em; margin-top: 0.8rem !important; color: var(--plum); opacity: 0.85; }
.footer-contact { margin-top: 1rem !important; color: var(--plum); opacity: 0.85; }
.replay {
  margin-top: 1.4rem; background: none; border: 0; cursor: pointer; padding: 6px;
  font-family: var(--serif); font-size: 0.9rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--plum); text-decoration: underline; text-underline-offset: 4px;
}

@media (max-width: 600px) {
  body { font-size: 16px; }
  .section { padding: 76px 0; }
  .card { padding: 34px 24px 28px; }
  .form-bouquet { width: 120px; height: 130px; right: -26px; top: -54px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition-duration: 0.01s !important; transition-delay: 0s !important; }
  .petal { display: none; }
}
