/* ===== Tokens ===== */
:root {
  --pink-bg: #FAEAE7; /* matches the hero video's own backdrop exactly */
  --pink-deep: #F6E0DB;
  --pink-envelope: #F2DAD6;
  --rose-gold: #B76E62;
  --rose-soft: #D9A398;

  --fade: .8s;
  --rise: .9s;
  --ease-soft: cubic-bezier(.22, .61, .36, 1);
}

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

html, body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--pink-bg);
  font-family: 'Cormorant Garamond', Georgia, serif;
  color: var(--rose-gold);
  -webkit-font-smoothing: antialiased;
}

/* both, so the page can't scroll behind the cover while it's up */
body.locked { overflow: hidden; }
html:has(body.locked) { overflow: hidden; }

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

/* ===== Cover ===== */
#cover {
  position: fixed;
  inset: 0;
  z-index: 10;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(.15rem, .8vh, .6rem);

  min-height: 100vh;
  min-height: 100dvh;
  padding: clamp(.6rem, 1.8vh, 1.1rem) clamp(.5rem, 2vw, 1.5rem);
  overflow: hidden;

  /* soft glow behind the envelope */
  background:
    radial-gradient(ellipse 70% 60% at 50% 48%, #FFF7F5 0%, var(--pink-bg) 55%, var(--pink-deep) 100%);

  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;

  opacity: 1;
  transition: opacity var(--fade) ease;
}

#cover:focus-visible {
  outline: 2px solid var(--rose-gold);
  outline-offset: -6px;
}

#cover.is-hidden {
  opacity: 0;
  pointer-events: none;
}

/* ===== Drifting petals ===== */
.petals {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  overflow: hidden;
}

.petal {
  position: absolute;
  top: -8vh;
  width: 17px;
  height: 12px;
  background: linear-gradient(135deg, #DCA096, #F2C6BD);
  border-radius: 100% 0 100% 100%;
  opacity: 0;
  animation: fall linear infinite;
  will-change: transform, opacity;
}

@keyframes fall {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg);          opacity: 0; }
  10%  {                                                        opacity: .8; }
  90%  {                                                        opacity: .55; }
  100% { transform: translate3d(40px, 118vh, 0) rotate(420deg); opacity: 0; }
}

/* the page layer drifts over content, so it carries a touch more presence */
@keyframes fallPage {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg);          opacity: 0; }
  8%   {                                                        opacity: .9; }
  92%  {                                                        opacity: .65; }
  100% { transform: translate3d(64px, 118vh, 0) rotate(400deg); opacity: 0; }
}

.petal:nth-child(1) { left:  6%; animation-duration: 14s; animation-delay:  0s;   transform: scale(.9); }
.petal:nth-child(2) { left: 17%; animation-duration: 19s; animation-delay: -6s;  }
.petal:nth-child(3) { left: 29%; animation-duration: 16s; animation-delay: -11s; }
.petal:nth-child(4) { left: 41%; animation-duration: 21s; animation-delay: -3s;  }
.petal:nth-child(5) { left: 54%; animation-duration: 15s; animation-delay: -14s; }
.petal:nth-child(6) { left: 66%; animation-duration: 18s; animation-delay: -8s;  }
.petal:nth-child(7) { left: 77%; animation-duration: 23s; animation-delay: -17s; }
.petal:nth-child(8) { left: 87%; animation-duration: 17s; animation-delay: -2s;  }
.petal:nth-child(9)  { left: 95%; animation-duration: 20s; animation-delay: -12s; }
.petal:nth-child(10) { left: 35%; animation-duration: 22s; animation-delay: -19s; }

/* ===== Top block ===== */
.cover-top {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  margin-top: clamp(1.6rem, 6.5vh, 4.25rem); /* breathing room from the top edge */
  text-align: center;
  animation: rise var(--rise) var(--ease-soft) both;
  animation-delay: .15s;
}

.eyebrow {
  margin: 0 0 .15em;
  font-size: clamp(.62rem, 1.6vw, .78rem);
  font-weight: 500;
  letter-spacing: .42em;
  text-indent: .42em;
  text-transform: uppercase;
  color: var(--rose-soft);
}

.cover-names {
  margin: 0;
  font-family: 'Great Vibes', cursive;
  font-weight: 400;
  font-size: clamp(1.9rem, 5.5vw, 3.1rem);
  line-height: 1.15;
  color: var(--rose-gold);
}

.cover-names .amp {
  padding: 0 .12em;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: .62em;
  color: var(--rose-soft);
  vertical-align: .08em;
}

/* ===== Envelope ===== */
/* the wrapper takes the leftover column space; the scale pushes the artwork
   past that box, using the PNG's own transparent margin as breathing room */
.envelope-wrap {
  position: relative;
  z-index: 2;

  flex: 1 1 auto;
  min-height: 0;
  width: 100%;

  display: flex;
  align-items: center;
  justify-content: center;

  transform: scale(1.22);
}

#envelope {
  width: 100%;
  height: 100%;
  object-fit: contain;

  filter: drop-shadow(0 18px 34px rgba(140, 90, 80, .22));
  animation:
    rise var(--rise) var(--ease-soft) both,
    float 6.5s ease-in-out 1.1s infinite;
}

/* ===== Bottom block ===== */
.cover-bottom {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  animation: rise var(--rise) var(--ease-soft) both;
  animation-delay: .45s;
}

.ornament {
  width: clamp(110px, 22vw, 150px);
  height: auto;
  aspect-ratio: 140 / 16;
  color: var(--rose-soft);
  opacity: .85;
}

#hint {
  margin: 0;
  font-family: 'Great Vibes', cursive;
  font-size: clamp(1.15rem, 4.5vw, 1.5rem);
  letter-spacing: .06em;
  color: var(--rose-gold);
  animation: pulse 2.4s ease-in-out infinite;
}

/* ===== Keyframes ===== */
@keyframes pulse {
  0%, 100% { opacity: .5; }
  50%      { opacity: 1; }
}

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-9px); }
}

/* ===== Invitation ===== */
#invitation {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--pink-bg);
  overflow-x: hidden; /* nothing may ever push the page sideways */

  opacity: 0;
  transition: opacity var(--fade) ease;
}

#invitation.is-visible { opacity: 1; }

/* ===== Hero video ===== */
/* pinned for the first screen of scroll, so it can fade out in place while the
   next section rises over it */
.hero {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;

  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  will-change: opacity;
}

.hero-stage {
  position: relative;

  /* must match the video's contain-fitted artwork EXACTLY — the overlays below
     are positioned as plain percentages of this box. The height can't be pinned
     to 100%: on a viewport narrower than 2048/1732 the width clamps but a
     definite height doesn't shrink with it, so the box outgrows the artwork and
     the overlays drift off it. Width = the smaller of the room available and
     the width the artwork gets at full hero height; aspect-ratio does the rest. */
  width: min(100%, calc(100vh * 2048 / 1732));
  width: min(100%, calc(100dvh * 2048 / 1732));
  aspect-ratio: 2048 / 1732;

  /* lets the overlay text scale off the artwork's width (cqw), not the viewport */
  container-type: inline-size;

  /* the envelope isn't centred inside its own video frame — it sits 2.3% left.
     Nudging the whole stage lines it up with the centred text below. The
     overlays ride along, so their alignment to the artwork is unaffected. */
  transform: translateX(2.3%);
}

.hero-video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  /* contain never crops — and since the clip's backdrop is #FAEAE7, the same as
     --pink-bg, the letterboxing is invisible. Keep those two in sync if the
     video is ever re-exported. */
  object-fit: contain;
}

/* ===== Text laid over the final frame ===== */
.hero-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;

  opacity: 0;
  transition: opacity .4s var(--ease-soft);
}

.hero-overlay.is-in { opacity: 1; }

/* date, sitting on the deep red shape */
.ov-date {
  position: absolute;
  left: 48%;   /* centred on the deep red shape, clear of the bow above it */
  top: 56%;
  transform: translate(-50%, -50%);
  margin: 0;
  white-space: nowrap;

  font-size: clamp(.7rem, 2.4cqw, 1.5rem);
  font-weight: 500;
  letter-spacing: .18em;
  text-indent: .18em;
  color: #FBE7E2;
}

.ov-date span { opacity: .6; }

/* printed on the envelope's front flap, matching the closed cover */
.ov-flap {
  position: absolute;
  left: 49%;
  top: 79%;
  transform: translate(-50%, -50%);
  margin: 0;
  white-space: nowrap;

  font-family: 'Great Vibes', cursive;
  font-size: clamp(1.1rem, 4.6cqw, 3.1rem);
  letter-spacing: .02em;
  color: #9E5563;
  opacity: .92;
}

/* names, sitting on the pale card */
.ov-card {
  position: absolute;
  left: 65%;   /* centred on the card (it spans 51.7%–78.7% of the frame) */
  top: 27%;    /* sits a little below centre, clear of the card's floral corner */
  transform: translate(-50%, -50%);
  width: 26%;
  text-align: center;
  color: var(--rose-gold);
}

.ov-eyebrow {
  margin: 0 0 .55em;
  font-size: clamp(.45rem, 1.3cqw, .82rem);
  font-weight: 500;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  color: var(--rose-soft);
}

.ov-name {
  margin: 0;
  font-family: 'Great Vibes', cursive;
  font-size: clamp(1.15rem, 4.5cqw, 3.1rem);
  line-height: 1.1;
}

.ov-amp {
  margin: 0;
  font-style: italic;
  font-size: clamp(.55rem, 1.9cqw, 1.25rem);
  color: var(--rose-soft);
}

/* ===== Page decoration ===== */
/* petals keep drifting behind the content as you scroll */
/* z-index 5 puts them in FRONT of the opaque section backgrounds (z-index 1) —
   at 0 they were painted over the moment you scrolled into any section.
   Still below the cover at z-index 10, and pointer-events:none from .petals. */
.petals--page {
  position: fixed;
  z-index: 5;
}

.petals--page .petal {
  width: 18px;
  height: 13px;
  background: linear-gradient(135deg, #E3948A, #F4C6BD);
  animation-name: fallPage;
}

/* corner sprays that fill the wide empty margins of each section */
/* blossom branches — drawn as SVG, so they stay crisp at any size and cost
   nothing to download. Anchored flush to the page edge so each one reads as a
   real branch growing in from off-screen rather than a sticker in a corner. */
.branch {
  position: absolute;
  z-index: 0;
  /* mid-width fallback; the two media queries below take over at the ends —
     a margin-derived width once there is room beside the content, and a bolder
     corner vine on phones, where there is no margin at all */
  width: clamp(150px, 32vw, 400px);
  aspect-ratio: 760 / 240;
  opacity: .55;
  pointer-events: none;

  /* must stay centred: scaleX(-1) about any other origin would shift the
     mirrored copies out of their anchored corner */
  transform-origin: 50% 50%;
  animation: sway var(--sway, 12s) ease-in-out infinite;
  will-change: transform;
}

/* offset the right-hand vine of each pair so the pair breathes out of step */
.branch--tr,
.branch--br { animation-delay: calc(var(--sway, 12s) / -3); }

/* the mirror lives in custom properties so the sway keyframes can carry it
   through — otherwise the animation's transform would wipe out the flip */
.branch--tl { top: -3%;    left: 0;  --flip-x:  1; --flip-y:  1; }
.branch--bl { bottom: -3%; left: 0;  --flip-x:  1; --flip-y: -1; }
.branch--tr { top: -3%;    right: 0; --flip-x: -1; --flip-y:  1; }
.branch--br { bottom: -3%; right: 0; --flip-x: -1; --flip-y: -1; }

/* ---- one flower per section, each with its own weight and rhythm ---- */
.branch--rose  { --sway: 13s; --tilt: 1.3deg; opacity: .6;  }
.branch--hyd   { --sway:  8s; --tilt: 1.1deg; opacity: .58; }
.branch--euca  { --sway: 16s; --tilt: 1.6deg; opacity: .62; }
.branch--tulip { --sway:  7s; --tilt: 2deg;   opacity: .55; }
.branch--peony { --sway: 15s; --tilt: 1.2deg; opacity: .55; }
.branch--hero  { --sway: 12s; --tilt: 1.2deg; opacity: .58; }
.branch--lg    { --sway: 11s; --tilt: 1deg;   opacity: .62; }

/* tulips grow upward, so they must never take the vertical flip their
   bottom-corner anchors would otherwise apply */
.branch--tulip.branch--bl,
.branch--tulip.branch--br { --flip-y: 1; }

/* ---- keeping flowers off the wedding artwork ----
   Each vine is capped at the free margin beside whatever that section centres,
   so it can never reach the envelope, the video, the portraits or the text.
   Below 900px the content is full-width and there is no margin to sit in, so
   the vines run behind the content instead — see the phone block below. */
@media (min-width: 900px) {
  .couple .branch    { width: min(30vw, calc((100vw - 52rem) / 2 - 1.5rem)); }

  .details .branch,
  .venue .branch,
  .dresscode .branch,
  .closing .branch   { width: min(34vw, calc((100vw - 34rem) / 2 - 1.5rem)); }

  /* the hero video's artwork is roughly 0.87 x the viewport height wide */
  .hero .branch      { width: min(26vw, calc((100vw - 87dvh) / 2 - 1.5rem)); }

  /* measured: the envelope artwork is 59.3% of its PNG, which works out to
     roughly (viewport height - 160px) wide once contain + the 1.22 scale apply */
  #cover .branch     { width: min(28vw, calc((100vw - 100dvh + 160px) / 2 - 1.5rem)); }
}

/* On a phone the vines sit behind the content rather than beside it. At 32vw
   and the desktop opacity they shrank to a smudge that read as a stain, not a
   flower — so here they run properly across the corner, and lift enough to be
   seen against the pale background. The cap keeps them off the centred text.
   Must come after the per-flower rules above: same specificity, so source order
   is what decides the opacity. */
@media (max-width: 640px) {
  .branch {
    width: clamp(190px, 62vw, 250px);
    opacity: .78;
  }

  /* the cover is the one screen with centred text pinned to BOTH edges — the
     names at the top, the ornament and "Tap to open" at the bottom — so the
     vines get bands of their own instead of a smaller size: the footer lifts
     clear of the bottom edge, and the top vine tucks further into its corner,
     above the names. The envelope simply takes a little less of the middle. */
  .cover-bottom { margin-bottom: clamp(2.75rem, 9vh, 5rem); }

  #cover .branch--tl { top: -7%; }
}

/* a slow breeze — the second vine of each pair runs on a negative delay so the
   two never move in lockstep */
@keyframes sway {
  0%, 100% { transform: scale(var(--flip-x, 1), var(--flip-y, 1)) rotate(calc(var(--tilt, 1deg) * -1)); }
  50%      { transform: scale(var(--flip-x, 1), var(--flip-y, 1)) rotate(var(--tilt, 1deg)); }
}

/* branch between sections */
.section-divider {
  position: relative;
  z-index: 1;
  background: var(--pink-bg);
  padding: clamp(1rem, 4vh, 2.5rem) 1rem;
  text-align: center;
}

.divider-art {
  width: clamp(180px, 42vw, 330px);
  height: auto;
  aspect-ratio: 360 / 48;
  color: var(--rose-gold);
  opacity: .5;
}

/* ===== The couple ===== */
.couple {
  position: relative;
  z-index: 1;
  overflow: hidden;
  /* opaque, so it covers the sticky hero as it rises */
  background:
    radial-gradient(ellipse 62% 52% at 50% 46%, #FFF6F3 0%, var(--pink-bg) 62%, var(--pink-deep) 100%);
  padding: clamp(3rem, 10vh, 5.5rem) clamp(1.25rem, 6vw, 2rem) clamp(3.5rem, 11vh, 5.5rem);
  text-align: center;
  color: var(--rose-gold);
}

.couple-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 52rem;
  margin: 0 auto;
}

.couple-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: start;
  gap: clamp(.75rem, 3vw, 2.5rem);
  margin-top: clamp(1.5rem, 5vh, 2.75rem);
}

.couple-amp {
  align-self: center;
  font-family: 'Great Vibes', cursive;
  font-size: clamp(1.8rem, 6vw, 3rem);
  color: var(--rose-soft);
}

.person-photo {
  position: relative;
  width: min(78%, 210px);
  aspect-ratio: 3 / 4;
  margin: 0 auto clamp(.9rem, 3vh, 1.4rem);

  border-radius: 50%;
  overflow: hidden;
  background-color: var(--pink-deep);
  border: 1px solid rgba(183, 110, 98, .35);
  box-shadow: 0 14px 28px rgba(140, 90, 80, .18);
}

/* the photo paints over the watermark; with no file set it stays transparent
   and the rose shows through instead of a broken image */
.person-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--photo, none);
  background-size: cover;
  background-position: center;
}

.photo-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 62%;
  aspect-ratio: 220 / 380;
  color: var(--rose-gold);
  opacity: .22;
}

.person-name {
  margin: 0 0 .35em;
  font-weight: 400;
  font-size: clamp(1.1rem, 3.4vw, 1.5rem);
  line-height: 1.25;
}

.person-role {
  margin: 0 0 .3em;
  font-size: clamp(.6rem, 1.9vw, .7rem);
  font-weight: 500;
  letter-spacing: .26em;
  text-indent: .26em;
  text-transform: uppercase;
  color: var(--rose-soft);
}

.person-parents {
  margin: 0;
  font-size: clamp(.9rem, 2.8vw, 1.02rem);
  line-height: 1.6;
  color: var(--rose-soft);
}

/* the pair stays side by side all the way down — stacked, they read as two
   separate people rather than a couple. Only the spacing and the type tighten
   to fit the narrower columns. */
@media (max-width: 640px) {
  .couple { padding-left: 1rem; padding-right: 1rem; }

  .couple-grid { gap: .5rem; }

  .couple-amp { font-size: clamp(1.4rem, 5vw, 2rem); }

  /* wider share of a narrower column, so the portraits don't shrink twice over */
  .person-photo { width: min(92%, 150px); }

  .person-name { font-size: clamp(.95rem, 4vw, 1.2rem); }

  .person-role {
    font-size: clamp(.52rem, 2.1vw, .62rem);
    letter-spacing: .18em;
    text-indent: .18em;
  }

  .person-parents {
    font-size: clamp(.78rem, 3.2vw, .92rem);
    line-height: 1.5;
  }
}

/* ===== Dress code ===== */
.dresscode {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background:
    radial-gradient(ellipse 60% 52% at 50% 46%, #FFF6F3 0%, var(--pink-bg) 62%, var(--pink-deep) 100%);
  padding: clamp(3rem, 10vh, 5.5rem) clamp(1.25rem, 6vw, 2rem);
  text-align: center;
  color: var(--rose-gold);
}

.dresscode-inner {
  position: relative;
  z-index: 1;
  max-width: 34rem;
  margin: 0 auto;
}

.dresscode-title {
  margin: 0 0 .5em;
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.65rem, 6vw, 2.4rem);
  line-height: 1.2;
}

.dresscode-note {
  margin: 0 0 clamp(1.75rem, 5vh, 2.5rem);
  font-size: clamp(.98rem, 3vw, 1.1rem);
  line-height: 1.7;
  color: var(--rose-soft);
}

.swatches {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1rem, 4vw, 2rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.swatch-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5em;
}

.swatch {
  width: clamp(38px, 11vw, 54px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--c);
  border: 1px solid rgba(183, 110, 98, .28);
  box-shadow: 0 8px 16px rgba(140, 90, 80, .16);
}

/* names and hex codes, so the palette reads without relying on colour alone */
.swatch-name {
  font-size: clamp(.62rem, 2vw, .72rem);
  font-weight: 500;
  letter-spacing: .16em;
  text-indent: .16em;
  text-transform: uppercase;
}

.swatch-hex {
  font-size: clamp(.58rem, 1.8vw, .66rem);
  letter-spacing: .08em;
  color: var(--rose-soft);
}

/* ===== Details + countdown ===== */
.details {
  position: relative;
  z-index: 1;
  overflow: hidden;
  /* opaque, so it covers the hero as it rises — with a soft glow behind the text */
  background:
    radial-gradient(ellipse 60% 46% at 50% 50%, #FFF6F3 0%, var(--pink-bg) 62%, var(--pink-deep) 100%);

  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;

  padding: clamp(2.5rem, 8vh, 4.5rem) clamp(1.25rem, 6vw, 2rem);
  text-align: center;
  color: var(--rose-gold);
}

.details-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 34rem;
  margin: 0 auto;
}

.details-eyebrow {
  margin: 0 0 .5em;
  font-size: clamp(.68rem, 2vw, .8rem);
  font-weight: 500;
  letter-spacing: .34em;
  text-indent: .34em;
  text-transform: uppercase;
  color: var(--rose-soft);
}

.details-place {
  margin: 0 0 .7em;
  font-weight: 400;
  font-style: italic;
  font-size: clamp(2rem, 8vw, 3.1rem);
  line-height: 1.2;
  letter-spacing: .01em;
}

.details-date {
  margin: 0 0 .25em;
  font-size: clamp(.82rem, 2.6vw, .96rem);
  font-weight: 500;
  letter-spacing: .16em;
  text-indent: .16em;
  text-transform: uppercase;
}

.details-time {
  margin: 0 0 1.4em;
  font-size: clamp(1.05rem, 3.4vw, 1.3rem);
}

.details-note {
  margin: 0 0 clamp(2rem, 6vh, 3rem);
  font-size: clamp(1rem, 3.2vw, 1.18rem);
  font-style: italic;
  color: var(--rose-soft);
}

.countdown {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(.35rem, 2vw, .9rem);
}

.cd-unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .5em;
  min-width: 3.4ch;
}

.cd-num {
  font-size: clamp(1.5rem, 6.5vw, 2.3rem);
  font-weight: 400;
  line-height: 1;
  letter-spacing: .06em;
  font-variant-numeric: tabular-nums; /* stops the digits jittering as they tick */
  font-feature-settings: 'tnum' 1;
}

.cd-label {
  font-size: clamp(.55rem, 1.9vw, .64rem);
  letter-spacing: .22em;
  text-indent: .22em;
  text-transform: uppercase;
  color: var(--rose-soft);
}

.cd-sep {
  font-size: clamp(1.3rem, 5.5vw, 1.9rem);
  line-height: 1;
  color: var(--rose-soft);
}

/* ===== Venue + map ===== */
.venue {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background:
    radial-gradient(ellipse 62% 50% at 50% 46%, #FFF6F3 0%, var(--pink-bg) 64%, var(--pink-deep) 100%);
  padding: clamp(3rem, 10vh, 5.5rem) clamp(1.25rem, 6vw, 2rem) clamp(4rem, 12vh, 6rem);
  text-align: center;
  color: var(--rose-gold);
}

.venue-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 34rem;
  margin: 0 auto;
}

.venue-name {
  margin: 0 0 .45em;
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.65rem, 6vw, 2.4rem);
  line-height: 1.2;
}

.venue-address {
  margin: 0;
  font-size: clamp(.98rem, 3vw, 1.1rem);
  line-height: 1.6;
  color: var(--rose-soft);
}

/* an arched chapel window rather than the usual plain rectangle */
.map-wrap {
  position: relative;
  width: 100%;
  max-width: 25rem;
  margin: clamp(2.5rem, 7vh, 4rem) auto clamp(2.25rem, 6vh, 3.25rem);
}

.map-frame {
  position: relative;
  z-index: 1;              /* sits between the two vine layers */
  aspect-ratio: 4 / 5;

  /* rounded arch on top, squared feet at the bottom */
  border-radius: 50% 50% 10px 10px / 26% 26% 10px 10px;
  overflow: hidden;
  border: 1px solid rgba(183, 110, 98, .45);
  background: var(--pink-bg);

  box-shadow:
    0 22px 44px rgba(140, 90, 80, .22),          /* lift off the page      */
    inset 0 0 0 7px rgba(255, 255, 255, .6),     /* pale mount, like a mat */
    inset 0 0 0 8px rgba(183, 110, 98, .3);      /* inner hairline         */
}

/* bouquets breaking over the frame, so it doesn't read as a pasted-in box */

/* the embed draws a place card in its top-left corner, which the arch would
   slice through. Oversizing the iframe and pulling it up lifts that card above
   the visible area while keeping the pin — and Google's attribution — in view. */
.map-frame iframe {
  position: absolute;
  top: -34%;
  left: 0;
  width: 100%;
  height: 134%;
  border: 0;
  /* warms Google's default blues/greens toward the rose palette */
  filter: sepia(26%) saturate(108%) hue-rotate(-12deg) brightness(1.03);
}

.btn-map {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;              /* comfortable tap target */
  padding: .75em 2.4em;

  border: 1px solid var(--rose-gold);
  border-radius: 2px;
  color: var(--rose-gold);
  text-decoration: none;

  font-size: clamp(.68rem, 2.2vw, .78rem);
  font-weight: 500;
  letter-spacing: .22em;
  text-indent: .22em;
  text-transform: uppercase;

  transition: background-color .25s ease, color .25s ease;
}

.btn-map:hover,
.btn-map:focus-visible {
  background-color: var(--rose-gold);
  color: var(--pink-bg);
}

/* ===== Closing ===== */
.closing {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background:
    radial-gradient(ellipse 58% 62% at 50% 42%, #FFF6F3 0%, var(--pink-bg) 60%, var(--pink-deep) 100%);
  padding: clamp(3.5rem, 12vh, 6rem) clamp(1.25rem, 6vw, 2rem) clamp(4.5rem, 14vh, 7rem);
  text-align: center;
  color: var(--rose-gold);
}

.closing-inner {
  position: relative;
  z-index: 1;
  max-width: 30rem;
  margin: 0 auto;
}

.closing .ornament { margin-bottom: clamp(1.25rem, 4vh, 2rem); }

.closing-note {
  margin: 0 0 .3em;
  font-size: clamp(.7rem, 2.2vw, .82rem);
  font-weight: 500;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  color: var(--rose-soft);
}

.closing-names {
  margin: 0 0 .5em;
  font-family: 'Great Vibes', cursive;
  font-size: clamp(2rem, 7vw, 3.2rem);
  line-height: 1.2;
}

.closing-names .amp {
  padding: 0 .1em;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: .58em;
  color: var(--rose-soft);
  vertical-align: .08em;
}

.closing-thanks {
  margin: 0;
  font-size: clamp(1rem, 3.2vw, 1.15rem);
  font-style: italic;
  color: var(--rose-soft);
}

/* ===== Scroll reveal ===== */
.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .85s var(--ease-soft), transform .85s var(--ease-soft);
}

.reveal.is-in { opacity: 1; transform: none; }

/* ===== Reduced motion ===== */
@media (prefers-reduced-motion: reduce) {
  :root { --fade: .01s; --rise: .01s; }

  #hint { animation: none; opacity: .8; }
  .petals, .petals--page { display: none; }
  .branch { animation: none; transform: scale(var(--flip-x, 1), var(--flip-y, 1)); }

  #envelope,
  .cover-top,
  .cover-bottom {
    animation: none;
    opacity: 1;
    transform: none;
  }

  .envelope-wrap { transform: scale(1.22); } /* keep the size, drop the motion */

  .reveal { opacity: 1; transform: none; transition: none; }
}
