/* ---------- Fonts ---------- */

@font-face {
  font-family: 'Editors Note';
  src: url('fonts/editors-note-thin.woff') format('woff');
  font-weight: 300;
  font-display: swap;
}
@font-face {
  font-family: 'Sloop Script';
  src: url('fonts/sloop-script.woff') format('woff');
  font-display: swap;
}
@font-face {
  font-family: 'Made Mirage';
  src: url('fonts/made-mirage.woff') format('woff');
  font-display: swap;
}
@font-face {
  font-family: 'Perfectly Nineties';
  src: url('fonts/perfectly-nineties-thin.woff') format('woff');
  font-weight: 300;
  font-display: swap;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('fonts/instrument-sans.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/inter.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'Work Sans';
  src: url('fonts/work-sans.woff2') format('woff2');
  font-display: swap;
}
@font-face {
  font-family: 'Raleway';
  src: url('fonts/raleway.woff2') format('woff2');
  font-display: swap;
}

/* ---------- Base ---------- */

:root {
  /* The sticky header is opaque and sits at z-index 10. Heroes are no longer
     sticky themselves (2026-08-02, see the Hero block), but they still pass
     UNDERNEATH the header on their way off screen, and the header still covers
     their top edge at rest. Any hero's top padding must therefore clear the
     header's full height (76px mobile, 97px desktop) or its first line is
     hidden. */
  --header-clear: 5.5rem;

  /* The design's own palette, matching /designs/04/ exactly. A build retints
     these from the client's brand; the KIT ships the published gallery values,
     because the gallery is what the client picked from. */
  --cream: #f5f3f0;
  --brown: #3a3531;
  --ink: #141414;
  --rose: #a0857e;

  /* Roles the five-page kit needs and the one-page gallery has no token for.
     They ALIAS gallery tokens so the kit renders exactly as published, and stay
     named so a build can move one without disturbing the others.
     --band is the ground of every full-bleed STATEMENT band plus the inquiry
     section and the footer; the gallery paints that ground with --brown
     (.addon-dark), which is what .pg-band--brown is named after.
     --blush and --gold are the accents sitting ON those dark grounds. They are
     NOT --rose: the gallery's rose is a mid-tone that measures 3.55:1 on
     --brown, which fails AA for the 0.8rem eyebrows these colour. This is the
     muted taupe the kit has always used for that job (6.25:1 on --brown,
     9.51:1 on --ink), now a token instead of a literal repeated 16 times. */
  --band: var(--brown);
  --blush: #cbb6ae;
  --gold: var(--blush);
  --serif: 'Editors Note', 'Times New Roman', serif;
  --script: 'Sloop Script', cursive;
  --body: 'Instrument Sans', system-ui, sans-serif;
  --label: 'Work Sans', system-ui, sans-serif;
  --inter: 'Inter', system-ui, sans-serif;
  /* Packages ledger neutrals (vars so colorway overrides can retint them) */
  --pk-hairline: #d9d5cf;
  --pk-ghost: #d3cec7;
  --pk-ghost-hover: #a29a90;
  --pk-hover: #efece7;
  --pk-muted: #4a453f;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* scroll-padding keeps anchor targets (#inquire, #faq, #services) clear of the
   sticky header, which is ~97px tall. Without it every CTA jump lands with the
   section heading tucked underneath the nav. */
html { scroll-behavior: smooth; overflow-x: clip; scroll-padding-top: 82px; }

body {
  overflow-x: clip;
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink);
  background: #fff;
}

img { max-width: 100%; height: auto; display: block; }

.script { font-family: var(--script); text-transform: none; font-weight: 400; }
.display, .display-light { font-family: var(--serif); font-weight: 300; }

.eyebrow {
  font-family: var(--label);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Buttons & links ---------- */

.btn {
  display: inline-block;
  font-family: var(--label);
  font-size: 0.6875rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 1em 2.9em;
  border: 1px solid currentColor;
  background: none;
  color: inherit;
  cursor: pointer;
  transition: background-color 0.3s, color 0.3s;
}
.btn-outline-light { color: #fff; }
.btn-outline-light:hover { background: #fff; color: var(--ink); }
.btn-outline-dark { color: var(--ink); }
.btn-outline-dark:hover { background: var(--ink); color: #fff; }
.btn-solid { background: var(--brown); color: var(--cream); border-color: var(--brown); }
.btn-solid:hover { background: var(--ink); border-color: var(--ink); }

/* Prose links (phone numbers, cross-links inside copy and FAQ answers) inherit
   the palette instead of falling back to browser blue/purple. Buttons and
   .text-link keep their own styling. */
.inquire-note a,
.footer-base a:not([aria-label]),
.faq p a,
.pg-note a,
.svc-hero-line a,
.ss-hero-note a,
.pg-hero-note a,
.svc-addons-note a,
.intro-copy p a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  transition: text-decoration-color 0.25s;
}
.inquire-note a:hover,
.footer-base a:not([aria-label]):hover,
.faq p a:hover,
.pg-note a:hover,
.svc-hero-line a:hover,
.ss-hero-note a:hover,
.pg-hero-note a:hover,
.intro-copy p a:hover { text-decoration-color: currentColor; }

.text-link {
  font-family: var(--label);
  font-size: 0.875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.text-link:hover { border-bottom-color: currentColor; }

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: #fff;
  padding: 0.65rem clamp(1rem, 4vw, 2.5rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  flex-wrap: wrap;
}
.site-logo { flex: 0 0 auto; line-height: 0; }
.site-logo img { width: clamp(120px, 10vw, 144px); height: auto; }
.site-header nav {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 0.4rem 2.2rem;
}
.site-header a {
  font-family: var(--label);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  opacity: 0.85;
}
.site-header a:hover { opacity: 1; }

/* ---------- Hero ---------- */

/* THE HOME HERO PINS TO THE VIEWPORT AND EVERY FOLLOWING SECTION SCROLLS OVER
   THE TOP OF IT. This rule is the second half of that: it lifts every sibling
   onto z-index 1 so each one covers the hero as it arrives. The hero itself is
   `position: sticky; z-index: 0` below.

   History, because this has been decided twice in opposite directions. The pin
   is the ORIGINAL behaviour. The owner rejected it on 2026-08-02 ("I don't like
   that when I scroll the next section goes on top of it") and REINSTATED it on
   2026-09-07 on Tupelo, referring to Wonderstruck's site: "it should stay fixed
   the whole time". The weddings (.oc-hero) and Sullivan (.loc-hero) heroes do
   NOT pin: occasion.css and location.css set them back to position: relative,
   because on an interior page the words scroll (Tupelo, 2026-09-08). Services
   and the two service pages use their own hero classes and never had the pin. */
main > :not(.hero) { position: relative; z-index: 1; }

.hero {
  position: sticky;
  top: 0;
  z-index: 0;
  /* min-height, not height: a fixed viewport height has no give, so a hero whose
     copy runs longer than the kit's (this build's H1s wrap to three lines and the
     ledes run six) centres its overflow and spills UPWARD, under the opaque sticky
     header and into the ticker. Growing instead of spilling keeps every line
     readable; heroes whose content fits are unaffected at exactly 100svh. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 1.2rem;
  padding: var(--header-clear) 1.5rem 5rem;
  color: #f1f0ee;
  background:
    linear-gradient(rgba(0, 0, 0, 0.52), rgba(0, 0, 0, 0.52)),
    url("images/ms-props-group.jpg") center 42% / cover no-repeat #000;
}

/* The photograph holds still against the viewport while the hero scrolls over
   it. Only the IMAGE layer is fixed; the dimming gradient stays on scroll so it
   keeps sizing to the hero box rather than the viewport.

   The +65px is a correction, not a nudge. A fixed layer positions against the
   VIEWPORT, but the hero box starts one sticky-header height further down, so
   switching to fixed lifts the crop by exactly that much. The header is fluid
   (61px at 1024, 63px at 1280, 69px from 1440 up), so 65px is the middle of
   that range and the worst case error is 4px, inside the header's own opaque
   band either way.

   Desktop pointers only. iOS Safari sizes a fixed background to the viewport
   and then fails to pin it, which zooms the crop and cuts faces out of it. */
@media (hover: hover) and (pointer: fine) {
  .hero {
    background-attachment: scroll, fixed;
    background-position: 0% 0%, center calc(42% + 65px);
  }
}
.hero-logo {
  width: clamp(180px, 24vw, 300px);
  height: auto;
  margin-bottom: 0.6rem;
  opacity: 0.96;
}
.hero h1 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(2rem, 5.5vw, 3.4rem);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.05;
}
.hero-script {
  font-size: clamp(2.4rem, 5vw, 3.8rem);
  line-height: 1;
  color: #fff;
}
.hero .btn { margin-top: 1.6rem; }

/* ---------- Scattered photos scrolling over the pinned hero ----------

   HOME PAGE ONLY. This effect needs the hero to hold still while the photos
   travel up over it, so it depends entirely on the hero being sticky.

   Do NOT wrap the hero in another element. Sticky is bounded by its containing
   block, so a wrapper is a CAP: the kit's old .hero-stack wrapper (hero +
   scatter, ~1000px on a phone) pinned the hero for a fraction of a screen,
   let the scatter photos and their white wash ride over the headline and the
   button while it was still held, and then dropped it under the opaque sticky
   header. The hero is a direct child of <main>, <main> is the containing
   block, and the pin lasts the whole page (Tupelo removed the same wrapper on
   2026-09-08). .scatter takes its position/z-index from `main > :not(.hero)`
   like every other section; it needs them because its photos are absolutely
   positioned and its ::before white wash would otherwise escape. */


/* The original keeps a fixed 1200px canvas centered at wider windows and
   scales it down below 1200; max-width + percentages reproduce both. */
.scatter {
  max-width: 1200px;
  margin-inline: auto;
  aspect-ratio: 1200 / 1146;
  pointer-events: none;
}
.scatter::before {
  content: '';
  position: absolute;
  left: calc(50% - 50vw);
  right: calc(50% - 50vw);
  top: -30%;
  height: 130%;
  background: linear-gradient(to top, #fff 0%, rgba(255, 255, 255, 0) 100%);
}
.scatter img { position: absolute; object-fit: cover; }
.sc-1 { left: 1.1%;   top: 1.75%; width: 16.3%; aspect-ratio: 196 / 229; }
.sc-2 { left: 85.7%;  top: 10.2%; width: 18.6%; aspect-ratio: 223 / 305; }
.sc-3 { left: -23.1%; top: 30.4%; width: 27.7%; aspect-ratio: 332 / 264; }
.sc-4 { left: 93.1%;  top: 41.3%; width: 25.8%; aspect-ratio: 309 / 352; }
.sc-5 { left: 8.25%;  top: 58.1%; width: 15.3%; aspect-ratio: 184 / 206; object-position: 50% 0%; } /* p06 print strip: top-anchor shows a whole frame */

/* ---------- Intro / About ---------- */

.intro {
  display: grid;
  grid-template-columns: 1fr minmax(auto, 560px) 1fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  padding: clamp(4rem, 9vw, 7rem) clamp(1.25rem, 4vw, 3rem);
  background: #fff;
}
.intro-copy { text-align: center; }
.intro-copy .eyebrow { margin-bottom: 1.4rem; font-family: var(--body); letter-spacing: normal; font-size: 0.875rem; }
.intro-copy h2 {
  font-size: clamp(2rem, 4.5vw, 3.3rem);
  line-height: 1.1;
  margin-bottom: 2.2rem;
}
.intro-copy h2 .script {
  display: block;
  font-size: clamp(2.4rem, 5vw, 4rem);
  line-height: 1.35;
}
.intro-copy p:not(.eyebrow) { margin-bottom: 1.4rem; }
.intro-copy .text-link { display: inline-block; margin-top: 1rem; }
.intro-side { display: grid; gap: clamp(2rem, 5vw, 5rem); }
.intro-left { justify-items: start; }
.intro-right { justify-items: end; }
.intro-side img { width: clamp(120px, 15vw, 210px); object-fit: cover; }
.intro-left img:first-child { filter: grayscale(1); aspect-ratio: 179 / 257; }
.intro-left img:last-child { aspect-ratio: 152 / 150; width: clamp(105px, 12.7vw, 180px); object-position: 80% 80%; }
.intro-right img:first-child { aspect-ratio: 185 / 150; width: clamp(125px, 15.4vw, 215px); object-position: 60% 60%; }
.intro-right img:last-child { filter: grayscale(1); aspect-ratio: 177 / 215; object-position: 30% 30%; }
.intro-left img:last-child { margin-left: 20%; }
.intro-right img:first-child { margin-right: 15%; }
.intro-side img { transform: translateY(var(--drift, 0)); }

/* ---------- Packages (the Ledger) ---------- */
/* Hairline-ruled rows with ghost serif numerals. Numbering is CSS counters,
   so reconciled rows (added or removed by the platform) renumber themselves.
   The section flexes its rows to fill one viewport under the sticky header. */

.packages {
  background: var(--cream);
  padding: clamp(1.8rem, 3vw, 2.6rem) clamp(2rem, 6vw, 6.5rem);
  counter-reset: pkg;
  min-height: calc(100vh - 80px);
  display: flex;
  flex-direction: column;
}
.pk-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 3rem;
  padding-bottom: 1.4rem;
}
.pk-head h2 {
  font-family: var(--label);
  font-weight: 400;
  font-size: 0.85rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
}
.pk-head p { max-width: 38ch; font-size: 0.92rem; color: var(--pk-muted); }
.package {
  counter-increment: pkg;
  flex: 1;
  display: grid;
  grid-template-columns: 150px 1fr auto;
  align-items: center;
  gap: 1.5rem 2.6rem;
  padding: 1.4rem 1.2rem;
  border-top: 1px solid var(--pk-hairline);
  transition: background-color 0.45s ease;
}
.package:hover { background: var(--pk-hover); }
.pk-num::before {
  content: counter(pkg, decimal-leading-zero);
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(4.2rem, 6.5vw, 6rem);
  line-height: 0.8;
  color: var(--pk-ghost);
  transition: color 0.45s ease;
}
.package:hover .pk-num::before { color: var(--pk-ghost-hover); }
.pk-copy h3 { font-size: clamp(1.7rem, 2.4vw, 2.2rem); line-height: 1.1; }
.pk-copy > p:not(.pk-price) { margin-top: 0.5rem; max-width: 64ch; font-size: 0.9rem; color: var(--pk-muted); }
.pk-price {
  margin-top: 0.6rem;
  font-family: var(--label);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brown);
}
.pk-price .price { color: var(--ink); }
.pk-cta {
  font-family: var(--label);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
  white-space: nowrap;
}
.pk-cta i { display: block; width: 44px; height: 1px; background: var(--ink); transition: width 0.4s ease; }
.package:hover .pk-cta i { width: 78px; }
.pk-foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 3rem;
  border-top: 1px solid var(--pk-hairline);
  padding: 1.5rem 1.2rem 0;
}
.pk-foot p {
  font-family: var(--label);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pk-muted);
  max-width: 60ch;
  line-height: 1.9;
}

/* ---------- Occasions ---------- */
/* Replaced the home package ledger 2026-08-01: three occasion panels
   (weddings / corporate / celebrations) that funnel to packages.html.
   Reuses the ledger's head/foot/CTA patterns (.pk-head, .pk-foot, .pk-cta)
   and its ghost-numeral CSS counters so the section stays in the same
   design language. Panel photos run grayscale like the intro collage. */

.occasions {
  background: var(--band);
  color: #fff;
  padding: clamp(1.8rem, 3vw, 2.6rem) clamp(2rem, 6vw, 6.5rem);
  counter-reset: occ;
  /* Fits one viewport like the ledger it replaced: the type stack is fixed
     and the photos flex to absorb whatever height is left. The max stops the
     photo crops going extreme-portrait on very tall windows; the min is the
     floor where the type plus the photos' min-height still fit. */
  height: calc(100vh - 80px);
  min-height: 760px;
  max-height: 1020px;
  display: flex;
  flex-direction: column;
}
.occ-grid {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  border-top: 1px solid var(--pk-hairline);
  padding: clamp(1.5rem, 2.5vw, 2.2rem) 0;
}
.occ {
  counter-increment: occ;
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
/* Hairline dividers live in the middle of the grid gap so no panel loses
   width to them and the three columns stay identical. */
.occ + .occ::before {
  content: '';
  position: absolute;
  left: calc(clamp(1.5rem, 3vw, 3rem) / -2);
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--pk-hairline);
}
/* The photo is the flexible element: its height comes from the viewport so
   the section as a whole fits one window. Derived from the viewport, NOT
   from each panel's leftover space (flex: 1), because the wedding panel's
   copy runs a line longer and per-panel leftovers gave it a shorter photo,
   staggering the numerals under the three images. Viewport-derived heights
   are identical across panels; the copy-length slack lands in the gap above
   each CTA instead (margin-top: auto). */
.occ-media { height: clamp(160px, calc(100vh - 634px), 470px); overflow: hidden; }
.occ-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1);
}
.occ-num { display: block; margin-top: 1.1rem; }
.occ-num::before {
  content: counter(occ, decimal-leading-zero);
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(2.6rem, 3.5vw, 3.6rem);
  line-height: 1;
  color: var(--pk-ghost);
  transition: color 0.45s ease;
}
.occ:hover .occ-num::before { color: var(--pk-ghost-hover); }
.occ h3 { font-size: clamp(1.7rem, 2.4vw, 2.2rem); line-height: 1.1; margin-top: 0.4rem; }
.occ h3 .script { display: block; font-size: clamp(1.9rem, 2.6vw, 2.5rem); line-height: 1.3; }
.occ > p { margin-top: 0.7rem; font-size: 0.9rem; color: var(--pk-muted); }
.occ .pk-cta { margin-top: auto; padding-top: 1.4rem; }
.occ:hover .pk-cta i { width: 78px; }

/* Occasions on the PLUM ground with BLUSH accents (owner request
   2026-08-02, settled after a navy-and-gold pass). The ledger
   neutrals this section inherits (--pk-muted body copy, --pk-hairline rules,
   --pk-ghost numerals) are all tuned for cream and go invisible on plum, so
   each one is restated here rather than retinted globally: those same vars
   still carry the packages ledger, which stays light. The numerals and the
   CTA rules are BLUSH by request and brighten to white on hover, which is the
   same gesture the original ghost-grey had. Photos keep their grayscale
   treatment. */
.occasions .pk-head p { color: rgba(255, 255, 255, 0.82); }
.occasions .occ-grid { border-top-color: rgba(255, 255, 255, 0.3); }
.occasions .occ + .occ::before { background: rgba(255, 255, 255, 0.3); }
.occasions .occ-num::before { color: var(--blush); }
.occasions .occ:hover .occ-num::before { color: #fff; }
.occasions .occ > p { color: rgba(255, 255, 255, 0.85); }
.occasions .pk-cta { color: #fff; }
.occasions .pk-cta i { background: var(--blush); }

/* ---------- Add-Ons ---------- */

.addons {
  background:
    linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)),
    url("images/ms-bride-party.jpg") center / cover no-repeat var(--brown);
  padding: clamp(3.5rem, 8vw, 6rem) clamp(1.25rem, 5vw, 4rem);
}
.addons h2 {
  line-height: 1.15;
  text-align: center;
  color: #fff;
  font-weight: 300;
  margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
}
.addons h2 .display-light {
  font-size: clamp(2.8rem, 6vw, 4.4rem);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.addons h2 .script { font-size: clamp(2.6rem, 5.5vw, 4rem); }
.addon-step2 {
  display: grid;
  grid-template-columns: minmax(300px, 480px);
  justify-content: center;
  margin-top: clamp(2rem, 5vw, 3.5rem);
}
.addon-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 480px));
  gap: clamp(2rem, 5vw, 3.5rem);
  justify-content: center;
  align-items: start;
}

/* Desktop: the Audio Guest Book layer pins to the screen while the
   Key Chain Station scrolls up into the empty right column beside it */
@media (min-width: 801px) {
  /* Once the second card has scrolled into place (one viewport of travel),
     the whole section freezes and the FAQ scrolls over it, like the original.
     (main > prefix outranks the main > :not(.hero) positioning rule) */
  main > .addons {
    background: none;
    padding: 0;
    position: sticky;
    top: -100vh;
    top: -100svh;
    /* The pinned card's top offset: pin padding + heading + heading margin.
       Named because TWO things depend on it and must never drift apart: where
       the second card lands, and how tall a card may be on a short screen. */
    --addon-top: calc(11svh + 1.15 * clamp(2.8rem, 6vw, 4.4rem) + 1rem + 15px);
  }
  .addons-pin {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding: 11svh clamp(1.25rem, 5vw, 4rem) 2rem;
    background:
      linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)),
      url("images/ms-bride-party.jpg") center / cover no-repeat var(--brown);
  }
  .addon-cards { grid-template-columns: repeat(2, minmax(300px, 480px)); }
  .addons-pin h2 { margin-bottom: 1rem; }
  .addon-card { height: 645px; }
  .addon-inner { height: 100%; }
  .addon-step2 {
    position: relative;
    z-index: 1;
    height: 100vh;
    height: 100svh;
    margin-top: 0;
    grid-template-columns: repeat(2, minmax(300px, 480px));
    gap: clamp(2rem, 5vw, 3.5rem);
    align-items: start;
    padding: 2rem clamp(1.25rem, 5vw, 4rem);
    /* land level with the pinned card: --addon-top IS that offset */
    padding-top: var(--addon-top);
  }
  .addon-step2 .addon-card { grid-column: 2; }
  /* This pane is a full-width 2-column grid stacked over the pinned pane, and
     its LEFT column is empty and transparent. Without this it still swallows
     every click on card 01 underneath, including its Add It On button
     (elementFromPoint returned DIV.addon-step2 at every scroll position).
     Let the empty area pass clicks through; the card itself takes them back.
     The site editor honours this since 2026-10-05: it used to put the pane
     back into hit testing (its click-through restore read any opacity-1
     element as decorative text), so card 01 could not be edited while card
     02 was on screen; a box that paints nothing now stays click-through
     (markClickThrough in src/site_editor_client.js). */
  .addon-step2 { pointer-events: none; }
  .addon-step2 > * { pointer-events: auto; }
}
/* Short laptop windows (kit README "KNOWN KIT DEFECT", fix ported from the
   Smooches build): the 645px card ran past the fold under 881px tall and its
   button was never both visible and on top. The card shrinks to what the pane
   has left and the photo absorbs it (object-fit: cover crops, never distorts);
   min-height: 0 is what lets the flex item shrink at all. min() leaves 881px
   and taller untouched. */
@media (min-width: 801px) and (max-height: 880px) {
  .addon-card { height: min(645px, calc(100svh - var(--addon-top) - 4.25rem)); }
  .addon-card img { min-height: 0; flex: 0 1 auto; max-height: 26svh; margin-bottom: 1.1rem; }
  .addon-inner { padding: 1.15rem 1.5rem 1.4rem; }
  .addon-card { padding: 0.9rem; }
}
.addon-card { padding: 1.25rem; }
.addon-light { background: #fff; color: var(--ink); }
.addon-dark { background: var(--brown); color: #fff; }
.addon-inner {
  border: 1px solid currentColor;
  padding: 1.5rem 1.75rem 1.75rem;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  position: relative;
}
.addon-number {
  position: absolute;
  top: 0.5rem;
  right: 1rem;
  font-family: var(--serif);
  font-size: clamp(3.4rem, 6vw, 5rem);
  line-height: 1;
}
.addon-light .addon-number { color: rgba(28, 28, 28, 0.1); }
.addon-dark .addon-number { color: rgba(255, 255, 255, 0.3); }
.addon-card h3 {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  padding-bottom: 0.75rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid currentColor;
  align-self: stretch;
}
.addon-desc {
  font-family: 'Perfectly Nineties', var(--serif);
  font-size: 1.25rem;
  line-height: 1.15;
  max-width: 22em;
  margin-bottom: 1rem;
}
.addon-card img { width: min(100%, 288px); aspect-ratio: 288 / 279; object-fit: cover; margin-top: auto; margin-bottom: 1.6rem; }
.addon-light img { object-position: 50% 60%; }
.addon-dark img { object-position: 20% 20%; }
.addon-foot {
  align-self: stretch;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
.addon-foot .btn { white-space: nowrap; padding: 0.9em clamp(1.2em, 3vw, 2.8em); }
.addon-price {
  font-family: var(--inter);
  font-size: 0.875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- FAQ ---------- */

.faq {
  padding: clamp(3.5rem, 8vw, 6rem) clamp(1.25rem, 4vw, 2rem) clamp(4rem, 9vw, 7rem);
  background: #fff;
}
.faq > h2,
.faq > .eyebrow,
.faq details {
  max-width: 1140px;
  margin-inline: auto;
}
.faq > h2 {
  text-align: center;
  font-size: clamp(2.2rem, 4.5vw, 3.2rem);
  line-height: 1;
}
.faq > h2 .script {
  display: block;
  font-size: clamp(2.2rem, 4.5vw, 3.4rem);
  line-height: 0.8;
}
.faq > .eyebrow { text-align: center; margin: 1.8rem auto 3rem; }
.faq details { border-bottom: 1px solid var(--ink); }
.faq summary {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.3rem, 2.8vw, 2.1875rem);
  line-height: 1.2;
  padding: 1.1em 2.2em 1.1em 0;
  cursor: pointer;
  list-style: none;
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+';
  position: absolute;
  right: 0.2em;
  top: 50%;
  transform: translateY(-50%);
  font-weight: 200;
  font-size: 1.2em;
}
.faq details[open] summary::after { content: '\2212'; }
.faq details p { padding: 0 0 1.8em; max-width: 75ch; font-family: 'Raleway', var(--body); font-size: 1.0625rem; line-height: 1.8; }

/* ---------- Testimonials ---------- */

.testimonials {
  background: var(--ink);
  color: #fff;
  padding: clamp(4rem, 9vw, 7rem) clamp(1.25rem, 5vw, 4rem);
  /* clips the fixed background layer to this section (works on iOS,
     unlike background-attachment: fixed) */
  clip-path: inset(0);
}
.testimonials::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(rgba(20, 20, 20, 0.72), rgba(20, 20, 20, 0.72)),
    url('images/ms-props-group.jpg') center 30% / cover no-repeat var(--ink);
}
.testimonials > h2 { font-weight: 300; margin-bottom: clamp(2.5rem, 6vw, 4rem); }
.testimonials .display-light {
  font-size: clamp(3rem, 8vw, 6rem);
  text-transform: uppercase;
  letter-spacing: -0.025em;
  line-height: 1;
}
.testimonials .display-light { display: block; }
.testimonials .script {
  display: block;
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  margin: -0.15em 0 0 4.7em;
}
.quotes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: clamp(2rem, 5vw, 4rem);
}
.quotes blockquote {
  font-size: clamp(1.05rem, 1.8vw, 1.25rem);
  line-height: 1.6;
  margin-bottom: 1.6rem;
}
.quotes figcaption {
  font-family: var(--body);
  font-size: 1.125rem;
  letter-spacing: normal;
  text-transform: uppercase;
}

/* ---------- Inquire ---------- */

.inquire {
  background: var(--band);
  color: #fff;
  padding: clamp(4rem, 9vw, 7rem) clamp(1.25rem, 4vw, 2rem);
  text-align: center;
}
/* On the wine ground: blush for the label, white for the prose link, and a
   white submit (the navy .btn-solid all but disappears on plum). The fields
   keep their near-white faces and ink text, so nothing typed is ever hard to
   read; only their keylines lighten. */
.inquire .eyebrow { color: var(--blush); }
.inquire-note a { color: #fff; }
.inquire .inquiry-form input,
.inquire .inquiry-form select,
.inquire .inquiry-form textarea { border-color: rgba(255, 255, 255, 0.55); }
.inquire .inquiry-form select {
  background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%),
                    linear-gradient(135deg, var(--ink) 50%, transparent 50%);
}
.inquire .inquiry-form .btn-solid {
  background: #fff;
  color: var(--band);
  border-color: #fff;
}
.inquire .inquiry-form .btn-solid:hover {
  background: var(--blush);
  color: var(--band);
  border-color: var(--blush);
}
/* the add-on legend ships in --pk-muted (a navy grey): 1.14:1 on the wine
   ground, i.e. invisible. Caught by the contrast probe, not by eye. */
.inquire .addon-picks legend { color: var(--blush); }
.inquire h2 { font-weight: 400; margin: 1.2rem 0 1.6rem; }
.inquire-script {
  display: block;
  font-size: clamp(3rem, 8vw, 5.6rem);
  line-height: 1;
}
.inquire-together {
  display: block;
  font-size: clamp(2.6rem, 7vw, 5.4rem);
  text-transform: uppercase;
  line-height: 1;
  margin-top: -0.35em;
}
.inquire-note { max-width: 44ch; margin: 0 auto 3.5rem; font-family: 'Raleway', var(--body); line-height: 1.8; }

.inquiry-form {
  max-width: 620px;
  margin: 0 auto;
  display: grid;
  gap: 1.1rem;
  text-align: left;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
}
/* A field left alone on the row's last line spans the full line (owner rule
   2026-08-12: no blank half-cells on a customer form). Rows hold hidden-label
   + control pairs, so with an odd number of fields the final control is child
   4n+2; an even count never matches and unlabeled shapes just keep today's
   layout. */
/* ---------- Event date field (2026-08-21) ----------
   The date box used to ship as type="text" that flipped itself to type="date"
   on focus, purely so "Event Date" could show as placeholder text (a date input
   ignores placeholder). Safari could not be trusted through that swap: its
   picker is a panel that stays open after a day is clicked, and the flip's own
   onblur then tore the field down underneath it. So the field is a plain date
   box now, and the wording moved to a real <label>.
   The label+input are wrapped into ONE grid child on purpose: an un-wrapped
   visible label takes a cell of its own and throws the two columns out (proven
   by measurement before this shipped). Bottom-aligning only the row that holds
   the wrapper puts the date box back on the same underline as the field beside
   it. Both are scoped so no other row on any page moves.
   The label is a real <label for>, not decoration: the portal's contact-form
   editor rewords labels, so a client rewording this question keeps the visible
   wording in step (src/site_forms.js). */
.fd-wrap { display: block; }
.form-row:has(.fd-wrap) { align-items: end; }
.fd-label {
  display: block;
  font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
  opacity: 0.65; margin-bottom: 0.35rem;
}
/* appearance:none: iOS Safari otherwise renders a native date control that
   blows out past the form's width, and an empty one can collapse to no height. */
.inquiry-form input[type="date"] {
  -webkit-appearance: none; appearance: none;
  min-width: 0; max-width: 100%; text-align: left;
}
.inquiry-form input[type="date"]::-webkit-date-and-time-value {
  text-align: left; margin: 0; min-width: 0;
}
.inquiry-form input[type="date"]::-webkit-calendar-picker-indicator {
  margin-left: auto; opacity: 0.5; cursor: pointer;
}

.form-row > :nth-child(4n + 2):last-child {
  grid-column: 1 / -1;
}
.inquiry-form input,
.inquiry-form select,
.inquiry-form textarea {
  width: 100%;
  font-family: var(--body);
  /* 16px floor: anything smaller makes iOS Safari zoom on focus. */
  font-size: 1rem;
  color: var(--ink);
  background: #fdfdfc;
  border: 1px solid var(--brown);
  padding: 0.85em 1em;
  border-radius: 0;
}
.inquiry-form ::placeholder { color: #8b8680; opacity: 1; }
.inquiry-form textarea { resize: vertical; }
.inquiry-form .btn-solid { justify-self: center; margin-top: 1.4rem; }

/* Native select needs its own arrow once appearance is normalised. */
.inquiry-form select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--brown) 50%),
                    linear-gradient(135deg, var(--brown) 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 2.6em;
}
.inquiry-form select:invalid, .inquiry-form select option[value=""] { color: #8b8680; }

/* Add-on checkbox grid */
.addon-picks {
  border: 1px solid var(--pk-hairline);
  padding: 1.1rem 1.2rem 1.3rem;
  text-align: left;
}
.addon-picks legend {
  font-family: var(--label);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pk-muted);
  padding: 0 0.5em;
}
.addon-picks label {
  display: flex;
  align-items: flex-start;
  gap: 0.6em;
  font-family: var(--body);
  font-size: 0.95rem;
  line-height: 1.45;
  margin-top: 0.6rem;
  cursor: pointer;
}
.addon-picks input[type="checkbox"] {
  width: 1.05em;
  height: 1.05em;
  flex: 0 0 auto;
  margin-top: 0.18em;
  accent-color: var(--rose);
}
@media (min-width: 620px) {
  .addon-picks { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.4rem; }
  .addon-picks legend { grid-column: 1 / -1; }
}

/* NOTE: the add-ons section deliberately has no "see the rest" link. There is
   no room for one: on desktop the pane is exactly one viewport tall and the
   FAQ scrolls over its bottom ~130px, so anything placed there is visible for
   about 127px of scrolling and reads as missing. Nav "Packages" is the route
   to the full menu. Do not re-add a button here without solving that first. */

/* ---------- Gallery strip ---------- */

/* Now footer chrome (outside <main>), so it no longer inherits
   `main > :not(.hero)`'s stacking; restore it verbatim so it keeps covering
   the hero background layer exactly as it did inside <main>. */
.gallery { position: relative; z-index: 1; }
.gallery ul {
  list-style: none;
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* the strip sits directly on the footer, so its ground and its seams follow
     --band or a navy line shows between every photo */
  background: var(--band);
}
.gallery li { flex: 0 0 auto; scroll-snap-align: start; }
.gallery img {
  height: clamp(220px, 36vw, 300px);
  width: auto;
  border-right: 1px solid var(--band);
}

/* ---------- Footer ---------- */

.site-footer {
  position: relative;
  z-index: 1;
  background: var(--band);
  color: #fff;
  padding: clamp(2.5rem, 6vw, 4rem) clamp(1.5rem, 4vw, 3rem) 1.5rem;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem;
}
.site-footer nav { display: flex; gap: clamp(2.5rem, 8vw, 6rem); }
.site-footer nav ul { list-style: none; }
.site-footer nav a {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.4rem, 2.5vw, 1.75rem);
  line-height: 1.65;
  color: inherit;
  text-decoration: none;
  opacity: 0.95;
}
.site-footer nav a:hover { opacity: 1; text-decoration: underline; }
.back-to-top {
  font-family: var(--label);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: inherit;
  text-decoration: none;
  align-self: start;
}
.back-to-top:hover { text-decoration: underline; }
.footer-base {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 1rem;
  margin-top: 2rem;
}
/* The NAP line absorbs the free space so the social icons stay grouped at the
   right. Without this, space-between distributes every child evenly: the kit
   demo ships ONE icon so it looks correct, but a client with two or three
   (ShamCam has Instagram, Facebook and TikTok) gets them strung out across the
   whole footer. Auto margin instead of a wrapper element, so the markup keeps
   the kit's shape and any icon count lays out correctly. */
.footer-base p { margin-right: auto; }
.footer-base a[aria-label] + a[aria-label] { margin-left: 0.35rem; }
.footer-base p {
  font-family: var(--label);
  font-size: 0.5625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.55;
}
.footer-base a { color: inherit; opacity: 0.8; }
.footer-base a:hover { opacity: 1; }

/* ---------- Small screens ---------- */

@media (max-width: 800px) {
  /* Intro collage on mobile: couple left, bouquet right (staggered),
     other two photos hidden, images above the copy - like the original */
  .intro { grid-template-columns: 1fr 1fr; }
  .intro-left { order: 1; grid-column: 1; }
  .intro-right { order: 2; grid-column: 2; }
  .intro-copy { order: 3; grid-column: 1 / -1; }
  .intro-side img { margin: 0 !important; }
  .intro-left img:first-child { width: 36.5vw; }
  .intro-left img:last-child { display: none; }
  .intro-right img:first-child { display: none; }
  .intro-right img:last-child { width: 26vw; margin-top: 19vw !important; margin-right: 6vw !important; }

  .packages { min-height: 0; }
  .package { grid-template-columns: 1fr; gap: 0.6rem; padding: 1.6rem 0.4rem; }
  .pk-num::before { font-size: 14vw; }
  .pk-head, .pk-foot { flex-direction: column; align-items: flex-start; gap: 1rem; }

  .occasions { height: auto; min-height: 0; max-height: none; }
  .occ-grid { grid-template-columns: 1fr; gap: 0; padding: 0; }
  .occ { padding: 1.6rem 0.4rem; }
  .occ + .occ::before { left: 0; right: 0; top: 0; bottom: auto; width: auto; height: 1px; }
  .occ-media { height: auto; }
  .occ-media img { height: auto; aspect-ratio: 4 / 5; }
  .occ-num::before { font-size: 14vw; }
  .occ h3 { font-size: 7.8vw; }
  .occ h3 .script { font-size: 10.9vw; }
  .addon-card img { width: 100%; aspect-ratio: 240 / 265; }

  .site-header { padding: 0.7rem 1rem; }
  .site-header nav { justify-content: center; gap: 0.3rem 1.2rem; }

  .hero-script { font-size: 10.9vw; }

  /* Original mobile canvas typography (320px canvas values in vw) */
  .hero h1 { font-family: 'Made Mirage', var(--serif); font-size: 9.375vw; letter-spacing: normal; line-height: 1; }
  .intro-copy h2 { font-size: 7.8vw; }
  .intro-copy h2 .script { font-size: 10.9vw; }
  .pk-copy h3 { font-size: 7.8vw; }
  .addon-card h3 { font-size: 9.375vw; line-height: 1.1; }
  .addon-number { display: none; }
  .addon-desc { font-size: 5vw; }
  .addon-price { font-size: 3.125vw; }
  .btn { font-size: 3.75vw; }
  .addon-foot { gap: 0.5rem; }
  .addon-foot .btn { font-size: 3.2vw; padding: 1em 1.4em; }
  .faq > h2 { font-size: 10.6vw; }
  .faq > h2 .script { font-size: 10.9vw; }
  .faq summary { font-size: 5.625vw; }
  .testimonials .display-light { font-size: 11.25vw; }
  .testimonials .script { font-size: 7.5vw; }
  .quotes blockquote { font-size: 4.375vw; line-height: 1.4; }
  .quotes figcaption { font-size: 3.75vw; }
  .inquire-script { font-size: 16.875vw; }
  .inquire-together { font-size: 16.875vw; }

  .site-footer { grid-template-columns: 1fr; }
  .back-to-top { order: -1; justify-self: end; }

  /* Add-ons on mobile: same pin-and-ride-over choreography as desktop */
  main > .addons {
    background: var(--brown);
    padding: 0;
  }
  .addons-pin {
    position: sticky;
    top: 0;
    min-height: 100vh;
    min-height: 100svh;
    padding: 3.5rem 1.25rem 2rem;
  }
  .addon-step2 {
    position: relative;
    z-index: 1;
    /* base tail; site.js tunes padding-bottom so the pin releases exactly
       when card 2 fully overlaps card 1 at any viewport size */
    padding: 0 1.25rem 3.5rem;
  }

  /* Mobile scatter strip: fewer, smaller photos, like the original's mobile canvas */
  .scatter { aspect-ratio: 320 / 223; }
  .scatter::before { top: -61%; height: 161%; }
  .sc-1, .sc-4, .sc-5 { display: none; }
  .sc-2 { left: 0; top: 24.2%; width: 30.9%; aspect-ratio: 99 / 140; }
  .sc-3 { left: 59%; top: 8.5%; width: 40.9%; aspect-ratio: 131 / 87; }

  /* The original design uses different background photos and crops on mobile */
  .hero {
    background:
      linear-gradient(rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0.45)),
      url("images/ms-props-group.jpg") center 45% / cover no-repeat #000;
  }
  .addons-pin {
    background:
      linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)),
      url('images/ms-guests-props-white.jpg') center 30% / cover no-repeat var(--brown);
  }
  .testimonials::before {
    background:
      linear-gradient(rgba(20, 20, 20, 0.72), rgba(20, 20, 20, 0.72)),
      url('images/ms-props-group.jpg') center / cover no-repeat var(--ink);
  }
}

/* ---------- Effects (enhanced by site.js; page is complete without it) ---------- */

/* Hero fade-up on load, staggered like the engine's fadeIn transitions */
@media (prefers-reduced-motion: no-preference) {
  .hero > * {
    animation: hero-in 1s ease both;
  }
  .hero > :nth-child(2) { animation-delay: 0.15s; }
  .hero > :nth-child(3) { animation-delay: 0.3s; }
  .hero > :nth-child(4) { animation-delay: 0.45s; }
}
@keyframes hero-in {
  from { opacity: 0; translate: 0 22px; }
  to { opacity: 1; translate: 0 0; }
}

/* Scroll reveals: hidden state only applies once JS has run */
html.js .reveal {
  opacity: 0;
  translate: 0 26px;
  transition: opacity 0.9s ease, translate 0.9s ease;
}
html.js .reveal.revealed {
  opacity: 1;
  translate: 0 0;
}

/* Mobile menu overlay */
.menu-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0.5rem;
  position: relative;
  z-index: 21;
}
.menu-toggle span {
  display: block;
  width: 26px;
  height: 1.5px;
  background: var(--ink);
  transition: background-color 0.3s, transform 0.3s, opacity 0.3s;
}
.menu-open .menu-toggle span { background: var(--cream); }
.menu-open .menu-toggle span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.menu-open .menu-toggle span:nth-child(2) { opacity: 0; }
.menu-open .menu-toggle span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

@media (max-width: 800px) {
  /* logo hard left, burger hard right (owner request 2026-08-02). flex-end
     pushed BOTH in-flow children to the right, which parked the wordmark
     mid-header beside the burger; the nav itself is off-canvas fixed here
     so these two are the only items being distributed. */
  html.js .site-header { display: flex; justify-content: space-between; align-items: center; }
  html.js .menu-toggle { display: flex; }
  html.js .site-header nav {
    position: fixed;
    inset: 0;
    z-index: 20;
    background: var(--brown);
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 1.8rem;
    transform: translateX(100%);
    transition: transform 0.4s ease;
  }
  html.js .site-header.menu-open nav { transform: none; }
  html.js .site-header nav a {
    color: var(--cream);
    font-size: 1.25rem;
    letter-spacing: 0.1em;
  }
}

/* Love Notes rotation (controls are injected by site.js).
   All quotes share one grid cell so the box is always as tall as the
   longest quote and the prev/next controls never move. */
html.js .quotes {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  max-width: 620px;
}
html.js .quotes figure {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
}
html.js .quotes figure.quote-active {
  visibility: visible;
  opacity: 1;
}
@media (prefers-reduced-motion: no-preference) {
  html.js .quotes figure.quote-active { animation: quote-in 0.6s ease; }
}
@keyframes quote-in {
  from { opacity: 0; translate: 0 12px; }
  to { opacity: 1; translate: 0 0; }
}
.quote-controls {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 1.1rem;
  margin-top: 2.5rem;
}
.quote-controls span {
  font-family: var(--label);
  font-size: 0.85rem;
  color: #fff;
}
.quote-controls button {
  font-family: var(--label);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #fff;
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0.2rem 0;
}
.quote-controls button:hover { text-decoration: underline; }

/* Continuous gallery drift (site.js): snap and smooth scrolling would
   fight the per-frame scroll updates */
html.js .gallery ul {
  scroll-snap-type: none;
  scroll-behavior: auto;
}

/* ==========================================================================
   MOBILE PASS 2026-08-02 — purely additive, phone-only, desktop untouched
   (every rule verified at 390px and pixel-diffed against the 1440/1200
   baselines: 130/130 segments identical).
   !important appears only where an INLINE style left by the visual editor
   has to be neutralised; there is no other way to outrank one.
   ========================================================================== */
@media (max-width: 800px) {
  /* The intro copy carries a visual-editor height (224px, measured on a
     desktop canvas) on a wrapper the editor injected inside .answer-first.
     At 390px the same words need 355px, so the overflow ran straight through
     the "Check your date" link underneath it. Let the box find its own height
     on a phone; desktop keeps the authored 224. */
  .intro-copy div[style*="min-height"] { height: auto !important; min-height: 0 !important; }

  /* The add-on legend is one word too wide for a phone, and a <legend> that
     wraps puts its second line THROUGH the fieldset's top border (the border
     gap is only cut for the first line). Floating it takes it out of the
     border entirely: label above, unbroken box below, correct at any width. */
  .addon-picks legend { float: left; width: 100%; padding: 0 0 0.5rem; }
  /* The floated legend is taken out of flow, so the NEXT flow sibling shifts
     up beside it. In the kit that sibling is a plain <p> helper line, which
     absorbs the collision harmlessly. A client form built without that helper
     puts a display:flex label there instead: it forms a BFC, refuses to
     overlap the 100%-wide float, collapses to ZERO width and throws its text
     off the right edge. Measured on ShamCam: first add-on label w=0, text at
     x=376-425 in a 390px viewport, on all five pages. That is LIVE LEAD
     INTAKE with one add-on unreachable on a phone, so it is a kit-level fix. */
  .addon-picks label { clear: both; }
  .addon-picks { padding-top: 0.9rem; }

  /* The script's terminal swash on "Featured Add Ons" ran to the last pixel
     column of the viewport. */
  .addons-pin h2 { padding-right: 0.35em; }

  /* The nav drawer is a fixed full-screen panel, so the page behind it still
     took the scroll and the visitor came back somewhere else. */
  body:has(.site-header.menu-open) { overflow: hidden; }
}

/* ---- Event time combo menu (2026-08-12) ------------------------------------
   The dropdown for the Event starts / Event ends questions (site.js port of
   the portal Bookings tab combo). Cream card on the wine band, ink text, the
   highlight in the site's blush so it belongs to this palette. The wrap must
   stay a plain block so it takes the input's grid cell in .form-row. */
.tc-wrap { position: relative; display: block; }
.tc-menu {
  position: absolute; z-index: 40; top: calc(100% + 4px); left: 0; min-width: 100%;
  max-height: 236px; overflow: auto; background: #fff; border: 1px solid var(--cream);
  border-radius: 10px; padding: 6px; box-shadow: 0 12px 34px rgba(20, 20, 20, 0.28);
}
.tc-opt {
  display: flex; justify-content: space-between; align-items: baseline; gap: 14px;
  width: 100%; text-align: left; font: inherit; font-size: 0.9rem; color: var(--ink);
  padding: 7px 10px; border: 0; background: none; border-radius: 7px; cursor: pointer;
  white-space: nowrap;
}
.tc-opt .dur { color: #766f6b; font-size: 0.8rem; }
.tc-opt:hover { background: var(--cream); }
.tc-opt.hl { background: var(--blush); color: var(--brown); font-weight: 600; }
.tc-opt.hl .dur { color: var(--brown); }

/* Phones at their real svh (Safari chrome showing): card 01 ran past the
   window while pinned and its button was unreachable at every scroll position
   (kit README "KNOWN KIT DEFECT", fix ported from the Smooches build). The
   same spacing, tightened, and the photo bounded against the window, only
   where the window is short. padding-top is NOT touched: the opaque sticky
   header ends 62px down and that padding keeps the heading clear of it. */
@media (max-width: 800px) and (max-height: 820px) {
  .addons-pin { padding-bottom: 1.5rem; }
  .addons-pin h2 { margin-bottom: 1.25rem; }
  .addon-card { padding-block: 0.875rem; }
  .addon-inner { padding-top: 1.125rem; padding-bottom: 1.25rem; }
  /* 27svh, not the Smooches 31svh: this build's card copy runs longer, and
     31svh left the button 34px past a 390x664 window (measured). */
  .addon-card img { max-height: 27svh; margin-bottom: 0.85rem; }
}
