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

  /* Tupelo 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 Oxford (.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;
}
.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 services.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 ---------- */

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

.inquiry-form {
  max-width: 620px;
  margin: 0 auto;
  display: grid;
  gap: 1.1rem;
  text-align: left;
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.1rem;
}
.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;
}
.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/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; }
  .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; }
}
