/* ---------- 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. */
  /* 6rem, not the kit's 5.5rem: her logo is 1.92:1 where the kit's placeholder
     was 3:1, so the header stands 92px at 1440 instead of ~69px. 5.5rem (88px)
     no longer cleared it and the hero's first line tucked under. */
  --header-clear: 6rem;

  /* Glow Babe palette. She asked us to pick ("I trust you to select the
     highest converting colors") and gave no logo file, so the palette is
     drawn from her own photographs rather than from brand assets: the black
     marble backdrop her glam portraits are shot against, and the champagne
     curtain behind everything else. Warm black carries the type, gold is the
     single accent, champagne is the paper.
     --rose is a TEXT colour on light grounds (it inherits that role from the
     kit) so it is the bronze, dark enough to read at body size; --blush is a
     SURFACE tint and an accent on dark bands, never body text. */
  --cream: #f6f2ea;
  --brown: #2b2521;
  --ink: #15130f;
  --rose: #8a6534;
  --gold: #c19a4e;
  --sage: #6f6455;
  --blush: #e5cba4;
  /* --band is the ground of every full-bleed STATEMENT band plus the inquiry
     section and the footer. It is the marble black, kept separate from --ink
     (which grounds the photo-backed bands) so the two are free to move apart.
     Espresso (--brown) is the UI colour: rate cards, solid buttons, the mobile
     menu. Text on --band is #fff, accents on it are --blush. No photo overlay
     was retinted. */
  --band: #1a1512;
  --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: #ded7ca;
  --pk-ghost: #d5cdbe;
  --pk-ghost-hover: #a39880;
  --pk-hover: #efe9dd;
  --pk-muted: #554d42;
}

* { 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,
.rates-head p 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;
}
/* A phone number is one token even though it contains hyphens: without this the
   footer NAP line broke "475-296-2078" across two lines at 390px and below,
   which reads as two numbers and splits the tap target in half. Applies to
   every tel: link so the same break cannot come back in another slot. */
a[href^="tel:"] { white-space: nowrap; }
.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,
.rates-head p 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;
}
/* Her logo, top left of the nav. She supplied no logo with the onboarding form,
   so this build first shipped a text wordmark; the real mark was found on her
   live site and replaces it here (owner, 2026-08-09). The header is white, so
   this is the CHARCOAL cut, not the champagne one used in the hero and footer.
   Her artwork is 1.92:1, where the kit's placeholder was 3:1, so at the kit's
   width it stands twice as tall: the width below is set so the header clears
   --header-clear rather than growing under it. */
.site-logo { flex: 0 0 auto; display: block; line-height: 0; }
.site-logo-mark { width: clamp(110px, 9.5vw, 136px); 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/package-2.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 {
  width: clamp(180px, 24vw, 300px);
  height: auto;
  margin-bottom: 0.6rem;
  opacity: 0.96;
}
/* Her supplied logo, above the h1. .hero is already a centred flex column, so
   this is width only. The champagne cutout is the one that survives the hero's
   0.52 black overlay; the charcoal original would disappear into it. */
.hero-logo {
  width: clamp(190px, 26vw, 330px);
  height: auto;
  margin-bottom: clamp(0.4rem, 1.5vw, 1rem);
}
.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/stock/glam-portrait-details-100.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;
  }
  .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/stock/glam-portrait-details-100.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: 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/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 ---------- */

/* White ground since 2026-08-11. She moved the section over to her HoneyBook
   embed, which renders as an opaque white card, and a white card dropped onto
   the marble black read as a slab pasted over the page. The section is white
   so the two are one surface. */
.inquire {
  background: #fff;
  color: var(--ink);
  padding: clamp(4rem, 9vw, 7rem) clamp(1.25rem, 4vw, 2rem);
  text-align: center;
}
/* On the white ground every accent flips to a light-ground colour. --gold is
   the accent on dark bands but only reaches ~2.5:1 on white, so the label and
   the legend take --rose, the bronze the palette already reserves for text on
   light grounds (~5.5:1). The form rules below are dormant while the embed is
   in place; they are kept correct for white so restoring the form does not
   bring back a white button on a white ground. */
.inquire .eyebrow { color: var(--rose); }
.inquire-note a { color: var(--rose); }
.inquire .inquiry-form input,
.inquire .inquiry-form select,
.inquire .inquiry-form textarea { border-color: rgba(21, 19, 15, 0.35); }
.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: var(--band);
  color: #fff;
  border-color: var(--band);
}
.inquire .inquiry-form .btn-solid:hover {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}
.inquire .addon-picks legend { color: var(--rose); }
.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; }
/* Her supplied logo, centred across the footer grid above the nav. It is the
   champagne cutout, because .site-footer is grounded on --band. Sizing only:
   the footer's own padding and the nav's spacing are untouched. */
.footer-logo {
  grid-column: 1 / -1;
  justify-self: center;
  width: clamp(150px, 20vw, 230px);
  height: auto;
  margin-bottom: clamp(1.2rem, 3vw, 2rem);
}
.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;
    /* This pane is PINNED at top:0 for the whole ride-over, so anything inside
       it that sits below the fold can never be scrolled to: page scroll brings
       card 02 up over it, it never reveals this pane's own remainder. The kit
       sizes card 01 to the pin on DESKTOP (.addon-card{height:645px} above);
       on a phone the card kept its natural height, which the kit's own short
       demo copy happened to fit. This client's card runs 827px, so at 390x664
       (an iPhone with Safari's chrome showing, i.e. what 100svh ACTUALLY
       resolves to) the "$100" and the "Add it on" button were permanently
       unreachable; 440x776, 430x812, 360x780 and 360x600 were over too, and
       the width axis failed independently of the height axis.
       Same technique as the desktop pin: hold the pane to exactly one
       viewport and let the PHOTO absorb the difference, which it can because
       it is already object-fit:cover. Nothing is clipped or hidden: the image
       only ever SHRINKS, so every viewport where the card already fitted
       (844, 932, 956) renders byte-identically, and no overflow is set, so if
       a future copy change ever exceeded even this the text would still show.
       Vertical padding goes svh-relative for the same reason: it gives the
       photo back ~26px on the shortest screens and is a no-op at 844+. */
    display: flex;
    flex-direction: column;
    max-height: 100svh;
    padding-top: clamp(1.5rem, 6.6svh, 3.5rem);
    padding-bottom: clamp(0.9rem, 3.8svh, 2rem);
  }
  .addons-pin > .addon-cards { min-height: 0; align-items: stretch; }
  .addons-pin .addon-card { min-height: 0; }
  .addons-pin .addon-inner { height: 100%; }
  .addons-pin .addon-card img { min-height: 0; flex-shrink: 1; }
  .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/package-2.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/addons-bg-mobile.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/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; }
}
