/* ---------- 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;

  /* Lorem Photobooth brand palette (client-supplied, submission 51).
     --rose is 25/34 a text colour, so it carries the maroon from the
     wordmark; the dusty rose is a surface tint (--blush), never body text. */
  --cream: #f3f1ec;
  --brown: #2a3341;
  --ink: #16191f;
  --rose: #613545;
  --gold: #b79a5e;
  --sage: #5f6f60;
  --blush: #d6b2ab;
  /* PLUM ROMANCE colorway, owner pick 2026-08-02 (round: staging/README.md).
     --band is the ground of every full-bleed STATEMENT band plus the inquiry
     section and the footer; it is the same wine as --rose, named separately
     because --rose is a TEXT colour on light grounds and the two must be
     free to move apart. Navy (--brown) is demoted to the UI colour: rate
     cards, solid buttons, the live pill, the mobile menu. Ink (--ink) keeps
     the photo-backed bands (Love Notes, the chapter player), and NO photo
     overlay was retinted anywhere. Text on --band is #fff, accents on it are
     --blush. */
  --band: #613545;
  --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: #d8d4cd;
  --pk-ghost: #d1ccc4;
  --pk-ghost-hover: #9d968c;
  --pk-hover: #edeae4;
  --pk-muted: #464b54;
}

* { 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 hero used to PIN to the viewport (position: sticky, z-index 0) while every
   following section scrolled over the top of it. Owner rejected that on
   2026-08-02: "I don't like that when I scroll the next section goes on top of
   it". The hero now scrolls away with the page like any other section, and the
   photograph is held still by background-attachment instead (below), which
   gives the same held-still image WITHOUT anything sliding over the hero.
   `position: relative` rather than static so any absolutely positioned hero
   child keeps its containing block. This rule reaches three pages: home,
   weddings (.oc-hero) and Ipsum (.loc-hero); 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: relative;
  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/mey/home-hero-open-air-booth-garden.webp") 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 {
  /* full lockup (bow, glasses, sparkles) is 1.35:1, not the 2.6:1 wordmark
     crop, so the width is reduced to keep the rendered height in the hero's
     budget and stop it pushing the H1 down. */
  width: clamp(150px, 19vw, 240px);
  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, and the hero stopped being sticky on 2026-08-02 (owner:
   the next section must not slide over the hero), which killed it: measured,
   .scatter's top sat exactly on .hero's bottom at every scroll offset, so the
   two never overlapped by a single pixel and the photos just landed in a white
   void underneath.

   The fix is to scope the pin instead of restoring it globally. .hero-stack
   wraps ONLY the hero and the scatter, and sticky releases at its containing
   block's bottom, so the hero is pinned for exactly the scatter's travel and
   is then pushed off screen by the end of the wrapper. By the time .intro
   arrives the hero has already gone, so the thing the owner rejected cannot
   happen, and no other page is touched: this wrapper exists only on index.html
   and only the home page has a .scatter.

   .scatter must restate position/z-index here. It used to get them from
   `main > :not(.hero)`, and inside the wrapper it is no longer a child of
   main; without position: relative its absolutely positioned photos and the
   ::before white wash would escape to the nearest positioned ancestor. */

.hero-stack { position: relative; }
.hero-stack > .hero { position: sticky; top: 0; }
.hero-stack > .scatter { position: relative; z-index: 1; }


/* 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/mey/home-addons-bg.webp") 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;
  }
  .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/mey/home-addons-bg.webp") 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: pin top offset + heading height + heading margin */
    padding-top: calc(11svh + 1.15 * clamp(2.8rem, 6vw, 4.4rem) + 1rem + 15px);
  }
  .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. */
  .addon-step2 { pointer-events: none; }
  .addon-step2 > * { pointer-events: auto; }
}
.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/mey/testimonials-bg.webp') center 94% / 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); }
/* the phone link must never break across lines: measured in WebKit, the number
   at the end of this centred 44ch paragraph wrapped as "323-" / "505-8859",
   which reads as a broken number on the one control a call-first customer
   uses. Inherent to the kit (its lorem note ends the same way), fixed here
   once for every page rather than re-reported per section. */
.inquire-note a { color: #fff; white-space: nowrap; }
.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;
}
.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/mey/home-hero-open-air-booth-garden.webp") 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/mey/home-addons-bg.webp') center top / cover no-repeat var(--brown);
  }
  .testimonials::before {
    background:
      linear-gradient(rgba(20, 20, 20, 0.72), rgba(20, 20, 20, 0.72)),
      url('images/mey/testimonials-bg-mobile.webp') 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; }
}

/* Review star rows. Defined here, not only in pages.css, because index.html is
   the one page that does not load pages.css and the stars must render there too.
   Values are identical to the pages.css copy; keep them in step if either moves. */
.pg-stars {
  display: flex;
  align-items: center;
  gap: 0.32em;
  font-size: 0.9rem;
  color: #cbb6ae;
  margin-bottom: 1.1rem;
}
.pg-stars .ico-star { width: 1em; height: 1em; display: block; flex: none; }

/* ---------- Nav dropdown (photo booth group) --------------------------------
   Added 2026-08-07. The home page is now event planning, so a bare "Packages"
   in the nav read as the PLANNING packages. Every photo booth page is grouped
   behind one "Photo Booth" trigger instead.

   The trigger is a <button>, not an <a>, on purpose: site.js closes the mobile
   menu on any nav <a> click, so an anchor trigger would slam the menu shut the
   moment you tried to open the group.

   Desktop: absolutely positioned panel, opens on hover, focus-within, or click
   (click matters for touch laptops, where hover never fires).
   Mobile (<=800px): the nav is a full-screen column, so the panel becomes an
   inline expanding block instead of an overlay. */
.nav-group { position: relative; display: inline-flex; align-items: center; }
.nav-group-toggle {
  font-family: var(--label);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
  opacity: 0.85;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-weight: inherit;
  /* match the sibling <a> box exactly. A button defaults to line-height:normal,
     which gives it a 13px box next to the links' 17.6px. They still centre on
     the same axis, but matching the box keeps any future baseline or wrap
     measurement honest. */
  line-height: 17.6px;
}
.nav-group-toggle:hover,
.nav-group-toggle[aria-expanded="true"] { opacity: 1; }
.nav-group-toggle::after {
  content: "";
  width: 0.4em; height: 0.4em;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translate(-0.1em, -0.1em);
  transition: transform 0.25s ease;
}
.nav-group-toggle[aria-expanded="true"]::after { transform: rotate(-135deg) translate(-0.15em, -0.15em); }

.nav-group-menu {
  position: absolute;
  top: calc(100% + 0.9rem);
  right: 0;
  min-width: 15rem;
  background: #fff;
  border: 1px solid var(--ink);
  padding: 0.9rem 0;
  display: grid;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity 0.22s ease, transform 0.22s ease, visibility 0.22s;
  z-index: 30;
}
/* focus-within is scoped to the MENU, never to .nav-group. Scoping it to the
   group means focus sitting on the trigger button keeps the panel open, so
   Escape clears data-open and aria-expanded but the panel never visually
   closes: a keyboard user cannot dismiss it. Scoped here, tabbing INTO the
   links still holds it open (which is what no-JS keyboard access needs). */
.nav-group:hover .nav-group-menu,
.nav-group-menu:focus-within,
.nav-group-menu[data-open="true"] { opacity: 1; visibility: visible; transform: none; }
/* hover-open only where hovering is real; a touch tap must not leave it stuck */
@media (hover: none) {
  .nav-group:hover .nav-group-menu { opacity: 0; visibility: hidden; transform: translateY(-6px); }
  .nav-group-menu[data-open="true"] { opacity: 1; visibility: visible; transform: none; }
}
.site-header .nav-group-menu a {
  padding: 0.6rem 1.4rem;
  opacity: 0.85;
  white-space: nowrap;
}
.site-header .nav-group-menu a:hover { opacity: 1; background: var(--cream); }

@media (max-width: 800px) {
  /* full-screen column menu: expand inline rather than float a panel */
  html.js .site-header nav .nav-group { flex-direction: column; gap: 1rem; }
  html.js .site-header nav .nav-group-toggle {
    color: var(--cream);
    font-size: 1.25rem;
    letter-spacing: 0.1em;
  }
  html.js .site-header nav .nav-group-menu {
    position: static;
    min-width: 0;
    background: none;
    border: 0;
    padding: 0;
    gap: 1.1rem;
    text-align: center;
    height: 0;
    overflow: hidden;
  }
  html.js .site-header nav .nav-group-menu[data-open="true"] { height: auto; padding: 0.4rem 0 0; }
  html.js .site-header nav .nav-group-menu a { font-size: 1.05rem; padding: 0; }
  html.js .site-header nav .nav-group-menu a:hover { background: none; }
}
