/* =============================================================================
   Self-hosted type
   -----------------------------------------------------------------------------
   These were loaded from fonts.googleapis.com until 15 Sep 2026. Self-hosting
   them is the whole reason this site now makes NO third-party request of any
   kind, which is what lets the privacy policy say so plainly.

   Downloaded from Google Fonts (SIL Open Font License 1.1, which permits
   self-hosting) with `npm run fonts`, not by hand.

   Both text families are VARIABLE fonts, so one file covers every weight on
   the axis and the `font-weight: 300 700` range says so. Google serves the
   same variable file from four different weight URLs; taking them at face
   value ships the identical bytes four times and makes the browser download
   it once per weight the page uses. Hence one @font-face per family and
   subset, never one per weight.

   latin and latin-ext only. The Cyrillic, Greek and Vietnamese subsets Google
   also offers are not reachable from any copy on this site, and unicode-range
   means an unused subset is never downloaded anyway.
   ============================================================================= */

@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/cormorant-garamond-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/manrope-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/manrope-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Pinyon Script";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/pinyon-script-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Pinyon Script";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/pinyon-script-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* =============================================================================
   Luxe Proposal NYC - Concept 1, "Cinematic Gold"
   -----------------------------------------------------------------------------
   Every value below traces to one of two sources and nothing else:
     - the approved mockup, concept-1-approved-homepage.png
       (931px wide, built at 1440, so every measurement scaled x1.547)
     - the supplied tokens, bundle 1 ui/design-tokens.css (verbatim in :root)

   Nothing below :root hardcodes a value that exists as a token.
   ============================================================================= */

:root {
  /* --- bundle 1 tokens, verbatim ------------------------------------------ */
  /* --forest is every dark panel. --forest-rgb is the same colour for the
     scrims over photographs (rgb(… / x%)), kept beside it so the two can never
     drift. A second, darker --ground (#031612) was the page outside the 1200
     frame from 20 Sep until 5 Oct 2026, when the site went full bleed and there
     stopped being an outside. */
  --forest:        #08251e;
  --forest-rgb:    8 37 30;
  --forest-hover:  #16362d;
  --ivory:         #f5f0e7;
  --ivory-soft:    #faf8f3;
  --gold:          #c8aa6e;
  --ink:           #171a18;
  --muted:         #5f635e;
  --white:         #ffffff;

  --font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-body:    Manrope, Arial, Helvetica, sans-serif;

  --content:    1200px;
  --rule:       1px solid rgb(200 170 110 / 55%);
  --transition: 180ms ease;

  /* --- derived, measured off the mockup ------------------------------------ */
  --header-h:   76px;   /* mockup 49px x1.547 */
  --band-y:     94px;   /* mockup 61px, boundary to text, on the Settings band */
  --band-y-sm:  64px;
  --gutter:     28px;

  /* The vertical ladder is closed. Every gap in this file is one of these six. */
  --gap-1: 10px;
  --gap-2: 18px;
  --gap-3: 26px;
  --gap-4: 38px;
  --gap-5: 56px;
  --gap-6: 78px;

  /* Type. Left of the arrow is the mockup reading, right is the built value. */
  --t-hero:    clamp(2.35rem, 5.2vw, 3.4rem);  /* 35px  -> 54px */
  --t-h2:      clamp(1.85rem, 3.4vw, 2.55rem); /* 26px  -> 41px */
  --t-h3:      clamp(1.45rem, 2.4vw, 1.9rem);  /* 20px  -> 30px */
  --t-numeral: clamp(1.25rem, 2vw, 1.6rem);    /* 13px  -> 20px */
  --t-body:    1.0625rem;                      /* 11px  -> 17px */
  --t-lead:    1.1875rem;                      /* 12px  -> 19px */
  /* 8.5px on the mockup -> 13px at 1440. An INVERSE ramp, which is unusual
     here and deliberate: 13px of uppercase at 0.16em tracking is the one size
     on this site that reads as delicate on a phone, and it is doing the most
     work there - every footer link, every button, the Decor filters and every
     eyebrow. So it grows as the viewport SHRINKS, 13px at 1440 up to 15px at
     390, and it is a ramp rather than a breakpoint because MOBILE.md rule 1
     applies whichever direction a size moves in.
     The upper anchor is 960, NOT 1440. Ramping all the way up made the header
     "Start Planning" button 218px at 961px - the widest point where the nav is
     still horizontal - and the header overflowed by 28px. check:widths caught
     it on pre-push. Above 960 the layout is not the one the review was about,
     so the ramp ends there and every desktop width keeps the measured 13px it
     already had. 960 is a real structural breakpoint (the nav collapses) and
     the ramp is continuous through it, so nothing steps.
       slope (13 - 15) / (960 - 390) = -0.00350877px per px = -0.350877vw
       intercept 15 - (-0.00350877 x 390)                   = 16.3684px
     Review of 16 Sep 2026, item 2. Departs from the mockup on purpose. */
  --t-label:   clamp(13px, calc(16.3684px - 0.350877vw), 15px);

  --lh-tight: 1.14;
  --lh-body:  1.68;

  --track-label: 0.16em;   /* the letterspacing on every uppercase run */
  --track-btn:   0.13em;
}

/* --- reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* FULL BLEED, both sides (Jacob, 5 Oct 2026). Every band's colour and every
   band photograph runs to the edges of the window; the copy, grids and
   galleries inside them stay in the 1200 column (--content). The rules that do
   it are at the end of this file, under "Full bleed", because they only exist
   past 1200 and have to win over the per-section rules.
   From 10 Sep to 5 Oct 2026 it was the opposite: the whole page capped at 1200
   on a darker ground, nothing full bleed, Jacob's call on 10 Sep. The approved
   mockup was full bleed throughout, so this is a return to it. */
html {
  -webkit-text-size-adjust: 100%;
  background: var(--forest);
}
body {
  background: var(--ivory-soft);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  margin: 0;
}
/* height:auto is load-bearing, not tidiness. Every <img> carries width/height
   attributes (bundle 5 asks for them, and they stop layout shift), and those
   are presentation hints that set a used height of 1200px. With height left at
   its hinted value, `aspect-ratio` below is ignored entirely: every photograph
   rendered 1200px tall and the homepage came out 9562px instead of ~5600. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 500; line-height: var(--lh-tight); margin: 0; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

.container { width: 100%; max-width: var(--content); margin-inline: auto; padding-inline: var(--gutter); }

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--forest); color: var(--gold); padding: var(--gap-1) var(--gap-3); z-index: 100;
}
.skip-link:focus { left: 0; }

:where(a, button, input, textarea, select):focus-visible {
  outline: 2px solid var(--gold); outline-offset: 3px;
}

/* --- shared type ---------------------------------------------------------- */
.eyebrow {
  font-size: var(--t-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: var(--gap-2);
}
.lead { font-size: var(--t-lead); }
.muted { color: var(--muted); }

/* The short gold editorial rule under a heading. Bundle 1 ships it as an SVG;
   a border does the same job without a request. */
.rule { width: 62px; height: 0; border-top: var(--rule); margin: var(--gap-3) 0; }
.rule--center { margin-inline: auto; }

/* --- buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 52px;
  padding: 0 var(--gap-4);
  font-family: var(--font-body);
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: var(--track-btn);
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
  /* A button's copy cannot reflow, so never let it try. */
  white-space: nowrap;
}
.btn--primary { background: var(--forest); color: var(--ivory); border-color: var(--forest); }
.btn--primary:hover { background: var(--forest-hover); border-color: var(--forest-hover); }
.btn--ghost { background: transparent; color: var(--white); border-color: rgb(255 255 255 / 65%); }
.btn--ghost:hover { background: rgb(255 255 255 / 12%); border-color: var(--white); }
.btn--gold { background: var(--gold); color: var(--forest); border-color: var(--gold); }
.btn--gold:hover { background: transparent; color: var(--gold); }

.arrow-link {
  display: inline-flex; align-items: center; gap: var(--gap-1);
  font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--gold); text-decoration: none;
  border-bottom: 1px solid rgb(200 170 110 / 55%);
  padding-bottom: 6px;
}
.arrow-link:hover { color: var(--white); border-bottom-color: var(--white); }
.arrow-link .icon { width: 22px; height: 22px; margin-block: -7px; }

/* Icons are the PNG set Jacob supplied on 18 Sep 2026 (assets/img/icons/),
   drawn as masks so each takes the colour of the text it sits in, hover
   included, exactly as the inline SVGs did. */
.icon {
  display: inline-block; background-color: currentColor;
  -webkit-mask: center / contain no-repeat;
          mask: center / contain no-repeat;
}
.icon--whatsapp { -webkit-mask-image: url(../img/icons/icon-whatsapp.png); mask-image: url(../img/icons/icon-whatsapp.png); }
.icon--instagram { -webkit-mask-image: url(../img/icons/icon-instagram.png); mask-image: url(../img/icons/icon-instagram.png); }
.icon--google { -webkit-mask-image: url(../img/icons/icon-google-reviews.png); mask-image: url(../img/icons/icon-google-reviews.png); }
.icon--mood { -webkit-mask-image: url(../img/icons/icon-heart-personal-mood.png); mask-image: url(../img/icons/icon-heart-personal-mood.png); }
.icon--privacy { -webkit-mask-image: url(../img/icons/icon-privacy-lock.png); mask-image: url(../img/icons/icon-privacy-lock.png); }
.icon--weather { -webkit-mask-image: url(../img/icons/icon-weather-backup.png); mask-image: url(../img/icons/icon-weather-backup.png); }
.icon--guests { -webkit-mask-image: url(../img/icons/icon-guest-capacity.png); mask-image: url(../img/icons/icon-guest-capacity.png); }
.icon--heart { -webkit-mask-image: url(../img/icons/icon-heart-personal-mood.png); mask-image: url(../img/icons/icon-heart-personal-mood.png); }
.icon--flower { -webkit-mask-image: url(../img/icons/icon-thoughtful-leaf.png); mask-image: url(../img/icons/icon-thoughtful-leaf.png); }
.icon--toast { -webkit-mask-image: url(../img/icons/icon-celebration-champagne.png); mask-image: url(../img/icons/icon-celebration-champagne.png); }
.icon--arrow { -webkit-mask-image: url(../img/icons/icon-arrow-right.png); mask-image: url(../img/icons/icon-arrow-right.png); }
.icon--play { -webkit-mask-image: url(../img/icons/icon-video-play.png); mask-image: url(../img/icons/icon-video-play.png); }
.icon--email { -webkit-mask-image: url(../img/icons/icon-email.png); mask-image: url(../img/icons/icon-email.png); }

/* --- contact strip and social icons ---------------------------------------- */
/* Not in the mockup: Ariel asked for WhatsApp beside the way in to contact, and
   for his Google reviews and Instagram. Every value is an existing token - the
   footer's ivory-on-forest text and hairline, the 44px tap floor, --t-label -
   so the strip reads as part of the header rather than a new component. */
.topbar { background: var(--forest); border-bottom: 1px solid rgb(244 240 231 / 14%); }
.topbar-inner { display: flex; align-items: center; justify-content: flex-end; gap: var(--gap-1); }
.topbar-wa {
  display: inline-flex; align-items: center; gap: var(--gap-1); min-height: 44px; margin-right: var(--gap-2);
  font-size: var(--t-label); letter-spacing: 0.05em; color: rgb(244 240 231 / 76%); text-decoration: none;
  transition: color var(--transition);
}
.social-icon {
  display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  color: rgb(244 240 231 / 76%); transition: color var(--transition);
}
/* 25px boxes: the PNG set draws its glyph in the middle 72%, so the glyph is the 18px the SVGs were. */
.topbar-wa .icon, .social-icon .icon { width: 25px; height: 25px; flex-shrink: 0; }
.topbar-wa:hover, .social-icon:hover { color: var(--gold); }
/* The footer's icons: 44px targets whose 18px glyphs sit on the text around
   them. 13px is (44 - 18) / 2, the glyph's inset in its target, so the first
   glyph starts on the text edge; on desktop the -11px block margin is
   (44 - 22) / 2 against the meta row's 22px line, so the targets do not
   make the row taller than its text. */
.footer-social { display: flex; margin: -11px -13px; }

/* --- header --------------------------------------------------------------- */
.site-header { background: var(--forest); position: sticky; top: 0; z-index: 50; }
.header-inner {
  min-height: var(--header-h);
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap-3);
}
.header-logo { display: block; flex-shrink: 0; }
.header-logo img { width: 196px; height: auto; }  /* bundle 1 asks for 190-230px */
/* Once the page scrolls the sticky header tightens to 72px (Jacob, 18 Sep
   2026: "roughly 70-75"); the logo drops to 52px tall so it keeps 10px above
   and below. luxe.js sets .is-scrolled. Below 1061 the header does not stick. */
.header-inner, .header-logo img { transition: min-height var(--transition), width var(--transition); }
.site-header.is-scrolled { box-shadow: 0 1px 0 rgb(244 240 231 / 14%); }
.site-header.is-scrolled .header-inner { min-height: 72px; }
.site-header.is-scrolled .header-logo img { width: 164px; }

/* Six links since Home (18 Sep 2026): the gap ramps from 18 at the 1061 collapse point to the measured 38 at the frame, and no label may break in two. */
.nav { display: flex; align-items: center; gap: clamp(var(--gap-2), calc(14.39vw - 134.7px), var(--gap-4)); }
.nav a { white-space: nowrap; }
.nav a {
  font-size: var(--t-label);
  letter-spacing: 0.05em;
  color: var(--ivory);
  text-decoration: none;
  padding-block: var(--gap-1);
  transition: color var(--transition);
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--gold); }
.header-cta .btn { min-height: 44px; }
/* The collapsed menu's own button and contact links (header.php); the full
   header has the button and the phone bar instead. */
.nav-extra { display: none; }

.nav-toggle {
  display: none;
  background: none; border: 1px solid rgb(244 240 231 / 35%); color: var(--ivory);
  min-height: 44px; padding-inline: var(--gap-2);
  font-family: var(--font-body);
  font-size: var(--t-label); letter-spacing: var(--track-btn); text-transform: uppercase;
  cursor: pointer;
}

/* --- hero ----------------------------------------------------------------- */
.hero { position: relative; background: var(--forest); isolation: isolate; }
.hero-media { position: absolute; inset: 0; z-index: -2; }
/* 95% down, not centred (Jacob, 5 Oct 2026, twice): less headroom, more of
   the bottom. Phones have their own position, below at 620. */
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: 75% 95%; }

/* Contrast is added here, never edited into the photograph (bundle 1 and 2 both
   say so). The stops were chosen by measuring the backdrop under the copy box:
   the 90th-percentile luminance there has to clear 4.5:1 against --white. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
    rgb(var(--forest-rgb) / 92%) 0%,
    rgb(var(--forest-rgb) / 78%) 26%,
    rgb(var(--forest-rgb) / 34%) 52%,
    rgb(var(--forest-rgb) / 10%) 74%,
    rgb(var(--forest-rgb) / 0%) 100%);
}
.hero-inner {
  min-height: clamp(500px, 74vh, 660px);
  display: flex; flex-direction: column; justify-content: center;
  padding-block: var(--gap-6);
  max-width: 41rem;
  /* This element is also a .container, which sets `margin-inline: auto` for a
     1200px box. Narrowing it to 41rem here without resetting that leaves the
     auto margins to centre the copy over the middle of the photograph, on top
     of the man proposing. The copy belongs hard left, in the dark half the
     gradient was built for. */
  margin-inline: 0;
  color: var(--white);
}
.hero h1 { font-size: var(--t-hero); margin-bottom: var(--gap-3); }
.hero .lead { color: rgb(255 255 255 / 88%); margin-bottom: var(--gap-4); max-width: 34rem; }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--gap-2); }
.hero .btn--primary { background: var(--gold); border-color: var(--gold); color: var(--forest); }
.hero .btn--primary:hover { background: var(--white); border-color: var(--white); }

/* --- bands ---------------------------------------------------------------- */
.band { padding-block: var(--band-y); }
.band--ivory { background: var(--ivory); }
.band--ivory-soft { background: var(--ivory-soft); }
.band--forest { background: var(--forest); color: var(--ivory); }
.band--forest h2, .band--forest h3 { color: var(--white); }
.band--forest .muted { color: rgb(244 240 231 / 72%); }
.band--tight { padding-block: var(--band-y-sm); }

.split {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.split--wide-media { grid-template-columns: 1.05fr 0.95fr; }
.split figure { margin: 0; }
.split img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; max-width: 100%; }

.band h2 { font-size: var(--t-h2); }
.band .body-copy > p + p { margin-top: var(--gap-3); }
.narrow { max-width: 48rem; }
.center { text-align: center; margin-inline: auto; }

/* --- settings cards ------------------------------------------------------- */
.settings-head {
  display: flex; align-items: end; justify-content: space-between; gap: var(--gap-4);
  margin-bottom: var(--gap-5);
}
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-3); }
.card { display: block; text-decoration: none; color: inherit; }
.card img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.card-label { display: flex; align-items: center; gap: var(--gap-2); margin-top: var(--gap-3); padding-top: var(--gap-2); }
.card-num { font-family: var(--font-display); font-size: var(--t-numeral); color: var(--gold); }
.card-name {
  font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase;
  padding-left: var(--gap-2); border-left: 1px solid rgb(200 170 110 / 45%);
  transition: color var(--transition);
}
.card:hover .card-name { color: var(--gold); }

/* --- numbered process ----------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-3); margin-top: var(--gap-5); }
.step { padding-left: var(--gap-3); border-left: 1px solid rgb(200 170 110 / 45%); }
.step:first-child { padding-left: 0; border-left: 0; }
.step-num { font-family: var(--font-display); font-size: var(--t-h3); color: var(--gold); display: block; margin-bottom: var(--gap-1); }
.step-name { font-family: var(--font-display); font-size: var(--t-body); }

/* --- testimonial ---------------------------------------------------------- */
.testimonial { display: grid; grid-template-columns: 0.34fr 0.66fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.testimonial img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; filter: grayscale(1); }
/* The mockup drew one invented line at --t-h3. The real quotes are paragraphs,
   so they take the site's existing paragraph-length display setting, the one
   .page-intro-copy measured (1.4rem / 1.38), rather than a new size. */
.testimonial-quotes { text-align: center; }
.testimonial figure { margin: 0; }
.testimonial blockquote { margin: 0; font-family: var(--font-display); font-size: 1.4rem; line-height: 1.38; color: var(--ink); }
.testimonial figcaption {
  margin-top: var(--gap-2);
  font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted);
}
.testimonial figcaption::before { content: "\2014\00a0"; }

/* --- closing cta ---------------------------------------------------------- */
.cta { position: relative; isolation: isolate; text-align: center; color: var(--white); }
.cta-media { position: absolute; inset: 0; z-index: -2; }
.cta-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
.cta::after { content: ""; position: absolute; inset: 0; z-index: -1; background: rgb(var(--forest-rgb) / 52%); }
.cta-inner {
  min-height: clamp(320px, 40vh, 420px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding-block: var(--gap-6);
}
.cta h2 { font-size: var(--t-h2); color: var(--white); max-width: 22ch; margin-bottom: var(--gap-4); }

/* --- footer --------------------------------------------------------------- */
.site-footer { background: var(--forest); color: rgb(244 240 231 / 76%); padding-block: var(--gap-5); }
.footer-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--gap-4); }
.footer-logo img { width: 196px; height: auto; }
.footer-nav { display: flex; flex-wrap: wrap; gap: var(--gap-3); }
.footer-nav a { font-size: var(--t-label); letter-spacing: 0.05em; text-decoration: none; }
.footer-nav a:hover { color: var(--gold); }
.footer-meta {
  margin-top: var(--gap-4); padding-top: var(--gap-3);
  border-top: 1px solid rgb(244 240 231 / 14%);
  display: flex; flex-wrap: wrap; gap: var(--gap-3) var(--gap-4);
  font-size: var(--t-label); letter-spacing: 0.03em;
}
/* The seven meta items are grouped in the markup - contact, service area,
   legal - so the phone can stack them in that order. On desktop the groups
   DISSOLVE, so .footer-meta still lays out seven flex items in one wrapped
   row exactly as it did before the grouping existed. */
.footer-contact, .footer-area, .footer-legal { display: contents; }
.footer-meta a { text-decoration: none; }
.footer-meta a:hover { color: var(--gold); }

/* --- placeholder ---------------------------------------------------------- */
/* Deliberately plain. A plausible-looking placeholder is worse than an obvious
   gap, because it ships. Anything wearing this class is NOT ready. */
.placeholder {
  border: 1px dashed rgb(200 170 110 / 70%);
  background: rgb(200 170 110 / 8%);
  padding: var(--gap-3);
  font-size: var(--t-label);
  letter-spacing: 0.04em;
  color: var(--muted);
}
.band--forest .placeholder { color: rgb(244 240 231 / 80%); }
.placeholder strong {
  display: block; color: var(--gold);
  letter-spacing: var(--track-label); text-transform: uppercase; margin-bottom: var(--gap-1);
}

/* --- inquiry form --------------------------------------------------------- */
/* Ariel's spec, 9 Sep: one question set at a time, the way elitemarryme.com
   does it. Built as fieldsets so it degrades to a plain long form with no JS
   and no wired handler, which is what it is until we are on his hosting. */
.inquiry { margin-top: var(--gap-5); }
.form-step {
  border: 0; border-top: var(--rule);
  margin: 0; padding: var(--gap-4) 0 0;
}
.form-step + .form-step { margin-top: var(--gap-4); }
.form-step legend {
  font-family: var(--font-display);
  font-size: var(--t-h3);
  padding: 0;
  margin-bottom: var(--gap-2);
}
.form-step > p { margin-bottom: var(--gap-3); }
.form-step label {
  display: block;
  margin-top: var(--gap-2);
  font-size: var(--t-body);
}
.form-step input[type="text"],
.form-step input[type="email"],
.form-step input[type="tel"],
.form-step textarea {
  display: block; width: 100%; max-width: 100%;
  margin-top: var(--gap-1);
  padding: var(--gap-2);
  font-family: var(--font-body); font-size: var(--t-body); color: var(--ink);
  background: var(--white);
  border: 1px solid rgb(95 99 94 / 30%);
  border-radius: 0;
}
.form-step textarea { resize: vertical; }
.form-step input[type="radio"] { accent-color: var(--gold); margin-right: var(--gap-1); }
/* A file input is a native control and its intrinsic width is set by the font
   inside it, so it grew with the --t-label ramp and pushed /contact 38px wide
   at 320. max-width: 100% cannot fix that on its own - the control's own
   min-content is what is too wide - so it needs width and min-width: 0 to be
   allowed to shrink. Found by check:widths on pre-push, 16 Sep 2026. */
.form-step input[type="file"] {
  margin-top: var(--gap-1); font-size: var(--t-label);
  width: 100%; min-width: 0; max-width: 100%; box-sizing: border-box;
}
.upload { border: 1px dashed rgb(95 99 94 / 40%); padding: var(--gap-3); background: var(--ivory-soft); }

.tier { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--gap-1); }
.tier-name { font-family: var(--font-display); font-size: var(--t-body); }
.tier-price { color: var(--muted); }
.tier-flag {
  font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--gold);
}
.fine { font-size: var(--t-label); line-height: 1.55; margin-top: var(--gap-3); }
.inquiry > .btn { margin-top: var(--gap-4); }

/* --- stub pages ----------------------------------------------------------- */
.page-head { background: var(--forest); color: var(--white); padding-block: var(--gap-6); }
.page-head h1 { font-size: var(--t-h2); }
.page-head p { color: rgb(244 240 231 / 78%); margin-top: var(--gap-2); max-width: 46rem; }

/* --- legal ---------------------------------------------------------------- */
.legal { max-width: 46rem; }
.legal h2 { font-size: var(--t-h3); margin-top: var(--gap-5); }
.legal h2:first-of-type { margin-top: 0; }
.legal h3 { font-size: var(--t-body); margin-top: var(--gap-4); letter-spacing: 0.02em; }
.legal p + p, .legal ul { margin-top: var(--gap-2); }
.legal li { padding-left: var(--gap-2); position: relative; }
.legal li::before { content: "\00b7"; position: absolute; left: 0; color: var(--gold); }
.legal .updated { font-size: var(--t-label); letter-spacing: 0.04em; color: var(--muted); }

/* =============================================================================
   Subpages: the hero, intro and closing CTA that Decor Design and Unscripted
   Moments share. Defined once; each page sets its own measured values as
   custom properties on its <main> (.dd, .um), and design/SPEC.md has the
   measurement behind every one of them.
   ============================================================================= */
.subpage {
  --hero-h:        590px;
  --hero-floor:    440px;
  --hero-ratio:    0.4917;  /* --hero-h / 1200, the frame */
  --hero-inset:    74px;
  --hero-img-w:    100%;
  --hero-img-pos:  50% 50%;
  --hero-h1-lh:    1.1;
  --media-inset:   58px;
  --copy-inset:    106px;
  --cta-inset:     97px;
  --cta-h:         426px;
  --cta-pad-top:   78px;
  --cta-pad-bot:   78px;
  --cta-p-gap:     52px;
  --cta-btn-gap:   36px;
  --intro-top:     74px;
  --intro-w:       630px;
  --tile-gap:      10px;
  --t-page-hero: clamp(2.375rem, calc(2.469vw + 1.776rem), 3.625rem);
  --t-page-h2:   clamp(1.75rem, calc(0.864vw + 1.536rem), 2.1875rem);  /* 35 at the frame, 28 at 390 */
}

.page-hero { position: relative; isolation: isolate; background: var(--forest); color: var(--white); }
.page-hero-media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
/* --hero-img-w above 100% draws the photograph wider than the band from its left
   edge, which moves a centred subject right, out from under the headline. */
.page-hero-media img { width: var(--hero-img-w); max-width: none; height: 100%; object-fit: cover; object-position: var(--hero-img-pos); }
.page-hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(95deg,
    rgb(var(--forest-rgb) / 88%) 0%, rgb(var(--forest-rgb) / 70%) 30%,
    rgb(var(--forest-rgb) / 22%) 55%, rgb(var(--forest-rgb) / 0%) 72%);
}
.page-hero-inner {
  /* --hero-h at the 1200 frame, scaling with the frame; a floor, never a fixed
     height, so taller copy on a phone grows the band instead of spilling. */
  min-height: clamp(var(--hero-floor), calc(min(100vw, 1200px) * var(--hero-ratio)), var(--hero-h));
  display: flex; flex-direction: column; justify-content: center;
  padding-inline: var(--hero-inset); padding-block: var(--gap-5);
}
/* 8.4em breaks both pages' headlines where their mockups break them. */
.page-hero h1 { font-size: var(--t-page-hero); line-height: var(--hero-h1-lh); max-width: 8.4em; }
.page-hero .rule { margin-block: var(--gap-4); }
.page-hero p { font-size: var(--t-body); line-height: 1.53; color: rgb(255 255 255 / 90%); max-width: 22rem; }

.page-intro { padding-top: var(--intro-top); padding-inline: var(--gutter); }
.page-intro-copy { max-width: var(--intro-w); margin-inline: auto; }
.page-intro-copy p { font-family: var(--font-display); font-size: 1.4rem; line-height: 1.38; color: var(--ink); }
.page-intro-copy .rule { margin: 28px 0 0; }

.page-cta { position: relative; isolation: isolate; background: var(--forest); color: var(--white); }
.page-cta-media { position: absolute; inset: 0 0 0 40%; z-index: -2; }
.page-hero-media picture, .page-cta-media picture { display: contents; }
.page-cta-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
.page-cta::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, var(--forest) 0%, var(--forest) 40%, rgb(var(--forest-rgb) / 40%) 58%, rgb(var(--forest-rgb) / 0%) 80%);
}
.page-cta-inner {
  min-height: var(--cta-h);
  padding: var(--cta-pad-top) var(--cta-inset) var(--cta-pad-bot);
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
}
.page-cta h2 { font-size: var(--t-page-h2); line-height: 1.25; color: var(--white); max-width: 12em; }
.page-cta .rule { margin: 25px 0 0; }
/* The gaps are mockup ink to ink, less the ~16px the type's own leading supplies. */
.page-cta p { margin-top: var(--cta-p-gap); color: rgb(244 240 231 / 86%); max-width: 21rem; line-height: 1.53; }
.page-cta .btn { margin-top: var(--cta-btn-gap); min-width: 240px; }

/* =============================================================================
   Page: Decor Design (decor-design.html)
   Mockup design/mockup/decor-design-826.png, read as the 1200 frame, so x1.453.
   The shared defaults above ARE this page's values; only its own parts follow.
   ============================================================================= */
/* The castle lawn heart (IMG_0657, Ariel's pick, 18 Sep 2026) full width and
   low: the whole heart shows, near the middle and clear of the headline. */
.dd { --hero-img-w: 100%; --hero-img-pos: 50% 62%; }

.dd-filters {
  display: flex; flex-wrap: wrap; justify-content: center;
  margin: 64px auto 44px; padding-inline: var(--gutter);
}
.dd-filters[hidden] { display: none; }
.dd-filter {
  position: relative;
  background: none; border: 0; cursor: pointer;
  font-family: var(--font-display); font-size: 1.1rem; color: var(--ink);
  min-height: 44px; padding: 0 34px;
}
.dd-filter + .dd-filter::before {
  content: ""; position: absolute; left: 0; top: 50%; height: 1em; transform: translateY(-50%);
  border-left: 1px solid rgb(200 170 110 / 70%);
}
.dd-filter span { padding-bottom: var(--gap-1); border-bottom: 1px solid transparent; transition: color var(--transition), border-color var(--transition); }
.dd-filter:hover span { color: var(--gold); }
.dd-filter[aria-pressed="true"] span { color: var(--gold); border-bottom-color: var(--gold); }

.dd-gallery-wrap { padding-inline: var(--media-inset); }
.dd-gallery {
  display: grid; gap: var(--tile-gap);
  grid-template-columns: 283fr 225fr 225fr;
  grid-template-rows: 410fr 99fr 36fr 301fr;
  grid-template-areas: "a b c" "a e c" "a e f" "d e f";
  aspect-ratio: 1084 / 876;
}
.dd-gallery figure { margin: 0; min-height: 0; overflow: hidden; background: var(--forest); }
.dd-gallery img { width: 100%; height: 100%; object-fit: cover; }
.dd-gallery [data-slot="a"] { grid-area: a; }
.dd-gallery [data-slot="b"] { grid-area: b; }
.dd-gallery [data-slot="c"] { grid-area: c; }
.dd-gallery [data-slot="d"] { grid-area: d; }
.dd-gallery [data-slot="e"] { grid-area: e; }
.dd-gallery [data-slot="f"] { grid-area: f; }
/* Photos beyond the mockup's six only appear once a filter is chosen, so each
   category has more than one setup to show. Filtered, the mosaic's fixed areas
   no longer make sense, so the grid becomes uniform. */
.dd-gallery:not([data-filter]) [data-extra] { display: none; }
.dd-gallery[data-filter] {
  grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: none; grid-template-areas: none;
  aspect-ratio: auto; grid-auto-flow: dense;
}
.dd-gallery[data-filter] figure { grid-area: auto; aspect-ratio: 4 / 5; }
/* A landscape setup in a 4:5 tile keeps under half its frame, so wide shots
   take two tracks at a landscape ratio wherever the grid is uniform. */
.dd-gallery[data-filter] figure[data-wide] { grid-column: span 2; aspect-ratio: 16 / 10; }
.dd-gallery figure[hidden] { display: none; }

/* 126/86 are the mockup's measurements at 1440 and they still are up there.
   They were also being served UNCHANGED at 390, where 126px of top padding is
   a third of the screen width in empty space - the fixed-padding case
   MOBILE.md rule 1 exists for, and the reason this section reads as stranded
   from its heading on a phone. Ramped to 64/48 at 390, which is the rhythm the
   16 Sep review asked for (56-64px), solved so the upper anchor is exactly the
   measured value:
     top     (126 - 64) / 1050 = 0.059048px/px = 5.9048vw,  40.971px intercept
     bottom  (86  - 48) / 1050 = 0.036190px/px = 3.6190vw,  33.886px intercept */
.dd-process {
  padding-top: clamp(64px, calc(40.971px + 5.9048vw), 126px);
  padding-inline: var(--copy-inset);
  padding-bottom: clamp(48px, calc(33.886px + 3.619vw), 86px);
}
.dd-process h2 { font-size: var(--t-page-h2); }
.dd-process .rule { margin: 35px 0 0; }
.dd-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 44px 0 0; padding: 0; list-style: none; }
.dd-step { padding-inline: 0 41px; }
.dd-step + .dd-step { padding-left: 41px; border-left: 1px solid rgb(200 170 110 / 45%); }
/* Shared with .um-chapter-num: the gold display numeral both pages use. */
.dd-step-num, .um-chapter-num { display: block; font-family: var(--font-display); font-size: var(--t-page-h2); line-height: 1; color: var(--gold); font-variant-numeric: lining-nums; }
.dd-step h3 { font-size: 1.25rem; margin-top: 28px; }
.dd-step p { font-size: 1rem; line-height: 1.625; color: var(--muted); margin-top: 22px; max-width: 16rem; }

/* =============================================================================
   Page: Unscripted Moments (unscripted-moments.html)
   Mockup design/mockup/unscripted-moments-827.png, read as the 1200 frame, so
   x1.451. Every number is in design/SPEC.md, "Unscripted Moments".
   ============================================================================= */
.um {
  /* 502 (the mockup's 346) until 5 Oct 2026, when Jacob asked for more of the
     bottom of the photograph: it stopped at their waists. */
  --hero-h:       600px;
  --hero-ratio:   0.5;
  /* NLV01231 at 125% and 26% down (Jacob, 18 Sep 2026: "up a bit, and to the
     right"): the couple clear the headline and the ring hands are in frame. */
  --hero-img-w:   125%;
  --hero-img-pos: 50% 26%;
  --hero-h1-lh:   1.16;    /* pitch 39 -> 57 on 49px */
  /* 49px at the frame, 36px at 390 */
  --t-page-hero: clamp(2.25rem, calc(1.605vw + 1.859rem), 3.0625rem);
  --intro-top:    57px;    /* 39  */
  --intro-w:      557px;   /* 384 */
  --cta-h:        441px;   /* 304 */
  --cta-pad-bot:  102px;   /* 70  */
  --cta-p-gap:    26px;    /* 18, after the rule */
  --cta-btn-gap:  28px;    /* 19  */
}

.um-chapters { padding: 44px var(--media-inset) 42px; }
.um-chapter + .um-chapter { margin-top: 41px; }
/* The title track used to be the 1fr, so it stretched the width of the band
   and pushed "View moments" against the right edge - roughly 870px of nothing
   between a chapter's name and its own control at 1440, which is why the two
   read as unrelated (review, 16 Sep 2026, item 4). The 1fr now sits AFTER the
   toggle: number, title, toggle, then whatever space is left over. Below 960
   the toggle already dropped onto its own row, and still does. */
.um-chapter-head {
  display: grid; grid-template-columns: auto auto 1fr; align-items: center;
  column-gap: 0; margin-bottom: 23px; padding-inline: 7px 12px;
}
.um-chapter-num { padding-right: 46px; border-right: 1px solid rgb(200 170 110 / 60%); }
.um-chapter-title { padding-left: 58px; }
/* 29 at 961 and up, ramping to 24 at 390 (the mobile review's tighter
   chapter heads, 18 Sep 2026) rather than stepping at 620. */
.um-chapter h2 { font-size: clamp(1.5rem, calc(0.876vw + 1.2863rem), 1.8125rem); line-height: 1.1; }
.um-chapter-sub { font-family: var(--font-display); font-size: 1.0625rem; color: var(--muted); margin-top: 6px; }
.um-more-toggle {
  background: none; border: 0;
  /* 46px is the gap the number already sets against the rule in this same
     component (.um-chapter-num padding-right), so the header keeps one
     horizontal rhythm instead of gaining a second number. */
  padding: 0; margin-left: 46px; justify-self: start;
  min-height: 44px; cursor: pointer; align-self: end;
  font-family: var(--font-body); font-size: var(--t-label); font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--gold);
}
.um-more-toggle span { padding-bottom: 6px; border-bottom: 1px solid rgb(200 170 110 / 60%); }
.um-more-toggle:hover { color: var(--ink); }
.um-more-toggle:hover span { border-bottom-color: var(--ink); }

.um-row { display: grid; gap: var(--tile-gap); }
.um-row--surprise    { grid-template-columns: 391fr 171fr 174fr; aspect-ratio: 1084 / 276; }
.um-row--yes         { grid-template-columns: 352fr 176fr 206fr; aspect-ratio: 1084 / 270; }
.um-row--celebration { grid-template-columns: 362fr 149fr 225fr; aspect-ratio: 1084 / 254; }
.um-row figure, .um-more figure { margin: 0; min-width: 0; min-height: 0; overflow: hidden; background: var(--forest); }
.um-row img, .um-more img { width: 100%; height: 100%; object-fit: cover; }

.um-film { position: relative; display: block; width: 100%; height: 100%; padding: 0; border: 0; cursor: pointer; background: var(--forest); }
.um-film img { transition: opacity var(--transition); }
.um-film:hover img { opacity: .85; }
.um-film-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 64px; height: 64px; border-radius: 50%;
  border: 1.5px solid var(--gold); background: rgb(var(--forest-rgb) / 45%);
  display: grid; place-items: center;
}
/* The PNG play mark brings its own ring, drawn at 70% of its box, so the box
   is 142% of the button and the ring lands on the button's edge. */
.um-film-play { border: 0; color: var(--gold); }
.um-film-play .icon { width: 142%; height: 142%; }

/* Three across, matching the chapter's own row above it. It was four while
   each chapter had exactly four photographs to reveal (SPEC.md: the row "has
   nowhere to go on the site", so the count was the files, not a measurement).
   Six per chapter since 19 Sep 2026, and six over four leaves a half row. */
.um-more { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--tile-gap); margin-top: var(--tile-gap); }
.um-more[hidden] { display: none; }
.um-more figure { aspect-ratio: 4 / 5; }

.um-story { position: relative; isolation: isolate; background: #0b0c0b; color: var(--white); }
.um-story-media { position: absolute; inset: 0 43% 0 0; z-index: -2; }
.um-story-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 100%; }
/* Anchored to the bottom (Jacob, 5 Oct 2026: "more of the couple, less head
   space"). The file is a 16:9 still with nothing below their waists, so the
   bottom edge is the most of them there is; the crop comes off the sky. */
.um-story::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgb(11 12 11 / 0%) 30%, rgb(11 12 11 / 70%) 50%, #0b0c0b 58%);
}
.um-story-inner {
  min-height: 338px; margin-left: 59%; padding: 87px var(--gutter) 60px 0;
  display: flex; flex-direction: column; justify-content: center;
}
.um-story .eyebrow { color: var(--white); margin: 0; }
.um-story .eyebrow + .rule { width: 48px; border-top-color: rgb(255 255 255 / 70%); margin: 14px 0 0; }
.um-story blockquote { margin: 32px 0 0; font-family: var(--font-display); font-style: italic; font-size: var(--t-page-h2); line-height: 1.17; text-indent: -0.4em; max-width: 12em; }
.um-story blockquote + .rule { margin: 28px 0 0 26px; }

.um-dialog { width: min(92vw, 960px); max-height: 92vh; padding: 0; border: 0; background: #000; }
.um-dialog::backdrop { background: rgb(var(--forest-rgb) / 88%); }
.um-dialog video { display: block; width: 100%; max-height: 86vh; background: #000; }
.um-dialog-close {
  position: absolute; top: 8px; right: 8px; z-index: 1;
  min-width: 44px; min-height: 44px; border: 0; cursor: pointer;
  background: rgb(var(--forest-rgb) / 70%); color: var(--white);
  font-family: var(--font-body); font-size: var(--t-label); letter-spacing: var(--track-btn); text-transform: uppercase;
}

/* Shared-component variants first used by Locations. */
.page-hero .eyebrow { color: var(--white); margin: 0 0 24px; max-width: none; }
.page-hero h1.page-hero-h1--free { max-width: none; }
.page-intro--center .page-intro-copy { text-align: center; }
.page-intro--center .rule { margin-inline: auto; }
.page-cta-inner > .rule:first-child { margin: 0 0 var(--cta-rule-gap, 33px); }
/* Full-bleed variant: the photograph fills the band and the scrim carries the copy. */
.page-cta--full .page-cta-media { inset: 0; }
.page-cta--full::after { background: linear-gradient(90deg, rgb(var(--forest-rgb) / 82%) 0%, rgb(var(--forest-rgb) / 55%) 38%, rgb(var(--forest-rgb) / 0%) 70%); }

/* =============================================================================
   Page: Locations (locations.html)
   Mockup design/mockup/locations-827.png, read as the 1200 frame, so x1.451.
   Every number is in design/SPEC.md, "Locations".
   ============================================================================= */
.loc {
  /* 548 (the mockup's 378) until 5 Oct 2026, when Jacob found it too short
     and asked for more of the bottom of the photograph: the bouquet and the
     foot of the heart. Taller, and the crop moved down to match. */
  --hero-h:       630px;
  --hero-ratio:   0.525;
  --hero-img-w:   125%;
  --hero-img-pos: 50% 40%;
  --hero-h1-lh:   1.17;    /* pitch 42 -> 61 on 52px */
  /* 52px at the frame, 36px at 390 */
  --t-page-hero: clamp(2.25rem, calc(1.975vw + 1.769rem), 3.25rem);
  --intro-top:    44px;    /* 30  */
  --intro-w:      578px;   /* 398 */
  --cta-inset:    84px;    /* 58  */
}
.loc .page-intro-copy .rule { margin-top: 29px; }
@media (min-width: 961px) { .loc { --hero-img-pos: 50% 58%; } }
.loc .page-hero p { max-width: none; }

/* Venue rows (12 Sep 2026, replacing the mockup's four cards): one row per kind
   of setting, one photograph per venue. The heading keeps the cards' measured
   label - numeral 35, divider, title 29 / sub 16, gaps 41 and 46 - and the
   outer padding keeps the cards' 36 / 42 / 39. Three tiles show across the
   frame; longer rows scroll sideways, with arrows once JS is running. */
.loc-rows { padding: 36px 42px 39px; }
.loc-row + .loc-row { margin-top: 56px; }
.loc-row-head { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; column-gap: var(--gap-2); margin-bottom: 23px; padding-left: 3px; }
.loc-card-num { padding-right: 41px; border-right: 1px solid rgb(200 170 110 / 60%); font-family: var(--font-display); font-size: var(--t-page-h2); line-height: 1; color: var(--gold); font-variant-numeric: lining-nums; }
.loc-card-text { padding-left: 28px; }
.loc-row h2 { font-size: 1.8125rem; line-height: 1.1; }
.loc-card-text p { font-family: var(--font-display); font-size: 1rem; color: var(--muted); margin-top: 6px; }
.loc-row-link {
  font-size: var(--t-label); font-weight: 600; letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--gold); text-decoration: none; padding-block: 12px;
}
.loc-row-link:hover { color: var(--ink); }
.loc-row-nav { display: flex; gap: var(--gap-1); }
.loc-row-nav[hidden] { display: none; }
.loc-row-nav button {
  width: 44px; height: 44px; display: grid; place-items: center; cursor: pointer;
  background: none; border: 1px solid rgb(200 170 110 / 70%); color: var(--gold);
}
.loc-row-nav button:hover:not(:disabled) { background: var(--gold); color: var(--forest); }
.loc-row-nav button:disabled { opacity: .35; cursor: default; }
.loc-row-nav .icon { width: 22px; height: 22px; }
.loc-row-nav button:first-child .icon { transform: scaleX(-1); }

.loc-strip {
  display: grid; grid-auto-flow: column; gap: var(--tile-gap);
  grid-auto-columns: calc((100% - 2 * var(--tile-gap)) / 3);
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  margin: 0; padding: 0 0 var(--gap-1); list-style: none;
  scrollbar-width: thin; scrollbar-color: rgb(200 170 110 / 60%) transparent;
}
.loc-strip li { scroll-snap-align: start; }
.loc-strip img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; background: var(--forest); }

.loc-features { background: var(--ivory); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); padding: 39px var(--gutter) 58px; margin: 0; list-style: none; }
.loc-feature { text-align: center; padding-inline: var(--gap-2); }
.loc-feature + .loc-feature { border-left: 1px solid rgb(200 170 110 / 55%); }
.loc-feature .icon { display: block; width: 45px; height: 45px; margin-inline: auto; color: var(--gold); }
.loc-feature h3 { font-family: var(--font-body); font-size: var(--t-label); font-weight: 600; letter-spacing: var(--track-label); text-transform: uppercase; margin-top: 20px; }
.loc-feature p { font-family: var(--font-display); font-size: 1rem; line-height: 1.625; color: var(--muted); margin: 10px auto 0; max-width: 13rem; }

/* "Not sure where to begin?" and "Choose your backdrop," are the shared CTA.
   Since 5 Oct 2026 Locations ends on one of them, not both (Jacob): the
   backdrop band, the bridge photograph, carrying the "Not sure where to
   begin?" copy. The begin band's waterfront photograph was the home hero's
   scene, and the two stacked bands met with no space between them. */
.loc-begin { --cta-h: 385px; --cta-pad-top: 68px; --cta-pad-bot: 54px; --cta-rule-gap: 33px; --cta-p-gap: 29px; --cta-btn-gap: 33px; }
.loc-begin p { max-width: 25rem; }
.loc-backdrop { --cta-h: 419px; --cta-pad-top: 109px; --cta-pad-bot: 119px; --cta-p-gap: 23px; --cta-btn-gap: 36px; }
/* Top of IMG_1695: the bridge and skyline. The couple are low in the frame and stay out of it. */
/* 62% down keeps the couple and the petal heart whole, with the bridge deck
   still behind them (18 Sep 2026); from the top it showed only their heads. */
.loc-backdrop .page-cta-media img { object-position: 50% 62%; }
.loc-backdrop p { max-width: 25rem; }
.loc-backdrop h2 { font-size: clamp(1.875rem, calc(0.988vw + 1.585rem), 2.4375rem); } /* 27 -> 39, 30 at 390 */
/* The whole photograph, uncropped (Jacob, 5 Oct 2026): on a computer the band
   takes the file's own proportions, 2560 x 1707, so the width decides the
   height and nothing is cut off. Below 961 the copy needs more height than
   that leaves, so a phone keeps the square crop and the 62% position above.
   The copy sits at the top, over the glass tower: centred, it covered the man
   kneeling, who is just left of the middle of the frame. */
@media (min-width: 961px) {
  .loc-backdrop { aspect-ratio: 2560 / 1707; display: flex; flex-direction: column; --cta-pad-top: 64px; }
  .loc-backdrop .page-cta-inner { flex: 1; justify-content: flex-start; }
}

/* =============================================================================
   Page: Videos (videos.html)
   No mockup: added 13 Sep 2026 at Jacob's request. Built only from components
   and values already measured for the other subpages - the shared hero and
   CTA, the chapter numeral and label, the 10px tile gap, and Unscripted
   Moments' play button and film dialog - so nothing here is a new number.
   ============================================================================= */
.vid {
  --hero-h:     502px;    /* Unscripted Moments' band */
  --hero-ratio: 0.4183;
  /* 125% from the left moves the couple out from under the headline (18 Sep 2026). */
  --hero-img-w:   125%;
  --hero-img-pos: 50% 50%;
  --cta-h:      374px;    /* About's closing band */
}
.vid-films { padding: 44px var(--media-inset) 42px; }
.vid-films .rule { margin: 0 auto 44px; }
.vid-feature { margin: 0; }
.vid-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gap-5) var(--tile-gap); margin: var(--gap-5) 0 0; padding: 0; list-style: none; }
/* height:auto overrides .um-film height:100%, which in a grid row would stretch the poster to the tallest caption. */
.vid-film .um-film { aspect-ratio: 16 / 9; height: auto; }
.vid-film .um-film img { width: 100%; height: 100%; object-fit: cover; }
.vid-film figcaption, .vid-caption { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; margin-top: 23px; }
.vid-film h2 { font-size: 1.8125rem; line-height: 1.1; }
.vid-film p { font-family: var(--font-display); font-size: 1rem; color: var(--muted); margin-top: 6px; }
.vid-feature .um-film-play { width: 84px; height: 84px; }
/* An odd film out in the pairs runs the full width, as the first one does,
   rather than sitting beside an empty half (six films since 2 Oct 2026). */
.vid-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
.vid-grid > :last-child:nth-child(odd) .um-film-play { width: 84px; height: 84px; }

/* =============================================================================
   Page: About (about.html)
   Mockup design/mockup/about-827.png, read as the 1200 frame, so x1.451.
   Every number is in design/SPEC.md, "About".
   Words only since 16 Sep 2026: Ariel asked for no photographs of himself, so
   the mockup's portrait, DUMBO band, behind-the-moments tiles and founder
   portrait were removed rather than left waiting. The hero and the founder
   note keep their measured copy columns, centred now that nothing sits
   beside them (MOBILE.md rule 5).
   ============================================================================= */
.ab {
  --intro-top:   57px;    /* 39  */
  --intro-w:     733px;   /* 505 */
  --cta-inset:   86px;    /* 59  */
  --cta-h:       374px;   /* 258 */
  --cta-pad-top: 55px;    /* 38  */
  --cta-pad-bot: 84px;    /* 58  */
  --cta-rule-gap: 29px;   /* 20  */
  --cta-p-gap:   36px;    /* 25  */
  --cta-btn-gap: 29px;    /* 20  */
}
.ab .page-intro-copy .rule { margin-top: 35px; }

.ab-hero { background: var(--forest); color: var(--white); text-align: center; }
.ab-hero-copy { padding: 66px var(--gutter) 60px; display: flex; flex-direction: column; align-items: center; }
.ab-hero .eyebrow { display: flex; align-items: center; justify-content: center; gap: 22px; color: var(--white); margin: 0 0 30px; }
.ab-hero .eyebrow::before, .ab-hero .eyebrow::after { content: ""; width: 55px; border-top: 1px solid var(--gold); }
.ab-hero h1 { font-size: clamp(2.125rem, calc(1.728vw + 1.726rem), 3rem); line-height: 1.15; max-width: 11em; }  /* 48 at the frame, 34 at 390 */
.ab-hero-copy > p:not(.eyebrow) { margin-top: 55px; font-size: 1.0625rem; line-height: 1.65; color: rgb(244 240 231 / 88%); max-width: 451px; }
.ab-values { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 36px 0 0; padding: 0 var(--gutter) 61px; list-style: none; }
.ab-value { text-align: center; padding-inline: var(--gap-3); }
.ab-value + .ab-value { border-left: 1px solid rgb(200 170 110 / 55%); }
.ab-value .icon { display: block; width: 62px; height: 62px; margin-inline: auto; color: var(--gold); }
.ab-value h2 { font-size: clamp(2.125rem, calc(1.235vw + 1.824rem), 2.75rem); margin-top: 23px; }  /* 44 at the frame */
.ab-value p { font-family: var(--font-display); font-size: 1.0625rem; line-height: 1.7; color: var(--muted); margin: 13px auto 0; max-width: 15rem; }

.ab-founder { text-align: center; padding: 51px var(--gutter) 23px; }
.ab-founder h2 { font-size: var(--t-page-h2); }
.ab-founder p { margin: 29px auto 0; max-width: 560px; font-family: var(--font-display); font-size: 1.0625rem; line-height: 1.65; color: var(--ink); }
.ab-founder .ab-signature { font-family: "Pinyon Script", var(--font-display); font-size: 3.4rem; line-height: 1; color: var(--ink); margin-top: 19px; }
.ab-founder .ab-signature + p { margin-top: 15px; font-size: 1.0625rem; }

/* With his portrait (Ariel, 2 Oct 2026: "I want to upload my picture for the
   founder page"). The mockup's founder row, y 1389-1644 (SPEC.md, About):
   portrait 389 beside the note 697, 44 between, 46 in from each side. The
   note keeps its measured copy values and sits left beside the photograph. */
.ab-founder--photo { display: grid; grid-template-columns: 389fr 697fr; column-gap: 44px; align-items: center; text-align: left; padding-inline: 46px; }
.ab-founder-media { aspect-ratio: 389 / 297; overflow: hidden; }
.ab-founder-media img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 15%; }  /* room above his head: the original has 7% over it */
.ab-founder--photo p { margin-inline: 0; }

/* =============================================================================
   Page: /gallery — the photographs of his that are NOT on the site
   Not in either menu and not linked from any page: it exists to be sent to
   Ariel, so that "we did not use this one" arrives as a picture with a reason
   under it. No mockup, so nothing here is a new measurement: the band, the
   container, the heading and the tile gap are the ones every other page uses,
   and the grid is .vid-grid's shape one column wider, because a note is a line
   rather than a title and a subtitle.
   ============================================================================= */
.gal-lead { max-width: 46rem; margin-top: var(--gap-2); color: var(--muted); }
.gal-notes {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap-4) var(--tile-gap);
  margin: var(--gap-4) 0 0; padding: 0; list-style: none;
}
/* contain, not cover, and this is the one page where that is right: he is
   being asked to judge the photograph, so he has to see all of it. A 3:2 frame
   in a 4:5 tile keeps 53% under cover (check:layout, "PHOTOGRAPH STARVED"),
   which on a showcase is a crop and here would be us hiding the evidence. The
   tile keeps its uniform box so the grid still reads as a grid. */
.gal-note figure { margin: 0; aspect-ratio: 4 / 5; overflow: hidden; background: var(--forest); }
.gal-note img { width: 100%; height: 100%; object-fit: contain; }
/* The pictures butt together on the tile gap like every other grid here, but
   10px between two columns of WORDS reads as one paragraph, so the note is
   inset instead of the column being widened. */
.gal-note p { margin-top: var(--gap-2); padding-inline-end: var(--gap-3); font-size: var(--t-body); line-height: 1.55; color: var(--muted); }

/* =============================================================================
   Breakpoints. Three, all declared here, so check:widths and the sweep can read
   them out of the stylesheet rather than being handed a list.
   ============================================================================= */

/* The header menu collapses at 1060, ahead of the page layout at 960: six
   links since Home joined them (18 Sep 2026) push the header button past the
   frame between 961 and 1040. */
@media (max-width: 1060px) {
  .nav-toggle { display: inline-flex; align-items: center; }
  .nav {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--forest);
    padding: var(--gap-2) var(--gutter) var(--gap-4);
    border-top: 1px solid rgb(244 240 231 / 14%);
  }
  .nav[data-open="true"] { display: flex; }
  .nav a { padding-block: var(--gap-2); font-size: var(--t-body); letter-spacing: 0.03em; }
  /* The header stays sticky here too (mobile review, 18 Sep 2026): it used to
     turn static at this width. The open menu scrolls inside what is left of
     the screen, so its last links are never below the fold. */
  .nav { max-height: calc(100dvh - var(--header-h)); overflow-y: auto; overscroll-behavior: contain; }
  .header-cta { display: none; }

  .nav-extra {
    display: grid; gap: var(--gap-2);
    margin-top: var(--gap-2); padding-top: var(--gap-3);
    border-top: 1px solid rgb(244 240 231 / 14%);
  }
  .nav a.nav-cta {
    width: 100%; padding-block: 0;
    font-size: var(--t-label); letter-spacing: var(--track-btn); color: var(--forest);
  }
  .nav a.nav-cta:hover { color: var(--gold); }
  .nav-contact { display: grid; }
  .nav .nav-contact a {
    display: flex; align-items: center; gap: var(--gap-1); min-height: 44px; padding-block: 0;
    font-size: var(--t-label); letter-spacing: 0.05em; color: rgb(244 240 231 / 76%);
  }
  .nav .nav-contact a:hover { color: var(--gold); }
  .nav-contact .icon { width: 25px; height: 25px; flex-shrink: 0; }
}

@media (max-width: 960px) {
  :root { --band-y: 68px; --band-y-sm: 50px; }

  /* Heroes stack: the photograph, then the copy on forest beneath it. Above
     960 the copy covers at most 58% of the home hero's width and 53% of any
     subpage's; below it the home copy passes 60% by 920 and 97% at 600, so the
     scrim ends up darkening the couple instead of framing them. Stacking here
     joins About's hero and every other split, which stack at the same width.
     The photograph's height runs through two anchors so nothing steps at 620:
     16:9 at 960 (540px) and 250px at 390, the middle of the mobile review's
     230-270 (18 Sep 2026; it was 4:3, 292px), i.e. 50.88vw + 51.6px. */
  .hero-media, .page-hero-media { position: relative; inset: auto; z-index: auto; height: calc(50.88vw + 51.6px); }
  .hero::after, .page-hero::after { content: none; }
  .hero-inner, .page-hero-inner { min-height: 0; padding-block: var(--gap-5); }
  .page-hero-media img { width: 100%; }

  .split, .testimonial { grid-template-columns: 1fr; }
  .split--reverse figure { order: -1; }
  .testimonial img { max-width: 320px; }
  .testimonial-quotes { text-align: left; }
  .testimonial-quotes .rule { margin-inline: 0; }

  .cards { grid-template-columns: repeat(2, 1fr); }
  .settings-head { flex-direction: column; align-items: start; gap: var(--gap-2); }

  /* Decor Design: the mosaic's areas stop working below the frame's two-column
     widths, so it becomes a plain two-up grid; everything else keeps ramping. */
  .subpage { --hero-inset: var(--gutter); --media-inset: var(--gutter); --copy-inset: var(--gutter); --cta-inset: var(--gutter); }
  .dd-gallery, .dd-gallery[data-filter] {
    grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; grid-template-areas: none;
    aspect-ratio: auto;
  }
  .dd-gallery { grid-auto-flow: dense; }
  .dd-gallery figure, .dd-gallery figure[data-slot] { grid-area: auto; aspect-ratio: 4 / 5; }
  .dd-gallery figure[data-wide] { grid-column: span 2; aspect-ratio: 16 / 10; }
  .dd-steps { grid-template-columns: 1fr; gap: var(--gap-4); }
  .dd-step, .dd-step + .dd-step { padding: 0; border-left: 0; }
  .dd-step + .dd-step { padding-top: var(--gap-4); border-top: 1px solid rgb(200 170 110 / 45%); }
  .dd-step p { max-width: 34rem; }
  .page-cta-media { inset: 0; }
  .page-cta::after { background: rgb(var(--forest-rgb) / 72%); }

  /* Unscripted Moments: three-across rows become the wide shot over two, and
     the story band's photograph goes behind the quote instead of beside it. */
  .um-row, .um-row--surprise, .um-row--yes, .um-row--celebration {
    grid-template-columns: repeat(2, minmax(0, 1fr)); aspect-ratio: auto;
  }
  .um-row > :first-child { grid-column: span 2; aspect-ratio: 16 / 9; }
  .um-row > :not(:first-child) { aspect-ratio: 4 / 5; }
  .um-more { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .um-chapter-head { padding-inline: 0; }
  .um-chapter-num { padding-right: var(--gap-3); }
  .um-chapter-title { padding-left: var(--gap-3); }
  .um-story-media { inset: 0; }
  .um-story::after { background: rgb(11 12 11 / 70%); }
  .um-story-inner { margin-left: 0; padding: var(--gap-6) var(--gutter); }

  .loc-rows { padding-inline: var(--gutter); }
  .loc-card-num { padding-right: var(--gap-3); }
  .loc-card-text { padding-left: var(--gap-2); }
  /* two and a bit across, so the next venue peeks in and the row reads as scrollable */
  .loc-strip { grid-auto-columns: 42%; }
  .loc-features { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--gap-5); }
  .loc-feature:nth-child(3) { border-left: 0; }
  .page-cta--full::after { background: rgb(var(--forest-rgb) / 66%); }

  .ab-hero-copy { padding: var(--gap-6) var(--gutter) var(--gap-5); }
  /* 44 between stacked values, 21% under the 56 they had (mobile review,
     18 Sep 2026: "20-25%"); the gold divider stays. */
  /* The founder row stacks with the hero (MOBILE.md 5: the note's measured
     column is re-centred now nothing sits beside it). */
  .ab-founder--photo { grid-template-columns: minmax(0, 1fr); row-gap: var(--gap-4); padding-inline: var(--gutter); text-align: center; }
  .ab-founder--photo .ab-founder-media { width: 100%; max-width: 560px; margin-inline: auto; }  /* the note's own measure */
  .ab-founder--photo p { margin-inline: auto; }
  .ab-values { grid-template-columns: 1fr; row-gap: 44px; }
  .ab-value + .ab-value { border-left: 0; border-top: 1px solid rgb(200 170 110 / 55%); padding-top: 44px; }

  .gal-notes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  :root { --gutter: 20px; --band-y: 54px; --band-y-sm: 42px; }

  /* Locations' four features stack as About's values do: two across left
     each line about 15 characters at 360-430 (check:layout, 2 Oct 2026). */
  .loc-features { grid-template-columns: 1fr; row-gap: 44px; }
  .loc-feature + .loc-feature { border-left: 0; border-top: 1px solid rgb(200 170 110 / 55%); padding-top: 44px; }

  .hero-media img { object-position: 72% 52%; }

  /* /gallery goes one-up here, not two: the note under each photograph is the
     point of the page, and two columns at 390 leave it about ten characters
     wide. Nothing shrinks across the breakpoint, only the column count. */
  .gal-notes { grid-template-columns: 1fr; }
  .gal-note p { padding-inline-end: 0; }   /* one column, nothing to separate from */

  .cards, .steps { grid-template-columns: 1fr; }
  .step { padding-left: 0; border-left: 0; padding-top: var(--gap-2); border-top: 1px solid rgb(200 170 110 / 45%); }
  .step:first-child { padding-top: 0; border-top: 0; }

  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }
  .header-logo img { width: 158px; }
  /* The mobile footer, rebuilt (review, 16 Sep 2026, item 8). It was a
     six-link flex pile above a seven-item flex pile, both ragged, 560px tall
     against 309px on desktop. Now five deliberate rows: logo, two-column nav,
     contact, service area, legal. minmax(0, 1fr) rather than 1fr because
     "Unscripted Moments" is wider than half the column and 1fr floors at
     min-content - MOBILE.md rule 4. */
  /* The band's own padding and the rule above the meta were desktop values
     riding down unchanged: 56px top and bottom plus 38+26 above the meta is
     ~120px of the footer's height spent on air, on the screen with least of
     it to spend. */
  .site-footer { padding-block: var(--gap-4); }
  .footer-meta { margin-top: var(--gap-3); padding-top: var(--gap-2); }
  .footer-inner { flex-direction: column; align-items: start; gap: var(--gap-3); }
  .footer-nav {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-2) var(--gap-3); width: 100%;
  }
  .footer-meta { display: grid; gap: var(--gap-2); }
  .footer-contact { display: grid; gap: 6px; }
  .footer-area { display: block; }
  .footer-legal { display: flex; flex-wrap: wrap; gap: 6px var(--gap-3); }
  .footer-social { margin-block: 0; }

  .dd-filter { padding: 0 10px; }
  .page-cta .btn { min-width: 0; width: 100%; }

  .um-chapter-head { grid-template-columns: auto 1fr; row-gap: var(--gap-1); }
  /* margin-left is the gap from the title when the toggle sits BESIDE it; on
     its own row it would just be an indent against nothing. */
  .um-more-toggle { grid-column: 1 / -1; justify-self: start; margin-left: 0; }
  .um-film-play { width: 52px; height: 52px; }

  .vid-grid { grid-template-columns: minmax(0, 1fr); }
  .vid-feature .um-film-play, .vid-grid > :last-child:nth-child(odd) .um-film-play { width: 64px; height: 64px; }
  .loc-row-head { grid-template-columns: auto 1fr; row-gap: var(--gap-1); }
  .loc-row-link { grid-column: 1 / -1; justify-self: start; padding-block: 8px; }
  .loc-row-nav { display: none; }
  .loc-strip { grid-auto-columns: 72%; }

  /* ---------------------------------------------------------------------------
     The mobile review, 18 Sep 2026 (design/BRIEF.md, "Mobile design review").
     Where it names a number, that number is the spec, and each rule says which.
     --------------------------------------------------------------------------- */

  /* Header: 66px (review: 64-68) with a 145px logo, the phone bar hidden and
     its links moved into the menu (header.php). It no longer grows when the
     page scrolls, which is a desktop behaviour. */
  :root { --header-h: 66px; }
  .topbar { display: none; }
  .header-logo img, .site-header.is-scrolled .header-logo img { width: 145px; }
  .site-header.is-scrolled .header-inner { min-height: var(--header-h); }

  /* Hero copy: 36 above, 42 below (review), the buttons 12 apart (was 18). */
  .hero-inner, .page-hero-inner { padding-block: 36px 42px; }
  .hero-actions { gap: 12px; }
  /* Inside the home hero's copy, 20 heading to lead and 28 lead to buttons
     (were 26 and 38), so both buttons reach the first screen with the
     browser's own bars showing. 28 is the review's image-to-copy step. */
  .hero h1 { margin-bottom: 20px; }
  .hero .lead { margin-bottom: 28px; }

  /* Heading to rule, 22 (review: 20-24). A rule placed by its own component
     (the intro's, the films') keeps its value. */
  .rule, .page-hero .rule { margin-block: 22px; }
  .page-cta .rule { margin-top: 22px; }
  .page-cta-inner > .rule:first-child { margin: 0 0 22px; }

  /* Major sections: 52 top and bottom (review: 48-56). The bands through
     --band-y; the page components here, each of which had its own desktop
     value riding down unchanged (78, 64, 61, 44...). */
  :root { --band-y: 52px; --band-y-sm: 48px; }
  .page-intro { padding-top: 48px; }
  .page-cta-inner { min-height: 0; padding-block: 52px; }
  .cta-inner { min-height: 0; padding-block: 52px; }
  .page-head { padding-block: 52px; }
  .ab-hero-copy { padding-block: 52px; }
  .ab-founder { padding-bottom: 0; }
  .ab-values { padding-bottom: 52px; }
  .dd-process { padding-block: 52px; }
  .um-chapters, .vid-films { padding-block: 48px 52px; }
  .loc-rows { padding-block: 48px 52px; }
  .loc-features { padding-block: 48px 52px; }
  .um-story-inner { padding-block: 52px; }

  /* Footer: every link a 44px target (review: 40-44; several were 22). The
     rows lose their gaps, since the targets now carry the space. */
  .footer-nav { row-gap: 0; }
  .footer-nav a, .footer-meta a { display: flex; align-items: center; min-height: 44px; }
  .footer-contact { gap: 0; }
  .footer-legal { gap: 0 var(--gap-3); }

  /* Decor Design: the filters on one row that scrolls, never wrapping; the
     first photograph of whatever is showing full width, and the last one too
     when it would otherwise sit alone (luxe.js marks both). */
  .dd-filters {
    flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto;
    margin: 36px 0 20px; scrollbar-width: none;
  }
  .dd-filters::-webkit-scrollbar { display: none; }
  .dd-filter { flex-shrink: 0; white-space: nowrap; }
  .dd-gallery figure[data-wide] { grid-column: auto; aspect-ratio: 4 / 5; }
  .dd-gallery figure[data-lead] { grid-column: span 2; aspect-ratio: 16 / 10; }

  /* Unscripted Moments: tighter chapter heads, "View moments" on its own row. */
  .um-chapter + .um-chapter { margin-top: 36px; }
  .um-chapter-head { margin-bottom: 16px; padding-inline: 0; }
  .um-chapter-num { padding-right: 14px; }
  .um-chapter-title { padding-left: 14px; }
  .um-chapter-sub { margin-top: 2px; }
  .um-more-toggle { margin-top: 4px; }

  /* Locations: the next card still peeks in; the scrollbar under it goes. */
  .loc-strip { scrollbar-width: none; padding-bottom: 0; }
  .loc-strip::-webkit-scrollbar { display: none; }

  /* Videos: each caption sits closer to its own film than to the next one. */
  .vid-grid { row-gap: 36px; }
  .vid-film figcaption, .vid-caption { margin-top: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; scroll-behavior: auto !important; }
}

/* =============================================================================
   WordPress and Elementor
   -----------------------------------------------------------------------------
   Everything above is the static build's stylesheet, carried over unchanged:
   every widget prints the markup it was measured against. This block only
   takes away what Elementor and WordPress add around that markup, so the
   sections stack exactly as they did in public/.

   Elementor wraps each widget in a container, and a container brings padding
   and a gap between children (10px and 20px by default). Zeroed here at low
   specificity, so a padding Ariel sets on one container in the editor, which
   Elementor writes as `.elementor-123 .elementor-element-abc`, still wins.
   ============================================================================= */
.luxe-main .e-con {
  --padding-top: 0px; --padding-right: 0px; --padding-bottom: 0px; --padding-left: 0px;
  --padding-block-start: 0px; --padding-block-end: 0px; --padding-inline-start: 0px; --padding-inline-end: 0px;
  --margin-top: 0px; --margin-bottom: 0px;
  --gap: 0px; --row-gap: 0px; --column-gap: 0px;
  --widgets-spacing: 0px 0px; --widgets-spacing-row: 0px; --widgets-spacing-column: 0px;
  --container-max-width: 100%; --content-width: 100%;
}
.luxe-main .elementor-widget:not(:last-child) { margin-block-end: 0; }

/* Elementor's reset strips link underlines inside its content. The static
   build underlined running-text links (the Contact page's phone line), and
   buttons and arrow links carry their own decoration. */
.luxe-main .elementor .muted a,
.luxe-main .elementor .legal a { text-decoration: underline; }

/* The dialog lives in <main> but is not part of the page's flow. */
.um-dialog:not([open]) { display: none; }

/* =============================================================================
   The inquiry form (Forminator, Contact page)
   -----------------------------------------------------------------------------
   Forminator is set to "no styles", so it loads none of its own CSS and this
   block draws it. Every value is one the static form in contact.html already
   used (.form-step, .upload, .fine, the buttons) — the form is the same one,
   now one step at a time and wired to an inbox.
   ============================================================================= */
.forminator-ui.forminator-custom-form { font-family: var(--font-body); color: var(--ink); }
.forminator-ui [hidden], .forminator-ui .forminator-hidden { display: none !important; }
.forminator-ui .forminator-response-message[aria-hidden="true"] { display: none; }

/* Progress through the steps: the gold rule each fieldset opened with, filling. */
.forminator-pagination-progress { margin-bottom: var(--gap-4); }
.forminator-progress-label { font-size: var(--t-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--muted); }
/* 4px, not a hairline (mobile review, 18 Sep 2026: "a stronger progress bar"). */
.forminator-progress-bar { height: 4px; margin-top: var(--gap-1); background: rgb(200 170 110 / 25%); }
.forminator-progress-bar span { display: block; height: 4px; background: var(--gold); transition: width var(--transition); }

.form-step-title { font-family: var(--font-display); font-size: var(--t-h3); line-height: var(--lh-tight); margin-bottom: var(--gap-2); }
.forminator-row + .forminator-row { margin-top: var(--gap-2); }

.forminator-ui .forminator-label { display: block; font-size: var(--t-body); }
.forminator-field-radio .forminator-label,
.forminator-field-upload .forminator-label { color: var(--muted); margin-bottom: var(--gap-1); }
.forminator-required { color: var(--gold); }
/* The step heading already asks the question; the label stays for screen readers. */
.luxe-label-hidden .forminator-label {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.forminator-ui .forminator-input,
.forminator-ui .forminator-textarea {
  display: block; width: 100%; max-width: 100%;
  margin-top: var(--gap-1);
  padding: var(--gap-2);
  font-family: var(--font-body); font-size: var(--t-body); color: var(--ink);
  background: var(--white);
  border: 1px solid rgb(95 99 94 / 30%);
  border-radius: 0;
  min-height: 52px;  /* mobile review: fields at least 52 */
}
.forminator-ui .forminator-textarea { resize: vertical; min-height: var(--forminator-textarea-min-height, 140px); }

/* Each choice a bordered tile, the chosen one in gold (mobile review, 18 Sep
   2026). The whole tile is the label, so the whole tile is the target. */
.forminator-ui .forminator-radio {
  display: flex; align-items: center; gap: var(--gap-2); margin-top: var(--gap-1);
  min-height: 52px; padding: 12px var(--gap-2);
  border: 1px solid rgb(95 99 94 / 30%); background: var(--white); cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}
.forminator-ui .forminator-radio:hover { border-color: rgb(200 170 110 / 80%); }
.forminator-ui .forminator-radio:has(input:checked) { border-color: var(--gold); background: rgb(200 170 110 / 12%); }
.forminator-ui .forminator-radio input { accent-color: var(--gold); margin: 0; width: 18px; height: 18px; flex-shrink: 0; }
.forminator-ui .forminator-radio-bullet { display: none; }
.forminator-ui .forminator-description { font-size: var(--t-label); line-height: 1.55; margin-top: var(--gap-3); color: var(--muted); }

.forminator-ui .forminator-multi-upload { margin-top: var(--gap-1); border: 1px dashed rgb(95 99 94 / 40%); padding: var(--gap-3); background: var(--ivory-soft); }
.forminator-ui .forminator-input-file { font-size: var(--t-label); width: 100%; min-width: 0; max-width: 100%; }
.forminator-ui .forminator-uploaded-files { margin-top: var(--gap-1); font-size: var(--t-label); }

.forminator-ui .forminator-error-message { display: block; margin-top: var(--gap-1); font-size: var(--t-label); color: #8a2a1f; }
.forminator-ui .forminator-response-message { margin-bottom: var(--gap-3); padding: var(--gap-2) var(--gap-3); border: var(--rule); background: var(--ivory-soft); }
.forminator-ui .forminator-response-message p { margin: 0; }

/* Back sits before Next, whatever Forminator's inline justify-content says. */
.forminator-ui .forminator-pagination-footer { display: flex; flex-wrap: wrap; gap: var(--gap-2); margin-top: var(--gap-4); justify-content: flex-start !important; }
.forminator-ui .forminator-button {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 52px; padding: 0 var(--gap-4);
  font-family: var(--font-body); font-size: var(--t-label); font-weight: 600;
  letter-spacing: var(--track-btn); text-transform: uppercase; white-space: nowrap;
  border: 1px solid var(--forest); border-radius: 0; cursor: pointer;
  background: var(--forest); color: var(--ivory);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.forminator-ui .forminator-button:hover { background: var(--forest-hover); border-color: var(--forest-hover); }
.forminator-ui .forminator-button-back { background: transparent; color: var(--ink); border-color: rgb(95 99 94 / 40%); }
.forminator-ui .forminator-button-back:hover { background: transparent; border-color: var(--ink); }
.forminator-ui .forminator-button:disabled { opacity: .5; cursor: default; }

@media (max-width: 620px) {
  .forminator-ui .forminator-pagination-footer .forminator-button { flex: 1 1 0; min-width: 0; padding-inline: var(--gap-2); }
  /* Next a little wider than Back (mobile review, 18 Sep 2026). */
  .forminator-ui .forminator-pagination-footer .forminator-button:not(.forminator-button-back) { flex-grow: 1.4; }
}

/* =============================================================================
   Full bleed (5 Oct 2026). Past 1200 only: below it the window is narrower than
   the column and every rule here computes to what it replaced.

   Each section sits in its own Elementor widget wrapper, which is now the full
   window. A section with a ground of its own (a colour band or a photograph)
   stays full width and pads itself in by --bleed, half of whatever the window
   has past 1200, so its content box is the 1200 column and its background is
   the window. Every other section, the transparent ones that sit on the body's
   ivory, is simply capped at 1200 and centred.
   --bleed is written with 100%, and a custom property is substituted before it
   is resolved, so the 100% is the width of whatever uses it: the widget wrapper
   for padding, the section for an absolutely placed photograph or a gradient
   stop. All three are the window, which is the point. --col is the column's
   width in the same terms, for splits and scrim stops measured off the 1200
   frame, so a photograph that began 40% of the way across the column still
   begins there and the scrim stays dark under the copy.
   ============================================================================= */
@media (min-width: 1201px) {
  :root {
    --bleed: max(0px, (100% - var(--content)) / 2);
    --col:   (100% - 2 * var(--bleed));
  }
  .luxe-main > section, .luxe-main .elementor-widget > * { max-width: var(--content); margin-inline: auto; }
  .luxe-main :is(.hero, .band, .cta, .page-head, .page-hero, .page-cta, .ab-hero, .um-story, .loc-features) {
    max-width: none; padding-inline: var(--bleed);
  }
  .luxe-main .loc-features { padding-inline: calc(var(--bleed) + var(--gutter)); }

  /* Splits measured off the frame: the photograph keeps its edge inside the
     column and runs out to the window on its own side. */
  .page-cta:not(.page-cta--full) .page-cta-media { left: calc(var(--bleed) + var(--col) * 0.40); }
  .um-story-media { right: calc(var(--bleed) + var(--col) * 0.43); }
  /* Full bleed made the photograph's box ~3:1 at 1920 against a 16:9 file,
     which left a strip across their heads. Tall enough to show 80% of the
     frame at any width: its box is 50vw + 84px wide (half the column's 57%
     plus the bleed), and 0.45 is 0.8 / (16/9). */
  .um-story-inner { min-height: max(338px, calc((50vw + 84px) * 0.45)); }
  /* The Locations hero keeps growing past 1200, so a wide window does not
     turn it back into a strip (Jacob, 5 Oct 2026: "a bit too short"). The
     125% width moved the couple out from under the headline in a 1200 band;
     full bleed puts the copy in the column and them in the middle already,
     and at 125% a 1920 window showed a third of the photograph. */
  .loc { --hero-img-w: 100%; --hero-img-pos: 50% 70%; }
  .loc .page-hero-inner { min-height: max(var(--hero-h), 40vw); }
  /* Unscripted Moments grows the same way but keeps its 125%: anything
     narrower slides him in under the headline at 1920. */
  .um .page-hero-inner { min-height: max(var(--hero-h), 44vw); }
  /* The home hero likewise: at 660px a 1920 window cut his knee and her
     shoes off the bottom of the photograph (5 Oct 2026). */
  .hero-inner { min-height: max(clamp(500px, 74vh, 660px), 40vw); }

  /* The same scrims, their stops moved from the band onto the column. The part
     of the band left of the column takes the first stop, so the copy's
     contrast is exactly what was measured at 1200. */
  .hero::after {
    background: linear-gradient(100deg,
      rgb(var(--forest-rgb) / 92%) calc(var(--bleed)),
      rgb(var(--forest-rgb) / 78%) calc(var(--bleed) + var(--col) * 0.26),
      rgb(var(--forest-rgb) / 34%) calc(var(--bleed) + var(--col) * 0.52),
      rgb(var(--forest-rgb) / 10%) calc(var(--bleed) + var(--col) * 0.74),
      rgb(var(--forest-rgb) / 0%)  calc(var(--bleed) + var(--col)));
  }
  .page-hero::after {
    background: linear-gradient(95deg,
      rgb(var(--forest-rgb) / 88%) calc(var(--bleed)),
      rgb(var(--forest-rgb) / 70%) calc(var(--bleed) + var(--col) * 0.30),
      rgb(var(--forest-rgb) / 22%) calc(var(--bleed) + var(--col) * 0.55),
      rgb(var(--forest-rgb) / 0%)  calc(var(--bleed) + var(--col) * 0.72));
  }
  .page-cta::after {
    background: linear-gradient(90deg,
      var(--forest) calc(var(--bleed) + var(--col) * 0.40),
      rgb(var(--forest-rgb) / 40%) calc(var(--bleed) + var(--col) * 0.58),
      rgb(var(--forest-rgb) / 0%)  calc(var(--bleed) + var(--col) * 0.80));
  }
  .page-cta--full::after {
    background: linear-gradient(90deg,
      rgb(var(--forest-rgb) / 82%) calc(var(--bleed)),
      rgb(var(--forest-rgb) / 55%) calc(var(--bleed) + var(--col) * 0.38),
      rgb(var(--forest-rgb) / 0%)  calc(var(--bleed) + var(--col) * 0.70));
  }
  .um-story::after {
    background: linear-gradient(90deg,
      rgb(11 12 11 / 0%)  calc(var(--bleed) + var(--col) * 0.30),
      rgb(11 12 11 / 70%) calc(var(--bleed) + var(--col) * 0.50),
      #0b0c0b             calc(var(--bleed) + var(--col) * 0.58));
  }
}
