/* Glacial Indifference (Hanken Design Co., SIL Open Font License) isn't on Google Fonts, so it's served from fonts/. */
@font-face { font-family: "Glacial Indifference"; font-style: normal; font-weight: 400; font-display: swap; src: url("../fonts/glacial-indifference/GlacialIndifference-Regular.woff") format("woff"); }
@font-face { font-family: "Glacial Indifference"; font-style: normal; font-weight: 700; font-display: swap; src: url("../fonts/glacial-indifference/GlacialIndifference-Bold.woff") format("woff"); }

:root {
  --raspberry: #9c3153;
  --viva: #b44555;
  --mauve: #c68b97;
  --blush: #eecacf;
  --beige: #d8d2c2;
  --champagne: #f5e8c7;
  --ivory: #fef7e6;
  --paper: #fffcf5;
  --ink: #2e2a2b;
  --muted: #5a5153;
  --silver: #c0c0c0;
  --serif: "Cormorant Garamond", Georgia, serif;
  /* Paragraphs and body text. */
  --body: "EB Garamond", Georgia, serif;
  /* The hero's display date and the pink ampersands. */
  --garamond: "EB Garamond", Georgia, serif;
  --script: "Pinyon Script", cursive;
  /* Supporting text, labels and buttons: menu, eyebrows, form labels, hints, captions. */
  --sans: "Glacial Indifference", "Century Gothic", Arial, sans-serif;
  --content: 1160px;
  color: var(--ink);
  background: var(--paper);
  font-family: var(--body);
  /* Lining (full-height) numbers everywhere, so Garamond's "01" doesn't read as "OI". */
  font-feature-settings: "lnum" 1;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 2rem; }
body { margin: 0; min-width: 320px; background: var(--paper); }
body, button, input, select, textarea { color: var(--ink); }
button, input, select, textarea { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
a { color: inherit; }
img { display: block; max-width: 100%; }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--raspberry);
  outline-offset: 4px;
}
.skip-link {
  position: fixed; z-index: 30; top: 1rem; left: 1rem; padding: .7rem 1rem;
  color: white; background: var(--raspberry); transform: translateY(-160%);
}
.skip-link:focus { transform: translateY(0); }
.ampersand { color: var(--raspberry); font-family: var(--garamond); font-style: normal; font-weight: 400; }
.script { margin: 0; color: var(--raspberry); font: 400 clamp(2rem, 4vw, 3rem)/1.05 var(--script); }
.eyebrow {
  margin: 0 0 .8rem; color: var(--raspberry); font: 400 .72rem/1.4 var(--sans);
  letter-spacing: .19em; text-transform: uppercase;
}

.hero {
  position: relative; min-height: 820px; min-height: max(820px, 100svh); overflow: hidden;
  isolation: isolate; color: white; background: #706158;
}
.hero__photo, .hero__scrim { position: absolute; z-index: -1; inset: 0; width: 100%; height: 100%; }
.hero__photo { object-fit: cover; object-position: 30% 100%; }
/* Wider screens: app.js (setupHeroPhoto) sizes and places the photo itself, zoomed in on the couple, with them on
   the left clear of the text and head to toe in view. */
.hero__photo.is-placed { inset: auto; max-width: none; object-fit: fill; }
.hero__photo.is-short { -webkit-mask-image: linear-gradient(to right, #000 80%, transparent); mask-image: linear-gradient(to right, #000 80%, transparent); }
.hero { background: #2a2524; }
.hero__scrim {
  background: linear-gradient(90deg, rgb(29 24 25 / 4%) 16%, rgb(29 24 25 / 13%) 43%, rgb(29 24 25 / 48%) 100%),
    linear-gradient(0deg, rgb(29 24 25 / 17%), transparent 32%);
}
.hero__frame { position: relative; min-height: inherit; width: min(100% - 8vw, 1440px); margin: auto; }
.brand-mark {
  position: absolute; top: 2.2rem; left: 0; display: grid; color: white; text-decoration: none;
  justify-items: center; line-height: .9;
}
.brand-mark__logo { width: 4rem; height: auto; filter: drop-shadow(0 2px 6px rgb(29 24 25 / 35%)); }
.site-nav { position: absolute; top: 2.4rem; right: 0; display: flex; align-items: center; gap: clamp(.75rem, 1.65vw, 1.6rem); }
.site-nav a {
  position: relative; padding: .35rem 0; color: white; text-decoration: none;
  font: .67rem var(--sans); letter-spacing: .1em; text-transform: uppercase;
}
.site-nav a:not(.nav-rsvp)::after {
  position: absolute; right: 0; bottom: 0; left: 0; height: 1px;
  background: white; content: ""; transform: scaleX(0); transform-origin: left; transition: transform .25s ease;
}
.site-nav a:hover::after, .site-nav a.is-active::after { transform: scaleX(1); }
.site-nav .nav-rsvp { border: 1px solid rgb(255 255 255 / 76%); border-radius: 99px; padding: .68rem 1.25rem; transition: background .2s, color .2s; }
.site-nav .nav-rsvp:hover { color: var(--raspberry); background: white; }
.menu-toggle { display: none; }
.hero__copy {
  position: absolute; top: 49%; right: 4%; width: min(55%, 690px); text-align: center;
  transform: translateY(-45%);
}
.hero__welcome { margin-bottom: .25rem; color: white; font-size: clamp(2.7rem, 5.3vw, 4.5rem); }
.hero h1 {
  margin: 0; color: white; font: 600 clamp(4rem, 8.5vw, 7rem)/.95 var(--serif);
  letter-spacing: .015em; text-transform: uppercase; white-space: nowrap;
}
.hero__date { margin: 1rem 0 0; color: white; font: 400 clamp(1.6rem, 2.8vw, 2.2rem) var(--garamond); }
.hero__discover {
  display: grid; width: 2.5rem; height: 2.5rem; margin: 3rem auto 0; place-items: center;
  border: 1px solid rgb(255 255 255 / 58%); border-radius: 50%; color: white;
  font: 1.2rem var(--sans); text-decoration: none; transition: background .2s, transform .2s;
}
.hero__discover:hover { background: rgb(255 255 255 / 17%); transform: translateY(3px); }
.hero [data-hero-reveal] { animation: hero-rise .8s both; }
.hero__welcome { animation-delay: .15s !important; }
.hero h1 { animation-delay: .35s !important; }
.hero__date { animation-delay: .55s !important; }

/* Invitation letter: covers the site until the guest opens it (the head script adds .has-letter; app.js runs it).
   Tapping the seal unfolds the envelope from the centre out (top, sides, then bottom flap) and the doodle plays
   on the letter page underneath, then the letter fades away to reveal the site. */
.letter { display: none; }
.has-letter body { overflow: hidden; }
.has-letter .hero [data-hero-reveal] { animation-play-state: paused; }
.has-letter .letter, .letter-leaving .letter {
  position: fixed; z-index: 100; inset: 0; display: block; overflow: hidden;
  background: radial-gradient(circle at 18% 12%, rgb(247 231 195 / 45%), transparent 42%),
    radial-gradient(circle at 85% 90%, rgb(245 200 207 / 30%), transparent 40%), var(--paper);
}
.letter-leaving .letter { opacity: 0; transform: scale(1.04); transition: opacity 1.1s ease, transform 1.1s ease; pointer-events: none; }
.letter__page {
  position: absolute; inset: 0; display: grid; place-content: center; justify-items: center;
  padding: 2rem 1rem 4rem; text-align: center;
}
.letter__doodle { width: min(94vw, 880px, (100svh - 28rem) * 1.6); aspect-ratio: 1920 / 1200; }
.letter__message { opacity: 0; transform: translateY(14px); transition: opacity .9s ease, transform .9s ease; }
.letter.is-welcomed .letter__message { opacity: 1; transform: none; }
.letter__welcome { margin-top: 1.2rem; font-size: clamp(2rem, 4.4vw, 3rem); }
.letter__welcome + .letter__note { margin-top: 1rem; }
.letter__note { max-width: 560px; margin: .8rem auto 0; color: var(--ink); font-size: clamp(1.1rem, 2.4vw, 1.3rem); line-height: 1.4; }
.letter__byline { margin: 1.8rem 0 0; color: var(--muted); }
.letter__timer { width: min(220px, 60vw); margin: 1.5rem auto 0; }
.letter__timer p { margin: 0 0 .5rem; color: var(--muted); font: .7rem var(--sans); letter-spacing: .14em; text-transform: uppercase; }
.letter__timer-bar { display: block; height: 2px; overflow: hidden; background: rgb(156 49 83 / 16%); }
.letter__timer-bar span { display: block; height: 100%; background: var(--raspberry); transform-origin: left; transition: transform var(--letter-wait, 8s) linear; }
.letter.is-welcomed .letter__timer-bar span { transform: scaleX(0); }

.letter__envelope { position: absolute; inset: 0; perspective: 2000px; }
.letter.is-opening .letter__envelope { pointer-events: none; }
/* Each flap folds over its outer edge, towards the guest, until it lies off screen. */
.letter__flap { position: absolute; inset: 0; transition: transform .9s cubic-bezier(.45, 0, .2, 1); }
.letter__flap--left {
  background: linear-gradient(90deg, #f3c6cd, #ecb4be); clip-path: polygon(0 0, 50% 52%, 0 100%);
  transform-origin: left center; transition-delay: .45s;
}
.letter__flap--right {
  background: linear-gradient(270deg, #f3c6cd, #ecb4be); clip-path: polygon(100% 0, 50% 52%, 100% 100%);
  transform-origin: right center; transition-delay: .45s;
}
.letter__flap--bottom {
  background: linear-gradient(0deg, #f6ccd2, #f1bdc6); clip-path: polygon(0 100%, 50% 47%, 100% 100%);
  transform-origin: bottom center; transition-delay: .7s;
}
.letter__flap--top {
  background: linear-gradient(180deg, #f0bac4, #e6a4b1); clip-path: polygon(0 0, 100% 0, 50% 56%);
  transform-origin: top center; transition-delay: .15s;
}
.letter.is-opening .letter__flap--top { transform: rotateX(180deg); }
.letter.is-opening .letter__flap--left { transform: rotateY(-180deg); }
.letter.is-opening .letter__flap--right { transform: rotateY(180deg); }
.letter.is-opening .letter__flap--bottom { transform: rotateX(-180deg); }
.letter__address {
  position: absolute; z-index: 1; top: calc(56% + 5.3rem); right: 0; left: 0; padding: 0 1.5rem; text-align: center;
  transition: opacity .3s ease;
}
.letter.is-opening .letter__address { opacity: 0; }
.letter__couple { font-size: clamp(3.2rem, 9vw, 4.8rem); }
.letter__hint { margin: 1.1rem 0 0; color: var(--muted); font: .68rem var(--sans); letter-spacing: .2em; text-transform: uppercase; }
.letter__seal {
  position: absolute; z-index: 2; top: 56%; left: 50%; display: block; width: 124px; height: 124px;
  padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer;
  transform: translate(-50%, -50%); transition: transform .45s cubic-bezier(.3, 1.5, .5, 1), opacity .35s ease;
}
.letter__seal::after {
  position: absolute; inset: 6%; border: 1px solid var(--raspberry); border-radius: 50%; content: "";
  animation: music-pulse 1.8s ease-out infinite;
}
/* The wax seal photo, cut out of its black backdrop (images/monogram/wax-seal-cutout.png). */
.letter__seal img { position: relative; z-index: 1; display: block; width: 100%; height: 100%; filter: drop-shadow(0 10px 14px rgb(87 20 45 / 35%)); }
.letter__seal:hover { transform: translate(-50%, -50%) scale(1.06); }
.letter__seal:focus-visible { outline: 2px solid var(--raspberry); outline-offset: 10px; }
.letter.is-opening .letter__seal { opacity: 0; transform: translate(-50%, -50%) scale(1.35); pointer-events: none; }
.letter__skip {
  position: absolute; z-index: 3; right: 1.25rem; bottom: 1.25rem; padding: .6rem .8rem; border: 0;
  background: none; color: var(--muted); font: .7rem var(--sans); letter-spacing: .2em; text-transform: uppercase;
  cursor: pointer; opacity: 0; pointer-events: none;
}
.letter.is-opening .letter__skip { opacity: 1; pointer-events: auto; transition: opacity .6s ease 1.6s; }

.floral {
  position: absolute; z-index: 0; width: clamp(145px, 24vw, 330px); pointer-events: none;
  --flower-rotation: 0deg; --flower-flip: 1;
  height: auto; filter: drop-shadow(0 10px 18px rgb(46 42 43 / 12%));
  transform: rotate(var(--flower-rotation)) scaleX(var(--flower-flip)) scale(.9);
}

.ticker { position: absolute; z-index: 5; right: 0; bottom: 0; left: 0; overflow: hidden; color: var(--ivory); background: var(--raspberry); }
.ticker__track { display: flex; width: max-content; min-height: 58px; align-items: center; animation: ticker-scroll 65s linear infinite; }
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker__group { display: flex; flex: 0 0 auto; align-items: center; }
.ticker__item { display: inline-flex; align-items: center; white-space: nowrap; font: 500 .9rem var(--sans); letter-spacing: .2em; text-transform: uppercase; }
.ticker__diamond { width: 6px; height: 6px; margin: 0 1.45rem; background: var(--blush); transform: rotate(45deg); }

.section { position: relative; overflow: hidden; padding: clamp(5rem, 9vw, 8.5rem) 1.5rem; }
.section__inner { position: relative; z-index: 1; width: min(100%, var(--content)); margin: 0 auto; }
.section__inner--narrow { max-width: 760px; }
.section__inner--wide { max-width: 1240px; }
.section-heading { margin: 0 auto 3.3rem; text-align: center; }
.section-heading h2 { margin: 0; color: var(--ink); font: 500 clamp(2.35rem, 4.7vw, 3.5rem)/1.1 var(--serif); letter-spacing: .13em; text-transform: uppercase; }
.ornament { width: min(260px, 64vw); aspect-ratio: 339 / 64; margin: .9rem auto .7rem; background: url("../images/cliparts/ribbon-divider-cropped.png") center / contain no-repeat; }
.ornament span { display: none; }
.section-heading__intro { max-width: 490px; margin: 0 auto; color: var(--muted); font-size: 1.2rem; line-height: 1.45; }
.details-section { background: #fcfbf1; }
.details-section .section-heading__intro { max-width: none; }
.details-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
/* Flip cards (setupDetailCards in app.js toggles .is-flipped). Both faces share one grid cell, so the card is
   as tall as its taller side; the face turned away is hidden and made inert. */
.detail-card { position: relative; perspective: 2000px; }
.detail-card__inner {
  display: grid; height: 100%; transform-style: preserve-3d;
  transition: transform .85s cubic-bezier(.3, .7, .2, 1);
}
.detail-card.is-flipped .detail-card__inner { transform: rotateY(180deg); }
.detail-card__face {
  position: relative; display: flex; grid-area: 1 / 1; flex-direction: column; padding: clamp(1.7rem, 4vw, 3rem);
  border: 1px solid #eaded7; background: var(--ivory); text-align: center;
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
.detail-card__front { cursor: pointer; }
.details-section.bg-ready .detail-card__front { --art: var(--art-src); }
.detail-card__back { transform: rotateY(180deg); }
/* The front is the venue sketch (--art, from data.js) filling the card, anchored to the bottom so the building
   sits low and the sky is cropped. Paper fades at the top and bottom keep the text and the flip link readable. */
.detail-card__front {
  min-height: clamp(680px, 50vw, 720px); overflow: hidden;
  background:
    linear-gradient(180deg, var(--ivory) 30%, rgb(255 246 228 / 72%) 38%, rgb(255 246 228 / 0%) 50%, rgb(255 246 228 / 0%) 80%, rgb(255 246 228 / 92%) 95%),
    var(--art, none) no-repeat center bottom / cover,
    var(--ivory);
}
.detail-card__front .detail-card__toggle { margin-top: auto; }
/* artWhole in data.js: the drawing is scaled to sit below the text with its top showing, and the top fade is
   shorter so it doesn't wash it out. */
.detail-card__front--whole {
  background:
    linear-gradient(180deg, var(--ivory) 16%, rgb(255 246 228 / 0%) 32%, rgb(255 246 228 / 0%) 80%, rgb(255 246 228 / 92%) 95%),
    var(--art, none) no-repeat center bottom / var(--art-size, auto 72%),
    var(--ivory);
}
.detail-card__back .map-frame { flex: 1 0 auto; height: auto; min-height: 240px; }
.detail-card__toggle {
  align-self: center; margin-top: 1rem; padding: .5rem .9rem; border: 0; background: none; cursor: pointer;
  color: var(--raspberry); font: .7rem var(--sans); letter-spacing: .12em; text-transform: uppercase;
}
.detail-card__toggle span { display: inline-block; transition: transform .4s ease; }
.detail-card__toggle:hover span { transform: rotate(180deg); }
.detail-card__directions { display: flex; flex-wrap: wrap; justify-content: center; gap: .6rem; margin-top: 1rem; }
.directions-button {
  display: inline-flex; min-height: 42px; align-items: center; gap: .45rem; padding: .55rem 1.1rem; border: 1px solid var(--raspberry);
  border-radius: 99px; color: var(--raspberry); font: .68rem var(--sans); letter-spacing: .1em; text-decoration: none; text-transform: uppercase;
  transition: background .2s, color .2s, transform .2s;
}
.directions-button svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.attire-card__inspire { align-self: center; margin-top: auto; background: transparent; cursor: pointer; }
.directions-button:hover { background: var(--raspberry); color: white; transform: translateY(-1px); }
.detail-card__number { position: absolute; top: 1.2rem; right: 1.35rem; color: #b9a9a2; font: .72rem var(--sans); letter-spacing: .14em; }
.detail-card h3 { margin: 0 0 .55rem; font: 500 clamp(1.65rem, 3vw, 2.2rem)/1.08 var(--serif); }
.detail-card__location { margin: 0; color: var(--muted); font-size: 1.1rem; line-height: 1.35; }
.details-note { max-width: 640px; margin: 1.8rem auto 0; color: var(--muted); font-size: 1.1rem; font-style: italic; line-height: 1.4; text-align: center; }
.details-note strong { color: var(--raspberry); font-style: normal; font-weight: 500; }
.detail-card__note { min-height: 3.2rem; margin: 1rem 0 1.3rem; color: var(--muted); font-style: italic; font-size: 1rem; }
.map-frame {
  position: relative; height: 290px; overflow: hidden; border: 1px solid #d8c7c1;
  background: #f7e7c3;
}
/* Static on purpose: the pin is drawn over the map's center, so panning would pull the map out from under it.
   The extra width and height push the zoom buttons out of view; the pin's offsets follow the map's shifted center. */
.map-frame iframe {
  position: absolute; top: -70px; left: 0; display: block; width: calc(100% + 56px); height: calc(100% + 70px); border: 0; opacity: .78; pointer-events: none;
  filter: grayscale(1) sepia(.16) contrast(.86) brightness(1.04);
}
.map-pin { position: absolute; top: calc(50% - 35px); left: calc(50% + 28px); width: 30px; height: auto; filter: drop-shadow(0 3px 3px rgb(46 42 43 / 35%)); pointer-events: none; transform: translate(-50%, -100%); }
.map-pin path { fill: var(--raspberry); stroke: white; stroke-width: 1.2; }
.map-pin circle { fill: white; }
.text-link { display: inline-block; margin-top: 1rem; color: var(--raspberry); font: .72rem var(--sans); letter-spacing: .11em; text-decoration: none; text-transform: uppercase; }
.text-link span { display: inline-block; padding-left: .35rem; transition: transform .2s; }
.text-link:hover span { transform: translate(2px, -2px); }
.floral--details { right: -6rem; bottom: -7rem; width: 250px; --flower-rotation: -18deg; }
.floral--details-top { top: -4rem; left: -5rem; width: 230px; --flower-rotation: 150deg; }

/* The painting drifts slower than the page: --p (app.js) runs 0 → 1 across the section's time on screen, and it is
   30% taller than the section to cover that travel. ::after is the dark layer between it and the text. */
.timeline-section { background: #1d1819; }
.timeline-photo {
  position: absolute; top: -15%; left: 0; width: 100%; height: 130%; object-fit: cover;
  transform: translate3d(0, calc((var(--p, .5) - .5) * 23%), 0); will-change: transform;
}
.timeline-section::after { position: absolute; inset: 0; background: rgb(29 24 25 / 66%); content: ""; pointer-events: none; }
.timeline-section { color: white; text-shadow: 0 1px 10px rgb(29 24 25 / 55%); }
.timeline-section .section-heading h2, .timeline-section .section-heading__intro { color: white; }
.timeline-section .section-heading { margin-bottom: 2.7rem; }
/* --time: width of the time column; the line and the icon badges sit in the middle of --gap. */
.timeline-list {
  --time: 72px; --gap: 5rem; --badge: 62px; position: relative; display: grid; max-width: 980px; grid-auto-flow: column;
  grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(var(--rows, 4), 1fr); column-gap: 2rem;
  margin: 0 auto; padding: 0; list-style: none;
}
.timeline-row { position: relative; display: grid; grid-template-columns: var(--time) 1fr; gap: var(--gap); min-height: calc(var(--badge) + 1.4rem); padding: 0 0 2.2rem; }
.timeline-row::before { position: absolute; top: .8rem; bottom: -.8rem; left: calc(var(--time) + var(--gap) / 2); width: 1px; background: white; content: ""; }
.timeline-row:last-child::before, .timeline-row--column-end::before { display: none; }
.timeline-row time { padding-top: .38rem; color: white; font: 500 .8rem var(--sans); letter-spacing: .1em; text-align: right; white-space: nowrap; }
.timeline-row h3 { margin: 0; color: white; font: 500 1.45rem/1.15 var(--serif); }
.timeline-row p { margin: .25rem 0 0; color: white; font-size: 1.05rem; }
.timeline-row h3 a { color: white; text-decoration: underline; text-decoration-color: white; text-underline-offset: 4px; }
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
/* Hand-drawn icons (app.js): roughened by the #sketch filter and sketched in stroke by stroke once the row is revealed. */
.timeline-icon {
  position: absolute; top: calc(.8rem - var(--badge) / 2); left: calc(var(--time) + var(--gap) / 2 - var(--badge) / 2);
  width: var(--badge); height: var(--badge); overflow: visible; fill: none; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .5s cubic-bezier(.3, 1.4, .5, 1);
}
.timeline-row:hover .timeline-icon { transform: rotate(-7deg) scale(1.1); }
.timeline-icon__ring { fill: white; stroke: white; stroke-width: 1.4; }
.timeline-icon__ring--pencil { fill: none; stroke-width: .7; opacity: .55; }
.timeline-icon__wash { fill: var(--blush); opacity: 0; transition: opacity .8s ease calc(var(--reveal-index, 0) * 110ms + .3s); }
.timeline-icon__ink { stroke: var(--ink); stroke-width: 1.7; }
.timeline-icon__ink .accent { stroke: var(--raspberry); }
.timeline-icon__ring, .timeline-icon__ink path {
  stroke-dasharray: 1.02 1.1; stroke-dashoffset: 1.05;
  transition: stroke-dashoffset 1.8s cubic-bezier(.4, 0, .2, 1) calc(var(--reveal-index, 0) * 110ms + .35s);
}
.timeline-row.is-visible .timeline-icon__wash { opacity: .6; }
.timeline-row.is-visible .timeline-icon__ring, .timeline-row.is-visible .timeline-icon__ink path { stroke-dashoffset: 0; }
.floral--timeline { right: -8rem; bottom: -5rem; width: 300px; --flower-rotation: -22deg; }
.floral--timeline-left { top: 2rem; left: -6rem; width: 240px; --flower-rotation: 24deg; --flower-flip: -1; }

.attire-section { background: var(--paper); }
.attire-dress-code.section-heading__intro { color: var(--raspberry); font: 400 clamp(2.4rem, 4vw, 3.2rem)/1.2 var(--script); }
.attire-grid { display: grid; max-width: 900px; grid-template-columns: repeat(2, 1fr); gap: 1.4rem; margin: 0 auto; }
.attire-card { position: relative; display: flex; flex-direction: column; padding: 2.8rem 2rem 1.8rem; border: 1px solid #eaded7; background: #fffaf3; text-align: center; }
.attire-card__scene { display: block; width: min(100%, 300px); height: auto; margin: 0 auto 1.2rem; }
.attire-card h3 { margin: 0 0 1.1rem; font: 500 1.8rem var(--serif); }
.attire-card > p:not(.eyebrow) { max-width: 310px; min-height: 3rem; margin: 0 auto; color: var(--muted); font-size: 1.1rem; line-height: 1.35; }
.swatches { display: flex; justify-content: center; gap: .35rem; margin: 1.7rem 0 1.4rem; padding: 0; list-style: none; }
.swatch { display: grid; flex: 0 1 4.2rem; min-width: 0; justify-items: center; gap: .7rem; }
.swatch__chip {
  width: 58px; height: 58px; border: 1px solid rgb(46 42 43 / 14%); border-radius: 50%;
  box-shadow: 0 0 0 4px #fffaf3, 0 0 0 5px rgb(46 42 43 / 9%);
  transition: transform .45s cubic-bezier(.3, 1.5, .5, 1), box-shadow .35s ease;
}
.swatch__name { color: var(--muted); font: .6rem var(--sans); letter-spacing: .1em; text-transform: uppercase; transition: color .3s ease, transform .45s cubic-bezier(.3, 1.5, .5, 1); }
.swatch:hover .swatch__chip { transform: translateY(-3px) scale(1.35); box-shadow: 0 0 0 4px #fffaf3, 0 0 0 5px rgb(46 42 43 / 9%), 0 14px 24px rgb(46 42 43 / 20%); }
.swatch:hover .swatch__name { color: var(--raspberry); transform: translateY(8px); }
.swatch--black { background: #292727; }.swatch--gray { background: #888783; }.swatch--beige { background: var(--beige); }
.swatch--blush { background: var(--blush); }.swatch--taupe { background: #92867c; }.swatch--champagne { background: var(--champagne); }
.floral--attire { bottom: -6rem; left: -5rem; width: 260px; --flower-rotation: 28deg; }
.floral--attire-top { top: -3rem; right: -6rem; width: 250px; --flower-rotation: -150deg; }

.section.prosperity-section { padding-inline: 0; background: #fffefa; isolation: isolate; }
/* The pale ribbon needs deepening on the colored sections. */
/* z-index: auto keeps the video in the same stacking context as the section background it blends with. */
.prosperity-layout { z-index: auto; width: 100%; }
.prosperity-layout .section-heading { position: relative; z-index: 1; margin-bottom: .6rem; padding-inline: 1.5rem; }
/* The animation is drawn on white, so multiply drops that white into the ivory, and the mask feathers the edges.
   Both sit on the element that fades in, so the video blends with the section from the first frame of its reveal. */
.prosperity-video {
  width: min(100%, 920px); margin: 0 auto; mix-blend-mode: multiply;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent), linear-gradient(to bottom, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent), linear-gradient(to bottom, transparent, #000 7%, #000 93%, transparent);
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
.prosperity-video video { display: block; width: 100%; height: auto; }
.prosperity-copy {
  position: relative; z-index: 1; display: grid; max-width: 1000px; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem clamp(1.8rem, 4vw, 3.2rem); margin: 1.4rem auto 0; padding-inline: 1.5rem;
}
.prosperity-copy h3 { grid-column: 1 / -1; margin: 0; color: var(--raspberry); font: 400 clamp(2.2rem, 4vw, 2.8rem)/1.2 var(--script); text-align: center; }
.prosperity-copy p { margin: 0; color: var(--ink); font-size: 1.1rem; line-height: 1.45; }
.floral--prosperity { right: -8rem; bottom: -10rem; width: 250px; --flower-rotation: -24deg; }
.floral--prosperity-top { top: -3rem; left: -6rem; width: 240px; --flower-rotation: 150deg; }

.section.gifts-section { padding-block: clamp(4.5rem, 7vw, 6rem) clamp(3rem, 5vw, 4.5rem); background: var(--raspberry); text-align: center; }
.gifts-section .section-heading h2 { color: var(--ivory); }
.gifts-layout { display: grid; max-width: 1040px; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 0 clamp(2rem, 5vw, 4rem); align-items: center; }
.gifts-layout .section-heading { grid-column: 1 / -1; width: 100%; margin-bottom: 1.6rem; }
.gifts-section .ornament { width: min(180px, 50vw); margin-block: .6rem .3rem; }
.gifts-copy { text-align: left; }
.gifts-copy .gifts-copy__lead { font: 500 clamp(1.5rem, 2.6vw, 1.8rem)/1.2 var(--serif); }
.gifts-copy p { margin: 0 0 .9rem; color: var(--ivory); font-size: 1.3rem; line-height: 1.45; }
/* The crochet frame from the clipart wraps the QR; only its lace edge shows, and the card stays plain white. */
.gifts-qr {
  display: grid; width: min(100%, 372px); min-height: 240px; margin: 0 auto; padding: .4rem;
  place-items: center; border: 36px solid transparent; background: #fff padding-box;
}
.gifts-section.bg-ready .gifts-qr { border-image: url("../images/cliparts/square%20frame.png") 60 round; }
.gifts-qr img { display: block; width: 100%; height: auto; }
.gifts-qr .text-link { margin: .4rem 0 .5rem; }
.gifts-qr__empty { margin: 0; color: var(--muted); font: .7rem var(--sans); letter-spacing: .16em; text-transform: uppercase; }

/* Image backgrounds get a dark layer (the gradient) so the text in front stays legible. */
/* The pattern only frames the section: the names sit on a plain paper card with a double-rule border, like a
   printed wedding-party page, so nothing busy runs behind the text. */
.entourage-section { background: #ebe4d6 center / cover; }
.entourage-section.bg-ready { background-image: url("../images/covers/entourage-bg.webp"); }
.entourage-section .section__inner {
  max-width: 980px; padding: clamp(2.6rem, 6vw, 4.5rem) clamp(1.2rem, 5vw, 4rem); background: #fffcf3;
  border: 1px solid rgb(156 49 83 / 30%); outline: 1px solid rgb(156 49 83 / 30%); outline-offset: -10px;
  box-shadow: 0 18px 50px rgb(80 60 20 / 18%);
}
.entourage-section .section-heading { margin-bottom: 2.8rem; }
/* The wedding party: two columns mirrored around the center line, so each side reads toward the middle. */
.party { --party-gap: clamp(1.4rem, 5vw, 3.5rem); max-width: 860px; margin: 0 auto; }
.party-row, .party-sponsors li { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--party-gap); }
.party-row { margin-bottom: 2.4rem; }
.party-row > :first-child, .party-sponsors li > :first-child { text-align: right; }
.party-row > :last-child, .party-sponsors li > :last-child { text-align: left; }
.party h3 { margin: 0 0 .35rem; color: var(--raspberry); font: 400 clamp(1.55rem, 3vw, 1.9rem)/1.2 var(--script); }
.party h3.party-title { margin: 3rem 0 1.2rem; font-size: clamp(1.8rem, 3.4vw, 2.3rem); text-align: center; }
.party-names, .party-sponsors { color: var(--ink); font: 400 1rem/1.7 var(--serif); letter-spacing: .07em; text-transform: uppercase; }
.party-names { margin: 0; }
.party-names span { display: block; }
.party-sponsors { margin: 0 0 3rem; padding: 0; list-style: none; line-height: 2; }
/* Entrance, once each block scrolls in (setupReveals adds .is-visible): script titles write themselves in from
   left to right, the bride's and groom's sides slide in toward the center, and names fade up one after another
   (--i, set in app.js). */
/* The clip goes on the group titles and on the text inside the centered ones, never on an observed .reveal
   element itself: a fully clipped element never counts as on screen, so it would never be revealed. */
.party-group h3, .party-title > span { clip-path: inset(-20% 100% -20% 0); transition: clip-path 1.3s cubic-bezier(.55, .1, .3, 1) .1s; }
.party-title > span { display: inline-block; }
.party .is-visible h3, .party-title.is-visible > span { clip-path: inset(-20% -10% -20% -10%); }
.party-row > .party-group { transition: transform 1s cubic-bezier(.2, .7, .2, 1); }
.party-row:not(.is-visible) > :first-child { transform: translateX(-32px); }
.party-row:not(.is-visible) > :last-child { transform: translateX(32px); }
.party-names span, .party-sponsors li, .party-flower-girls li {
  opacity: 0; transform: translateY(10px);
  transition: opacity .6s ease, transform .7s cubic-bezier(.2, .7, .2, 1), color .3s ease;
  transition-delay: calc(var(--i, 0) * 70ms + .45s);
}
.party .is-visible .party-names span, .party-sponsors.is-visible li, .party-flower-girls.is-visible li { opacity: 1; transform: none; }
.party-names span:hover, .party-sponsors span:hover, .party-flower-girls li:hover { color: var(--raspberry); transition-delay: 0s; }
/* Three across with the middle one dropped, like the sample. */
.party-secondary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: var(--party-gap); text-align: center; }
.party-secondary > :nth-child(2) { padding-top: 2.6rem; }
.party-bearers { margin-top: 2.8rem; }
/* Two, one, two across. */
.party-flower-girls { display: grid; max-width: 560px; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem 1rem; margin: 0 auto; padding: 0; color: var(--ink); font: 400 1rem/1.4 var(--serif); letter-spacing: .07em; list-style: none; text-align: center; text-transform: uppercase; }
.party-flower-girls li:nth-child(3n) { grid-column: 1 / -1; }
.floral--entourage { right: -8rem; bottom: -8rem; width: 320px; --flower-rotation: -24deg; }
.floral--entourage-top { top: -2rem; left: -7rem; width: 280px; --flower-rotation: 32deg; }

.gallery-section { background: var(--ivory); }
.gallery-section .section-heading { margin-bottom: 2.5rem; }
.floral--gallery-left { top: -3rem; left: -5rem; width: 240px; --flower-rotation: 20deg; }
.floral--gallery-right { top: -2rem; right: -5rem; width: 230px; --flower-rotation: -20deg; --flower-flip: -1; }
/* Photo album: a sideways strip that scrolls on its own; vertical scrolling carries on past it. */
.section.gallery-section { padding-inline: 0; }
.gallery-section .section-heading { padding-inline: 1.5rem; }
.gallery-track {
  display: flex; gap: 1.1rem; padding: .5rem max(1.5rem, (100vw - 1240px) / 2) 1rem;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none;
}
.gallery-track::-webkit-scrollbar { display: none; }
.gallery-track:focus-visible { outline: 2px solid var(--raspberry); outline-offset: -2px; }
.gallery-item {
  position: relative; flex: none; height: clamp(220px, 100svh - 20rem, 540px); min-width: 120px; margin: 0; padding: 0;
  overflow: hidden; border: 0; background: #e6d9d1; cursor: zoom-in; scroll-snap-align: center;
}
/* Every photo keeps its own shape: the row height is fixed and each one is as wide as its proportions need. */
.gallery-item img { display: block; width: auto; height: 100%; object-fit: contain; transition: transform .55s cubic-bezier(.2,.7,.2,1); }
.gallery-controls { display: flex; align-items: center; justify-content: center; gap: 1.1rem; margin-top: 1rem; padding-inline: 1.5rem; }
.gallery-arrow {
  display: grid; width: 44px; height: 44px; flex: none; place-items: center; border: 1px solid var(--mauve); border-radius: 50%;
  background: transparent; color: var(--raspberry); cursor: pointer; font: 1.05rem var(--sans); transition: background .2s, opacity .2s;
}
.gallery-arrow:hover:not(:disabled) { background: var(--blush); }
.gallery-arrow:disabled { opacity: .35; cursor: default; }
.gallery-progress { width: min(240px, 42vw); height: 2px; background: rgb(169 37 83 / 15%); }
.gallery-progress span { display: block; height: 100%; background: var(--raspberry); transform: scaleX(var(--gallery-p, 0)); transform-origin: left; }
.gallery-item:hover img { transform: scale(1.045); }
/* Loading: a portrait-shaped placeholder with a soft shimmer until the photo arrives (app.js adds .is-loaded). */
.gallery-item:not(.is-loaded) { aspect-ratio: 2 / 3; cursor: progress; }
.gallery-item:not(.is-loaded)::before {
  position: absolute; inset: 0; content: "";
  background: linear-gradient(100deg, transparent 30%, rgb(255 255 255 / 55%) 50%, transparent 70%) 0 0 / 250% 100% no-repeat;
  animation: gallery-shimmer 1.5s ease-in-out infinite;
}
.gallery-item.is-failed::before { animation: none; }
.gallery-item img { opacity: 0; }
.gallery-item.is-loaded img { opacity: 1; transition: opacity .6s ease, transform .55s cubic-bezier(.2,.7,.2,1); }
@keyframes gallery-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
.gallery-item::after { position: absolute; inset: 0; border: 1px solid rgb(255 255 255 / 20%); content: ""; pointer-events: none; }

.rsvp-section { display: grid; min-height: 800px; place-items: center; padding-top: 7rem; padding-bottom: 7rem; background: var(--mauve) center / cover; }
.rsvp-section.bg-ready { background-image: linear-gradient(rgb(29 24 25 / 45%), rgb(29 24 25 / 45%)), url("../images/covers/rsvp_liles_bg.JPG"); }
.rsvp-card { position: relative; z-index: 2; width: min(100%, 620px); padding: clamp(2rem, 6vw, 4.5rem); border: 1px solid #e9d9d5; background: #fffefa; }
.rsvp-card .section-heading { margin-bottom: 2rem; }
.rsvp-card .section-heading h2 { font-size: 2.8rem; }
.rsvp-card .section-heading__intro, .rsvp-deadline { color: var(--muted); font-size: 1.1rem; }
.rsvp-deadline { margin: .5rem 0 0; }
.rsvp-deadline strong { color: var(--raspberry); font-weight: 500; }
.rsvp-couple { position: absolute; top: 1.6rem; right: 1.8rem; width: 78px; height: auto; }
.form-field { margin: 0 0 1.25rem; }
.form-field label, .form-field legend { display: block; margin: 0 0 .45rem; font: .7rem var(--sans); letter-spacing: .12em; text-transform: uppercase; }
.form-field label span { color: var(--muted); font-size: .64rem; letter-spacing: .05em; text-transform: none; }
.form-field input, .form-field select, .form-field textarea {
  width: 100%; min-height: 48px; padding: .7rem 1rem; border: 1px solid #d9cbc2;
  border-radius: 14px; background: #fffdf8; font: 1.05rem var(--body); color: var(--ink);
  box-shadow: inset 0 1px 2px rgb(46 42 43 / 4%); transition: border-color .2s ease, box-shadow .2s ease;
}
.form-field input:hover, .form-field select:hover, .form-field textarea:hover { border-color: #c6aaa9; }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus { border-color: var(--raspberry); box-shadow: 0 0 0 4px rgb(169 37 83 / 10%); }
.form-field input:focus-visible, .form-field select:focus-visible, .form-field textarea:focus-visible { outline: none; }
.form-field textarea { min-height: 96px; resize: vertical; }
/* Dropdown: the browser's arrow replaced by a raspberry chevron set in from the edge. */
.form-field select {
  -webkit-appearance: none; appearance: none; padding-right: 3rem; cursor: pointer;
  background: #fffdf8 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 6l4.5 4.5L12.5 6' fill='none' stroke='%23a92553' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 1.1rem center / 16px;
}
.form-field select:invalid, .form-field select:has(option[value=""]:checked) { color: var(--muted); }
.form-field select option { color: var(--ink); }
/* Date picker: a raspberry calendar icon in place of the browser's; app.js opens the picker on any click.
   The native icon stays in place, invisible, so it still works where showPicker() is missing. */
.form-field input[type="date"] {
  -webkit-appearance: none; appearance: none; position: relative; padding-right: 3rem; text-align: left; cursor: pointer;
  background: #fffdf8 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none' stroke='%23a92553' stroke-width='1.4' stroke-linecap='round'%3E%3Crect x='2.5' y='3.5' width='13' height='12' rx='2.5'/%3E%3Cpath d='M2.5 7.5h13M6 2v3M12 2v3'/%3E%3C/svg%3E") no-repeat right 1.05rem center / 18px;
}
.form-field input[type="date"]::-webkit-date-and-time-value { text-align: left; }
.form-field input[type="date"]::-webkit-calendar-picker-indicator {
  position: absolute; top: 0; right: 0; width: 3rem; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer;
}
/* Firefox draws its own calendar button that can't be hidden, so skip the extra icon there. */
@supports (-moz-appearance: none) { .form-field input[type="date"] { background-image: none; padding-right: 1rem; } }
.form-field input[aria-invalid="true"], .form-field select[aria-invalid="true"] { border-color: #a31f43; }
.attendance-field { min-width: 0; padding: 0; border: 0; }
.attendance-field legend { padding: 0; }
.attendance-options { display: flex; flex-wrap: wrap; gap: .55rem; }
.choice-button {
  min-height: 43px; padding: .65rem 1rem; border: 1px solid #c6aaa9; border-radius: 99px;
  background: transparent; color: var(--muted); cursor: pointer; font: .67rem var(--sans); letter-spacing: .07em;
  transition: background .2s, border-color .2s, color .2s, transform .2s;
}
.choice-button:hover { transform: translateY(-1px); border-color: var(--raspberry); }
.choice-button[aria-pressed="true"] { border-color: var(--raspberry); background: var(--raspberry); color: white; }
.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 .9rem; }
.arrival-field { min-width: 0; padding: 0; border: 0; }
.arrival-field legend { padding: 0; }
.arrival-options { display: flex; flex-wrap: wrap; gap: .55rem; }
/* Radio choices drawn as the same pills as the attendance buttons. */
.choice-pill { position: relative; cursor: pointer; }
.choice-pill input { position: absolute; width: 1px; min-height: 0; height: 1px; padding: 0; opacity: 0; }
.choice-pill span {
  display: inline-flex; min-height: 43px; align-items: center; gap: .45rem; padding: .65rem 1rem; border: 1px solid #c6aaa9; border-radius: 99px;
  color: var(--muted); font: .67rem var(--sans); letter-spacing: .07em; transition: background .2s, border-color .2s, color .2s, transform .2s;
}
.choice-pill small { color: var(--mauve); font-size: .62rem; transition: color .2s; }
.choice-pill:hover span { transform: translateY(-1px); border-color: var(--raspberry); }
.choice-pill input:checked + span { border-color: var(--raspberry); background: var(--raspberry); color: white; }
.choice-pill input:checked + span small { color: var(--blush); }
.choice-pill input:focus-visible + span { outline: 2px solid var(--raspberry); outline-offset: 3px; }
.choice-pill input[aria-invalid="true"] + span { border-color: #a31f43; }
.arrival-custom { margin-top: .4rem; }
.field-error { display: block; min-height: 1.1rem; padding-top: .2rem; color: #8f1736; font: .75rem var(--sans); }
.button { min-height: 48px; border: 1px solid var(--raspberry); border-radius: 99px; cursor: pointer; font: .72rem var(--sans); letter-spacing: .13em; text-transform: uppercase; transition: background .2s, color .2s, transform .2s; }
.button--primary { padding: .8rem 1.65rem; background: var(--raspberry); color: white; }
.button--primary:hover { background: #871d42; transform: translateY(-1px); }
.rsvp-submit { display: flex; width: 100%; align-items: center; justify-content: center; gap: .7rem; margin-top: .25rem; }
.rsvp-submit span { font-size: 1rem; }
.rsvp-thanks { padding: 2rem 0; text-align: center; }
.rsvp-thanks__doodle { width: min(100%, 340px); height: auto; aspect-ratio: 16 / 9; margin: -1rem auto .5rem; object-fit: cover; object-position: center 22%; }
.rsvp-thanks .script { font-size: 3.5rem; }
.rsvp-thanks h3 { margin: .7rem 0 .35rem; font: 500 1.65rem var(--serif); }
.rsvp-thanks > p:not(.script) { margin: 0; color: var(--muted); font-size: 1.1rem; }
.rsvp-thanks .text-link { padding: .2rem; border: 0; background: none; cursor: pointer; }
.floral--rsvp-left { bottom: -5rem; left: -5rem; width: clamp(190px, 29vw, 360px); --flower-rotation: 20deg; }
.floral--rsvp-right { top: 1rem; right: -7rem; width: clamp(180px, 25vw, 330px); --flower-rotation: -25deg; --flower-flip: -1; }

.faq-section { background: #fcfbf1; }
.faq-section .section-heading { margin-bottom: 2rem; }
.hotels__panel { padding: 0 .15rem 1.4rem; }
.faq-item .hotels__intro { max-width: none; margin: -.1rem 0 1.1rem; }
.hotels__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; margin: 0; padding: 0; list-style: none; }
.hotel-card { display: flex; flex-direction: column; padding: 1.3rem 1.4rem; background: var(--ivory); }
.hotel-card .eyebrow { margin-bottom: .4rem; font-size: .62rem; }
.hotel-card h3 { margin: 0 0 .5rem; color: var(--ink); font: 500 1.35rem/1.15 var(--serif); }
.hotel-card__rate { color: var(--raspberry); font-size: 1.1rem; font-weight: 500; }
.hotel-card__rate span { color: var(--muted); font-size: .95rem; font-weight: 400; }
.hotel-card__fits { margin-top: .25rem; color: var(--muted); font-size: 1rem; line-height: 1.3; }
.hotel-card .text-link { margin-top: auto; padding-top: .8rem; }
.faq-item .hotels__note { max-width: none; margin: 1.1rem 0 0; color: var(--ink); font-size: .98rem; font-style: italic; line-height: 1.4; text-align: center; }
.floral--faq-left { bottom: -6rem; left: -5rem; width: 260px; --flower-rotation: 30deg; }
.floral--faq-right { top: -3rem; right: -6rem; width: 240px; --flower-rotation: -28deg; --flower-flip: -1; }
.faq-list { border-top: 1px solid #d9c8bd; }
.faq-item { border-bottom: 1px solid #d9c8bd; }
.faq-item summary { position: relative; padding: 1.15rem 2.8rem 1.15rem .15rem; cursor: pointer; list-style: none; font: 500 1.35rem var(--serif); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { position: absolute; top: 50%; right: .4rem; color: var(--raspberry); content: "+"; font: 1.4rem var(--sans); transform: translateY(-50%); transition: transform .2s; }
.faq-item[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq-item p { max-width: 690px; margin: -.1rem 2.8rem 1.3rem .15rem; color: var(--muted); font-size: 1.12rem; line-height: 1.45; }

.footer { position: relative; overflow: hidden; padding: 5rem 1rem 2rem; background: #342d2f; color: var(--ivory); text-align: center; }
.footer__doodle {
  position: relative; z-index: 1; display: grid; width: min(100%, 560px); aspect-ratio: 1920 / 1200; margin: -1.5rem auto .4rem;
  filter: invert(1) hue-rotate(180deg); opacity: .92;
}
/* Two Lottie players stacked: the finished drawing held still, and the twinkling sparkles on top. */
.footer__doodle-layer { grid-area: 1 / 1; }
.footer .script { color: var(--blush); font-size: 3.2rem; }
.footer .ampersand { padding: 0 .15em; color: var(--mauve); font-size: .62em; }
.footer__date { margin: 1rem 0; font: .75rem var(--sans); letter-spacing: .27em; }
.footer__date span { padding: 0 .5rem; color: var(--mauve); }
.footer__contact { color: var(--ivory); font: .65rem var(--sans); letter-spacing: .12em; text-decoration-color: var(--mauve); text-underline-offset: 4px; text-transform: uppercase; }
.footer__closing { margin: 2rem 0 0; color: #e1d4ce; font: italic 1rem var(--body); }
.floral--footer { right: -5rem; bottom: -5rem; width: 310px; opacity: .88; --flower-rotation: -30deg; }
.floral--footer-left { top: -4rem; left: -6rem; width: 260px; --flower-rotation: 155deg; --flower-flip: -1; }

.music-toggle {
  position: fixed; z-index: 40; right: 1.25rem; bottom: 1.25rem; display: grid; width: 52px; height: 52px; place-items: center;
  border: 1px solid var(--ivory); border-radius: 50%; background: var(--raspberry); color: white; cursor: pointer;
  box-shadow: 0 8px 22px rgb(46 42 43 / 28%); transition: background .2s, transform .2s, bottom .35s ease;
}
/* Sit above the hero's ticker while it is on screen (app.js toggles .is-raised). */
.music-toggle.is-raised { bottom: calc(58px + 1rem); }
.music-toggle:hover { background: #7f2543; transform: translateY(-2px); }
.music-toggle svg { width: 22px; height: 22px; fill: currentColor; }
.music-toggle__pause, .music-toggle.is-playing .music-toggle__play { display: none; }
.music-toggle.is-playing .music-toggle__pause { display: block; }
.music-toggle__hint {
  position: absolute; right: calc(100% + .7rem); padding: .55rem .9rem; border-radius: 99px; background: white; color: var(--raspberry);
  box-shadow: 0 6px 18px rgb(46 42 43 / 18%); font: .68rem var(--sans); letter-spacing: .08em; white-space: nowrap;
  opacity: 0; transform: translateX(6px); transition: opacity .3s, transform .3s; pointer-events: none;
}
.music-toggle.is-waiting .music-toggle__hint { opacity: 1; transform: none; }
.music-toggle.is-waiting::before,
.music-toggle.is-playing::before {
  position: absolute; inset: -1px; border: 1px solid var(--raspberry); border-radius: 50%; content: "";
  animation: music-pulse 2.2s ease-out infinite; pointer-events: none;
}
/* Photo viewer: no frame, just the photo at a fixed height over the dimmed page. The dialog covers the whole
   screen, so a click anywhere but the photo or a button lands on it and closes the viewer (see setupLightbox). */
.lightbox { width: 100vw; max-width: none; height: 100vh; height: 100dvh; max-height: none; margin: 0; padding: 0; overflow: hidden; border: 0; background: transparent; color: white; }
.lightbox[open] { display: grid; place-items: center; }
.lightbox::backdrop { background: rgb(23 19 20 / 72%); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.lightbox figure { display: grid; margin: 0; justify-items: center; gap: .9rem; pointer-events: none; }
/* Fixed height; a photo too wide for the screen is scaled down whole. drop-shadow only shades the photo itself. */
.lightbox figure img {
  width: auto; height: min(80vh, 820px, 115vw); height: min(80dvh, 820px, 115vw); max-width: 92vw; object-fit: contain;
  filter: drop-shadow(0 22px 40px rgb(0 0 0 / 50%)); pointer-events: auto;
}
.lightbox figcaption { color: #f4e7e3; font: .72rem var(--sans); letter-spacing: .18em; text-transform: uppercase; text-align: center; text-shadow: 0 1px 6px rgb(0 0 0 / 50%); }
.lightbox__close, .lightbox__arrow { position: absolute; border: 0; background: transparent; color: white; cursor: pointer; text-shadow: 0 2px 10px rgb(0 0 0 / 45%); }
.lightbox__close { top: .75rem; right: 1rem; width: 3rem; height: 3rem; font: 2.4rem/1 var(--sans); }
.lightbox__arrow { z-index: 1; top: 50%; display: grid; width: 2.6rem; height: 2.6rem; padding: 0 0 .2rem; place-items: center; border-radius: 50%; background: rgb(46 42 43 / 55%); font: 2rem/1 var(--serif); transform: translateY(-50%); }
.lightbox__arrow--prev { left: .7rem; }.lightbox__arrow--next { right: .7rem; }
/* The attire inspirations reuse the lightbox shell, with the photos side by side; the padding centers the first and last. */
.lightbox__arrow:disabled { opacity: 0; pointer-events: none; }
.inspirations { --photo-height: min(80dvh, 820px, 115vw); }
.inspirations__scroll {
  display: flex; width: 100%; gap: 1.1rem; padding-inline: calc(50vw - var(--photo-height) * .4);
  overflow-x: auto; overscroll-behavior: contain; scrollbar-width: none; outline: 0;
}
.inspirations__scroll::-webkit-scrollbar { display: none; }
.inspirations__scroll img { display: block; flex: none; width: auto; height: var(--photo-height); aspect-ratio: 4 / 5; }
.lightbox__close:hover, .lightbox__arrow:hover { color: var(--blush); }

/* Apple-style scroll scenes: app.js sets --p (0 → 1) on [data-scroll] elements, gallery items, the timeline
   and flowers as they move through the viewport. Every effect defaults to its finished state (--p: 1). */
.section-heading[data-scroll] h2 {
  opacity: clamp(0, calc(var(--p, 1) * 1.7 - .45), 1);
  transform: translateY(calc((1 - var(--p, 1)) * 80px)) scale(calc(.88 + var(--p, 1) * .12));
}
.section-heading[data-scroll] .ornament {
  opacity: clamp(0, calc(var(--p, 1) * 2 - .9), 1);
  transform: scale(calc(.55 + var(--p, 1) * .45));
}
.scroll-word { opacity: clamp(.16, calc((var(--p, 1) * (var(--n, 1) + 5) - var(--i, 0)) / 5), 1); transition: opacity .15s linear; }

.reveal { opacity: 0; transform: translateY(42px) scale(.98); transition: opacity .9s ease, transform 1.1s cubic-bezier(.16,1,.3,1); }
.reveal.is-visible { opacity: 1; transform: none; }
.timeline-row.reveal { transition-delay: calc(var(--reveal-index, 0) * 110ms); }
.detail-card.reveal, .attire-card.reveal { transition-delay: calc(var(--reveal-index, 0) * 75ms); }
[data-floral] { opacity: 0; transform-origin: center; transition: opacity .9s ease, transform 1s cubic-bezier(.2,.7,.2,1); }
[data-floral].is-visible { opacity: 1; transform: translateY(calc((.5 - var(--p, .5)) * 160px)) rotate(var(--flower-rotation, 0deg)) scaleX(var(--flower-flip, 1)) scale(1); }
.floral.is-visible { transition: opacity .9s ease, transform .5s cubic-bezier(.2,.7,.2,1); }
.floral.is-visible { animation: floral-drift 6s ease-in-out infinite alternate; }
.floral--extra.is-visible { animation-duration: 7.5s; animation-delay: -2s; }
.rsvp-couple.is-visible { animation: butterfly-sway 5s ease-in-out infinite alternate; }

@keyframes hero-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
@keyframes ticker-scroll { to { transform: translateX(-50%); } }
@keyframes music-pulse { from { opacity: .7; transform: scale(1); } to { opacity: 0; transform: scale(1.55); } }
@keyframes floral-drift { from { translate: 0 0; } to { translate: 0 -10px; } }
@keyframes butterfly-sway { 0% { transform: translate(0, 0) rotate(-3deg); } 100% { transform: translate(4px, -5px) rotate(4deg); } }

/* With room at the sides, the attire sketches stand either side of the cards as the section's backdrop. */
@media (min-width: 1280px) {
  .attire-grid { max-width: 760px; }
  .attire-card__scene { position: absolute; z-index: -1; bottom: -3.5rem; width: clamp(360px, 30vw, 520px); max-width: none; margin: 0; pointer-events: none; }
  .attire-card:first-child .attire-card__scene { right: calc(100% - 3rem); }
  .attire-card:last-child .attire-card__scene { left: calc(100% - 3rem); }
  .floral--attire, .floral--attire-top { display: none; }
}
@media (max-width: 1100px) {
  .floral { width: 200px; }
  .floral--extra { width: 175px; }
}
@media (max-width: 1050px) {
  .site-nav { gap: .8rem; }
  .site-nav a { font-size: .6rem; letter-spacing: .06em; }
  .site-nav .nav-rsvp { padding: .58rem .9rem; }
  .detail-card__front { --art-size: auto 62%; }
}
@media (max-width: 800px) {
  .hero { min-height: 100svh; }
  .hero__frame { width: calc(100% - 3rem); }
  .hero__photo { object-position: 30% center; }
  .hero__scrim { background: linear-gradient(0deg, rgb(29 24 25 / 64%) 0%, rgb(29 24 25 / 22%) 43%, rgb(29 24 25 / 12%) 100%); }
  .brand-mark { top: 1.45rem; }
  .brand-mark__logo { width: 3.3rem; }
  .menu-toggle {
    position: absolute; z-index: 5; top: 1.5rem; right: 0; display: grid; width: 45px; height: 45px;
    align-content: center; justify-items: center; gap: 6px; border: 1px solid rgb(255 255 255 / 65%);
    border-radius: 50%; background: transparent; cursor: pointer;
  }
  .menu-toggle span { width: 17px; height: 1px; background: white; transition: transform .2s; }
  .menu-toggle[aria-expanded="true"] span:first-child { transform: translateY(3.5px) rotate(45deg); }
  .menu-toggle[aria-expanded="true"] span:last-child { transform: translateY(-3.5px) rotate(-45deg); }
  .site-nav {
    position: absolute; z-index: 4; top: 5rem; right: 0; display: none; width: min(280px, 82vw);
    align-items: stretch; gap: 0; padding: .8rem 1.1rem 1.1rem; background: rgb(46 42 43 / 94%);
  }
  .site-nav.is-open { display: flex; flex-direction: column; }
  .site-nav a { padding: .72rem .2rem; font-size: .7rem; }
  .site-nav a:not(.nav-rsvp)::after { right: auto; width: 50px; }
  .site-nav .nav-rsvp { align-self: flex-start; margin-top: .55rem; padding: .6rem 1.2rem; }
  .hero__copy { top: auto; right: 0; bottom: 10%; left: 0; width: 100%; transform: none; }
  .hero:has(.ticker:not([hidden])) .hero__copy { bottom: calc(5% + 58px); }
  .hero__welcome { font-size: clamp(2.5rem, 8vw, 3.6rem); }
  .hero h1 { font-size: clamp(4.6rem, 12vw, 6.8rem); }
  .hero__date { margin-top: 1rem; font-size: 1.8rem; }
  .hero__discover { margin-top: 1.8rem; }
  .details-grid { gap: 1rem; }
  .detail-card__face { padding: 2rem 1.25rem; }
  .detail-card__note { min-height: 4.2rem; }
  .prosperity-copy { max-width: 640px; grid-template-columns: minmax(0, 1fr); text-align: center; }
  .timeline-list { display: block; }
  .timeline-row--column-end::before { display: block; }
  .gifts-layout { max-width: 560px; grid-template-columns: minmax(0, 1fr); row-gap: 1.2rem; }
  .gifts-layout .section-heading { margin-bottom: 0; }
  .gifts-copy p { font-size: 1.2rem; }
  .gifts-qr { width: min(330px, 88vw); border-width: 28px; }
  .attire-card { padding-inline: 1rem; }
  .swatch__chip { width: 44px; height: 44px; }
  .swatch__name { font-size: .54rem; letter-spacing: .06em; }
  .floral--extra { width: 170px; }
}
@media (max-width: 560px) {
  .hero { min-height: 100svh; }
  .hero__photo { object-position: 29% center; }
  .hero__scrim { background: linear-gradient(0deg, rgb(29 24 25 / 73%), rgb(29 24 25 / 22%) 52%, rgb(29 24 25 / 10%)); }
  .hero__copy { bottom: 9%; }
  .hero:has(.ticker:not([hidden])) .hero__copy { bottom: calc(4% + 50px); }
  .hero h1 { font-size: clamp(3.5rem, 13.5vw, 5.1rem); }
  .hero__welcome { font-size: 2.55rem; }
  .hero__date { font-size: 1.55rem; }
  .hero__discover { width: 2.15rem; height: 2.15rem; }
  .ticker__track { min-height: 50px; }
  .ticker__item { font-size: .74rem; }
  .ticker__diamond { width: 5px; height: 5px; margin: 0 1rem; }
  .section { padding: 4.5rem 1.15rem; }
  .section-heading { margin-bottom: 2.5rem; }
  .section-heading h2 { font-size: 2.45rem; }
  .section-heading__intro { font-size: 1.08rem; }
  .details-grid, .attire-grid { grid-template-columns: 1fr; }
  .detail-card__face { padding: 2rem 1.4rem; }
  .detail-card__note { min-height: 0; }
  .map-frame { height: 240px; }
  .detail-card__front { --art-size: 100% auto; min-height: 720px; }
  .detail-card__back .map-frame { min-height: 220px; }
  .timeline-list { --time: 62px; --gap: 4.4rem; --badge: 52px; }
  .timeline-row { padding-bottom: 1.7rem; }
  .timeline-row time { padding-top: .32rem; font-size: .7rem; letter-spacing: .06em; }
  .timeline-row h3 { font-size: 1.3rem; }
  .timeline-row p { font-size: .98rem; }
  .hotels__list { grid-template-columns: minmax(0, 1fr); }
  .party { --party-gap: 1.1rem; }
  /* Phones: one centered column, so names don't break across lines in two narrow halves. */
  .party-row { grid-template-columns: minmax(0, 1fr); row-gap: 1.6rem; }
  .party-row > :first-child, .party-row > :last-child { text-align: center; }
  .party-sponsors li { display: block; margin-bottom: .55rem; text-align: center; }
  .party-sponsors li > :first-child, .party-sponsors li > :last-child { display: block; text-align: center; }
  .entourage-section.section { padding-inline: .7rem; }
  .party h3 { font-size: 1.35rem; }
  .party-names, .party-sponsors, .party-flower-girls { font-size: .78rem; letter-spacing: .04em; }
  .party-sponsors li { margin-bottom: .3rem; line-height: 1.35; }
  .party-secondary { grid-template-columns: minmax(0, 1fr); row-gap: 1.3rem; }
  .party-secondary > :nth-child(2) { padding-top: 0; }
  .details-section .section-heading__intro { font-size: min(1.08rem, 3.4vw); white-space: nowrap; }
  .attire-card { padding: 1.8rem 1.2rem; }
  .attire-card h3 { margin-top: .4rem; }
  .attire-card > p:not(.eyebrow) { min-height: 0; }
  .floral--prosperity { right: -8rem; bottom: -10rem; width: 220px; }
  .gallery-track { gap: .75rem; }
  /* One height for every photo; wide ones are capped at 84vw and cropped to fit. */
  /* Every photo shares one height, low enough that a landscape photo still fits across the screen uncropped. */
  .gallery-item { height: 62vw; }
  .swatches { gap: .25rem; }
  .swatch__chip { width: 44px; height: 44px; }
  .swatch__name { font-size: .54rem; letter-spacing: .06em; }
  .rsvp-section { min-height: 0; padding: 5rem 1rem; }
  .rsvp-card { padding: 2.5rem 1.2rem 1.6rem; }
  .rsvp-card .section-heading { margin-bottom: 1.7rem; }
  .rsvp-card .section-heading h2 { font-size: 2.5rem; }
  .rsvp-couple { top: 1rem; right: .9rem; width: 52px; }
  .attendance-options { flex-direction: column; align-items: stretch; }
  .form-row { grid-template-columns: 1fr; }
  .floral--rsvp-left { left: -5rem; width: 210px; }
  .floral--rsvp-right { right: -6rem; width: 190px; }
  .floral--footer { right: -6rem; width: 215px; }
  .floral--extra { display: none; }
}
@media (max-width: 560px) {
  .music-toggle { right: 1rem; bottom: 1rem; width: 46px; height: 46px; }
  .music-toggle.is-raised { bottom: calc(50px + .8rem); }
  .letter__seal { width: 108px; height: 108px; }
}
/* Phones held sideways: too short to stack the doodle over the message, so they sit side by side. */
@media (max-height: 520px) {
  .letter__page { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.5rem; align-items: center; padding: 1rem 1.5rem; }
  .letter__doodle { width: 100%; }
  .letter__welcome { margin-top: 1rem; font-size: 1.4rem; }
  .letter__byline { margin-top: 1rem; }
  .letter__timer { margin-top: 1rem; }
  .letter__note { font-size: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  .party-group h3, .party-title > span, .party-row > .party-group, .party-names span, .party-sponsors li, .party-flower-girls li { clip-path: none; opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .reveal, [data-floral] { opacity: 1; transform: none; }
  /* These two keep moving even with Reduce Motion on (the couple's choice): the ticker carries information that
     would otherwise be cut off, and the venue cards keep their flip. */
  .ticker__track { animation-duration: 65s !important; animation-iteration-count: infinite !important; }
  .detail-card__inner { transition-duration: .85s !important; }
}
