/* ==========================================================================
   City Sites — Shared Design System
   --------------------------------------------------------------------------
   Warm editorial / organic minimalist. Paper-and-ink rather than screen-glow:
   cream grounds, warm charcoal ink, terracotta accent, hand-drawn line art.

   Contrast note (WCAG 2.1 AA, all values verified):
     ink #191712 on cream ............ 16.62:1
     ink-soft #4A443A on cream ....... 8.95:1
     ink-mute #6B6459 on cream ....... 5.43:1
     terracotta #C0522B on cream ..... 4.35:1  <- LARGE TEXT / UI ONLY
     terracotta-deep #9A3F1E on cream  6.28:1  <- use for small text
     paper #FFF on terracotta ........ 4.68:1
     border-strong #8C7F68 on cream .. 3.64:1  <- meets 3:1 for control edges
   Never set small body copy in --accent on a light ground; use
   --accent-deep. This is why the two tokens exist.
   ========================================================================== */

/* ------------------------------------------------------------------ tokens */
:root {
  /* surfaces */
  --cream:          #FAF6EF;
  --cream-deep:     #F4EEE3;
  --paper:          #FFFFFF;
  --sand:           #EFE6D8;
  --sand-deep:      #E4D8C6;
  --ink:            #191712;
  --ink-raised:     #23201A;

  /* text */
  --ink-strong:     #191712;
  --ink-soft:       #4A443A;
  --ink-mute:       #6B6459;
  --on-dark:        #FAF6EF;
  --on-dark-mute:   #B9AFA0;

  /* accent */
  /* Injected per city by tools/build-city.py from cities/<city>.py.
     Every accent must clear 4.5:1 under white for the button fill. */
  --accent:      #C0522B;
  --accent-deep: #9A3F1E;
  --accent-soft: #E8814F;
  --accent-wash: #F6E7DE;
  --slate:           #2B3844;

  /* lines */
  --border:          #DFD4C2;   /* decorative rules only */
  --border-strong:   #8C7F68;   /* control edges — meets 3:1 */
  --focus:           #9A3F1E;
  --focus-on-dark:   #E8814F;

  /* type */
  --font-display: 'Fraunces', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --font-body:    'Work Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  /* type scale — fluid, 375px → 1440px */
  --step--1: clamp(0.84rem, 0.82rem + 0.10vw, 0.90rem);
  --step-0:  clamp(1.00rem, 0.96rem + 0.18vw, 1.13rem);
  --step-1:  clamp(1.20rem, 1.12rem + 0.35vw, 1.45rem);
  --step-2:  clamp(1.45rem, 1.30rem + 0.65vw, 1.95rem);
  --step-3:  clamp(1.80rem, 1.52rem + 1.20vw, 2.75rem);
  --step-4:  clamp(2.20rem, 1.70rem + 2.15vw, 4.00rem);
  --step-5:  clamp(2.70rem, 1.85rem + 3.60vw, 5.50rem);

  /* spacing — 4/8 rhythm */
  --space-2xs: 0.25rem;  --space-xs: 0.5rem;   --space-sm: 0.75rem;
  --space-md:  1rem;     --space-lg: 1.5rem;   --space-xl: 2rem;
  --space-2xl: 3rem;     --space-3xl: 4rem;    --space-4xl: 6rem;
  --space-5xl: 8rem;

  /* form */
  --radius-xs: 4px;  --radius-sm: 8px;   --radius-md: 14px;
  --radius-lg: 22px; --radius-xl: 32px;  --radius-pill: 999px;

  --shell:      min(1240px, 100% - 2.5rem);
  --shell-text: min(70ch, 100% - 2.5rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur-fast: 140ms;
  --dur:      220ms;
  --dur-slow: 420ms;

  --z-base: 0; --z-raised: 10; --z-sticky: 40; --z-overlay: 100;
}

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

/* The success panel hides the form with `form.hidden = true`, which sets the
   hidden attribute. The browser's own `[hidden] { display: none }` loses to
   any author display rule, and `.form` sets `display: grid` -- so the form
   stayed on screen after a successful submission, still filled in, still
   submittable. A second click meant a duplicate lead. This one line is the
   standard fix and has to outrank every later display rule. */
[hidden] { display: none !important; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Light-only by design. Declared so a visitor whose OS is in dark mode still
     gets light form controls and scrollbars instead of dark browser chrome
     sitting on a cream page. */
  color-scheme: light;
}

/* Removes the ~300ms tap delay on touch. This audience is largely on a phone,
   often one-handed on a job site, so the delay is felt on every tap. */
a, button, summary, label, input, select, textarea, [role='button'] {
  touch-action: manipulation;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink-strong);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Paper grain. Very low opacity — sells "ink on stock" without costing a
   request or hurting text contrast. Sits behind everything, ignores input. */
body::before {
  content: '';
  position: fixed; inset: 0;
  z-index: var(--z-base);
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: no-preference) { }

img, video, svg { max-width: 100%; height: auto; display: block; }
a { color: var(--accent-deep); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--accent); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0 0 var(--space-md);
  color: var(--ink-strong);
  /* Fraunces variable axes: softer terminals, slight "wonk" — the warm,
     mid-century imperfection the brand is built on. */
  font-variation-settings: 'SOFT' 28, 'WONK' 1;
  text-wrap: balance;
}
p { margin: 0 0 var(--space-md); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

/* Long tokens (URLs, IDs) reflow instead of blowing out the layout */
p, li, dd, td, .u-wrap { overflow-wrap: anywhere; }

/* ------------------------------------------------------------ a11y helpers */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; top: 0; left: 50%; transform: translate(-50%, -110%);
  z-index: var(--z-overlay);
  background: var(--ink); color: var(--on-dark);
  padding: var(--space-sm) var(--space-lg);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  font-weight: 600; text-decoration: none;
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: translate(-50%, 0); color: var(--on-dark); }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}
/* Same reason: the focus ring on the CTA button was drawn in --focus
   (the light-background colour) against the dark panel, giving a 2.65:1
   indicator. WCAG 2.2 wants 3:1 for focus indicators. */
.band--ink :where(a, button, summary):focus-visible,
.cta-panel__body :where(a, button, summary):focus-visible { outline-color: var(--focus-on-dark); }

/* ----------------------------------------------------------------- layout */
.shell { width: var(--shell); margin-inline: auto; position: relative; z-index: var(--z-raised); }
.shell--text { width: var(--shell-text); margin-inline: auto; }

.section { padding-block: var(--space-4xl); }
.section--tight { padding-block: var(--space-3xl); }
.section--loose { padding-block: var(--space-5xl); }

.band--cream { background: var(--cream); }
.band--sand  { background: var(--sand); }
.band--paper { background: var(--paper); }
.band--ink   { background: var(--ink); color: var(--on-dark); }
.band--ink :is(h1,h2,h3,h4) { color: var(--on-dark); }
.band--ink p { color: var(--on-dark-mute); }

.stack > * + * { margin-top: var(--space-md); }
.stack-lg > * + * { margin-top: var(--space-xl); }

.grid { display: grid; gap: var(--space-lg); }
/* Grid and flex children default to min-width:auto, and a form control's
   intrinsic size is roughly 20 characters, so an <input> refuses to shrink
   and drags its whole column past a 320px viewport. 375px never shows it,
   which is why this survived every previous pass. */
.grid > *, .field, .input, .select, .textarea { min-width: 0; }
@media (min-width: 700px)  { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 700px)  { .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .grid--3 { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1040px) { .grid--4 { grid-template-columns: repeat(4, 1fr); } }

/* --------------------------------------------------------------- eyebrow */
.eyebrow {
  display: inline-flex; align-items: flex-start; gap: var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin-bottom: var(--space-md);
}
/* flex-start + this offset keeps the rule beside the FIRST line when the
   label wraps, instead of floating between the two lines. */
.eyebrow::before {
  content: ''; width: 28px; height: 1px; background: var(--accent);
  flex: none; margin-top: 0.72em;
}
/* The CTA panel is a dark surface that is NOT inside .band--ink, so these
   on-dark overrides have to name it explicitly. Without this the eyebrow
   rendered deep terracotta on near-black at 2.65:1, well under AA. */
.band--ink .eyebrow,
.cta-panel__body .eyebrow { color: var(--accent-soft); }
.band--ink .eyebrow::before,
.cta-panel__body .eyebrow::before { background: var(--accent-soft); }

.lede { font-size: var(--step-1); line-height: 1.5; color: var(--ink-soft); }
.band--ink .lede { color: var(--on-dark-mute); }
.muted { color: var(--ink-mute); }
.note {
  font-size: var(--step--1); color: var(--ink-mute);
  font-style: italic;
}

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-xs);
  min-height: 48px;                    /* comfortably above the 44px minimum */
  padding: var(--space-sm) var(--space-lg);
  border-radius: var(--radius-pill);
  border: 1.5px solid transparent;
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--accent); color: var(--paper); }
.btn--primary:hover { background: var(--accent-deep); color: var(--paper); }

.btn--ghost {
  background: transparent; color: var(--ink-strong);
  border-color: var(--border-strong);
}
.btn--ghost:hover { background: var(--sand); color: var(--ink-strong); border-color: var(--ink-soft); }

.btn--on-ink { background: var(--cream); color: var(--ink); }
.btn--on-ink:hover { background: var(--accent-soft); color: var(--ink); }

.btn--lg { min-height: 56px; padding: var(--space-md) var(--space-xl); font-size: var(--step-1); }
.btn[disabled], .btn[aria-disabled='true'] { opacity: 0.45; cursor: not-allowed; }
.btn[disabled]:active { transform: none; }

.btn-arrow { width: 1em; height: 1em; flex: none; transition: transform var(--dur) var(--ease); }
.btn:hover .btn-arrow { transform: translateX(3px); }

/* ---------------------------------------------------------------- header */
.site-header {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: color-mix(in srgb, var(--cream) 88%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
@supports not (backdrop-filter: blur(1px)) { .site-header { background: var(--cream); } }

.site-header__inner {
  display: flex; align-items: center; gap: var(--space-lg);
  min-height: 76px;
}
.brand {
  display: inline-flex; align-items: center; gap: var(--space-sm);
  text-decoration: none; color: var(--ink-strong); flex: none;
}
.brand__mark { width: 38px; height: 38px; flex: none; }
.brand__name {
  font-family: var(--font-display);
  font-size: 1.18rem; font-weight: 600; letter-spacing: -0.02em; line-height: 1.05;
  font-variation-settings: 'SOFT' 30, 'WONK' 1;
}
.brand__name span { display: block; font-family: var(--font-body); font-size: 0.62rem;
  font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute); }

/* "Serving <city> and surrounding areas" is long, and the header is a fixed
   row of logo, name and menu button that cannot shrink. At the tracking above
   it needs a 390px viewport, so it overflows a 375px iPhone and a 360px
   Android. Tighten the tracking and cap the width so it wraps to a second line
   instead, rather than shortening the wording or shrinking the type below
   readable: naming the surrounding areas is the whole point of the line. */
@media (max-width: 30rem) {
  .brand__name { max-width: calc(100vw - 118px); }
  .brand__name span { font-size: 0.56rem; letter-spacing: 0.06em; }
}

.site-nav { margin-left: auto; }
.site-nav__list {
  display: flex; align-items: center; gap: var(--space-xs);
  list-style: none; margin: 0; padding: 0;
}
.site-nav__link {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: var(--space-xs) 0.45rem;
  border-radius: var(--radius-sm);
  /* Nine items plus a CTA is a wide bar. Without nowrap the labels break
     mid-word ("Roofi / ng") before the row ever decides to collapse. */
  white-space: nowrap;
  font-size: 0.95rem; font-weight: 500;
  color: var(--ink-soft); text-decoration: none;
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.site-nav__link:hover { color: var(--ink-strong); background: var(--cream-deep); }
.site-nav__link[aria-current='page'] { color: var(--ink-strong); font-weight: 600; }
.site-nav__link[aria-current='page']::after {
  content: ''; position: absolute; margin-top: 2.1em;
  width: 18px; height: 2px; background: var(--accent); border-radius: 2px;
}
.header__cta { flex: none; }

/* mobile nav toggle */
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 48px; height: 48px;
  align-items: center; justify-content: center;
  background: transparent; border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm); cursor: pointer; color: var(--ink-strong);
}
.nav-toggle__bar, .nav-toggle__bar::before, .nav-toggle__bar::after {
  display: block; width: 19px; height: 1.5px; background: currentColor;
  transition: transform var(--dur) var(--ease), opacity var(--dur-fast) var(--ease);
}
.nav-toggle__bar::before, .nav-toggle__bar::after { content: ''; position: absolute; }
.nav-toggle__bar::before { transform: translateY(-6px); }
.nav-toggle__bar::after  { transform: translateY(6px); }
.nav-toggle[aria-expanded='true'] .nav-toggle__bar { background: transparent; }
.nav-toggle[aria-expanded='true'] .nav-toggle__bar::before { transform: rotate(45deg); }
.nav-toggle[aria-expanded='true'] .nav-toggle__bar::after  { transform: rotate(-45deg); }

@media (max-width: 1279px) {
  .nav-toggle { display: inline-flex; }
  .site-nav {
    position: fixed; inset: 76px 0 auto;
    background: var(--cream);
    border-bottom: 1px solid var(--border);
    padding: var(--space-md) 0 var(--space-xl);
    margin-left: 0;
    max-height: calc(100dvh - 76px); overflow-y: auto;
    display: none;
  }
  .site-nav[data-open='true'] { display: block; }
  .site-nav__list { flex-direction: column; align-items: stretch; width: var(--shell); margin-inline: auto; gap: 0; }
  .site-nav__link { min-height: 52px; font-size: 1.05rem; border-bottom: 1px solid var(--border); border-radius: 0; }
  .site-nav__link[aria-current='page']::after { display: none; }
  .site-nav__link[aria-current='page'] { color: var(--accent-deep); }
  .site-nav .btn { margin-top: var(--space-md); width: 100%; }
  .header__cta--desktop { display: none; }
}
@media (min-width: 1280px) {
  .site-nav .btn { display: none; }
  /* Nine destinations plus a CTA will not fit a single row. "Home" is the
     one that is genuinely redundant here, because the logo already goes
     home, so it is dropped from the bar and kept in the mobile drawer. */
  .site-nav__item--home { display: none; }
}

/* ------------------------------------------------------------------- hero */
.hero { padding-top: var(--space-xl); padding-bottom: var(--space-3xl); }

/* Scroll-scrub track. Its extra height IS the scrub distance: the frame
   sticks to the top while the page moves through the remaining ~110vh, and
   that progress drives video.currentTime. The headline and CTA stay on
   screen throughout, so the effect costs nothing in conversion terms.
   Only applied once JS confirms it can drive the video — see .js-scrub. */
.hero__track { position: relative; }
.hero__sticky { position: relative; }

.js-scrub .hero[data-hero-scrub] .hero__track { height: 150vh; }
/* 150vh means the scrub completes in half a screen of scrolling. Longer
   tracks turn the hero into a scroll trap — you cannot reach the rest of
   the page until the clip has run out. Keep this modest. */
.js-scrub .hero[data-hero-scrub] .hero__sticky {
  position: sticky;
  top: 76px;                       /* clears the sticky site header */
  height: calc(100vh - 76px);
  display: flex; align-items: center;
}
.js-scrub .hero[data-hero-scrub] .hero__frame { width: 100%; min-height: 0; height: min(78vh, 760px); }

/* The video stacks over the poster once it can render; until then the poster
   is what the reader sees, which keeps the largest paint fast. */
.hero__video { opacity: 0; transition: opacity var(--dur-slow) var(--ease); }
.hero__video[data-ready='true'] { opacity: 1; }
/* The frame sizes to its content with a min-height floor, so long headlines
   at narrow widths push it taller instead of spilling out of a fixed ratio. */
.hero__frame {
  position: relative;
  display: grid;
  align-items: end;
  min-height: clamp(480px, 74vh, 760px);
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--ink);
  isolation: isolate;
}

.hero__media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: -2;
}
/* Two scrims: a vertical one for the whole frame, and a horizontal one that
   anchors the left-aligned copy. Without the second, the eyebrow and subtext
   lose contrast wherever the photo is brightest. */
.hero__scrim {
  position: absolute; inset: 0;
  z-index: -1;
  /* Two gradients that MULTIPLY. Tuned so the bottom-left, where the headline
     sits, lands near 80% darkening for white text, while the top right stays
     light enough that the photograph is still a photograph. The previous
     values multiplied out to about 96% bottom-left and 52% at the top, which
     was survivable over a dark roof photo and turned a bright, sunny one into
     a black rectangle. */
  background:
    linear-gradient(90deg, rgba(15,13,10,0.66) 0%, rgba(15,13,10,0.38) 40%, rgba(15,13,10,0) 70%),
    linear-gradient(180deg, rgba(15,13,10,0.10) 0%, rgba(15,13,10,0.05) 30%, rgba(15,13,10,0.46) 100%);
}
/* Narrow screens put the copy over most of the frame, so the scrim darkens
   earlier rather than clearing in the middle. Lightened along with the wide
   version above: at 0.88 the bottom was effectively opaque, which was fine
   over a dark roof photograph and turned a bright sunny one into a black
   rectangle. The text shadows carry the difference. */
@media (max-width: 700px) {
  .hero__scrim {
    background: linear-gradient(180deg,
      rgba(15,13,10,0.20) 0%, rgba(15,13,10,0.34) 30%, rgba(15,13,10,0.74) 100%);
  }
  /* CROP THE PHOTOGRAPH TOWARD ITS SUBJECT.
     The photo is 1376x768 landscape; a phone frame is portrait, so `cover`
     scales to HEIGHT and only about 30% of the image width survives. Where
     that 30% window sits is therefore the whole composition:

       50% (the default) shows 35-65% — empty driveway, technician off frame
       64% (chosen)      shows 45-75% — technician at the right, text clear
       72%               shows 50-80% — technician centred, text over his body

     The technician's head sits at roughly 68-73% across, so 64% lands him
     just inside the right edge and leaves the darker house and planting on
     the left for the headline to sit on.

     The vertical value is inert here and kept only for readability: the scale
     is height-driven, so the full height of the photograph is always shown. */
  .hero__media { object-position: 64% 50%; }
}
.hero__content {
  position: relative;
  padding: var(--space-xl) var(--space-lg) var(--space-xl);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-md);
}
@media (min-width: 900px) { .hero__content { padding: var(--space-2xl); max-width: 62ch; } }
/* The title and sub both carry text-shadows to survive a bright photograph;
   the eyebrow was left without one, which is why it washed out over the pale
   stucco and palm fronds at the top of the frame. Same treatment, tighter
   radius because the type is small and letterspaced. */
.hero__content .eyebrow {
  color: var(--accent-soft); margin-bottom: 0;
  text-shadow: 0 1px 10px rgba(0,0,0,0.70), 0 1px 3px rgba(0,0,0,0.45);
}
.hero__content .eyebrow::before { background: var(--accent-soft); }
/* The shadows carry more of the legibility now that the scrim is lighter.
   Darkening text locally beats darkening the whole photograph, and the end of
   the third sub-line reaches past where the side gradient has faded out. */
.hero__title {
  font-size: var(--step-4); color: var(--cream); margin: 0;
  text-shadow: 0 2px 24px rgba(0,0,0,0.55), 0 1px 4px rgba(0,0,0,0.35);
}
.hero__sub { color: #EDE6DA; font-size: var(--step-1); margin: 0; max-width: 54ch;
  text-shadow: 0 1px 14px rgba(0,0,0,0.62), 0 1px 3px rgba(0,0,0,0.38); }

/* statement — the big editorial paragraph */
.statement {
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.28;
  letter-spacing: -0.015em;
  font-weight: 400;
  font-variation-settings: 'SOFT' 34, 'WONK' 1;
  color: var(--ink-mute);
  text-align: center;
  max-width: 26ch;
  margin-inline: auto;
  text-wrap: balance;
}
.statement strong { color: var(--ink-strong); font-weight: 600; }
.statement em { font-style: normal; color: var(--accent-deep); }
@media (min-width: 700px) { .statement { max-width: 30ch; } }

/* ------------------------------------------------------------ bleed band
   Full-width photographic break between two text-heavy sections. */
.bleed {
  position: relative;
  isolation: isolate;
  min-height: clamp(340px, 52vh, 560px);
  display: grid;
  align-items: end;
  background: var(--ink);
  overflow: hidden;
}
.bleed__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  z-index: -2;
}
/* Two gradients, same reasoning as the hero: the vertical one alone leaves
   the left-aligned copy sitting over bright stucco with too little contrast. */
.bleed__overlay {
  position: absolute; inset: 0;
  z-index: -1;
  background:
    linear-gradient(90deg, rgba(15,13,10,0.78) 0%, rgba(15,13,10,0.40) 45%, rgba(15,13,10,0) 75%),
    linear-gradient(180deg, rgba(15,13,10,0.24) 0%, rgba(15,13,10,0.12) 35%, rgba(15,13,10,0.72) 100%);
}
@media (max-width: 700px) {
  .bleed__overlay {
    background: linear-gradient(180deg, rgba(15,13,10,0.38) 0%, rgba(15,13,10,0.55) 40%, rgba(15,13,10,0.85) 100%);
  }
}
.bleed__content { padding-block: var(--space-2xl); }
.bleed__content .eyebrow { color: var(--accent-soft); }
.bleed__content .eyebrow::before { background: var(--accent-soft); }
.bleed__title {
  font-size: var(--step-3); color: var(--cream); margin-bottom: var(--space-xs);
  max-width: 20ch; text-shadow: 0 2px 20px rgba(0,0,0,0.4);
}
.bleed__text {
  color: #E4DCCF; max-width: 52ch; margin: 0;
  text-shadow: 0 1px 12px rgba(0,0,0,0.5);
}

/* ------------------------------------------------------------------ cards */
.card {
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.card--flat { background: var(--cream-deep); border-color: transparent; }
.card__title { font-size: var(--step-1); margin-bottom: var(--space-xs); }
.card__body { color: var(--ink-soft); font-size: 0.98rem; margin: 0; }

/* numbered step card */
.step { position: relative; padding-top: var(--space-xl); }
.step__num {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-variation-settings: 'SOFT' 30, 'WONK' 1;
  color: var(--accent);
  line-height: 1;
  display: block;
  margin-bottom: var(--space-sm);
}
.step__rule { height: 1px; background: var(--border); margin-bottom: var(--space-md); }

/* ---------------------------------------------------------- service list */
.service-list { display: grid; gap: var(--space-sm); }
.service-item {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--paper);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.service-item[open] { border-color: var(--ink); background: var(--ink); }
.service-item__summary {
  display: flex; align-items: center; gap: var(--space-md);
  min-height: 68px; padding: var(--space-md) var(--space-lg);
  cursor: pointer; list-style: none;
  font-family: var(--font-display);
  font-size: var(--step-1); font-weight: 600;
  font-variation-settings: 'SOFT' 28, 'WONK' 1;
  color: var(--ink-strong);
}
.service-item__summary::-webkit-details-marker { display: none; }
.service-item[open] .service-item__summary { color: var(--on-dark); }
.service-item__icon {
  margin-left: auto; flex: none;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--sand); color: var(--ink-strong);
  transition: background-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              transform var(--dur) var(--ease);
}
.service-item[open] .service-item__icon {
  background: var(--accent); color: var(--paper); transform: rotate(45deg);
}
.service-item__panel { padding: 0 var(--space-lg) var(--space-lg); }
.service-item[open] .service-item__panel { color: var(--on-dark-mute); }
.service-item__panel p { max-width: 62ch; }
.service-item__figure {
  margin: var(--space-md) 0 0;
  border-radius: var(--radius-sm); overflow: hidden;
  background: var(--cream);
}
.service-item__figure img { width: 100%; }

/* ------------------------------------------------------------------ cities */
.city-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-xs); }
.city-item {
  display: flex; align-items: baseline; gap: var(--space-md);
  padding: var(--space-md) 0;
  border-bottom: 1px solid var(--border);
}
.city-item__name {
  font-family: var(--font-display); font-size: var(--step-2); font-weight: 600;
  font-variation-settings: 'SOFT' 28, 'WONK' 1;
  letter-spacing: -0.02em;
}
.city-item__note { margin-left: auto; font-size: var(--step--1); color: var(--ink-mute); text-align: right; }

/* --------------------------------------------------------------- gallery */
.gallery { display: grid; gap: var(--space-md); }
@media (min-width: 760px) {
  .gallery { grid-template-columns: repeat(6, 1fr); grid-auto-rows: 180px; }
  .gallery__item--wide  { grid-column: span 4; grid-row: span 2; }
  .gallery__item--tall  { grid-column: span 2; grid-row: span 2; }
  .gallery__item--third { grid-column: span 2; grid-row: span 1; }
}
.gallery__item {
  position: relative; overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--sand);
  min-height: 180px;
}
.gallery__item img { width: 100%; height: 100%; object-fit: cover; }
.gallery__caption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--space-lg) var(--space-md) var(--space-md);
  background: linear-gradient(180deg, transparent, rgba(15,13,10,0.82));
  color: var(--cream);
}
.gallery__caption strong { display: block; font-family: var(--font-display); font-size: var(--step-1);
  font-variation-settings: 'SOFT' 28, 'WONK' 1; }
.gallery__caption span { font-size: var(--step--1); color: #D9D0C2; }

/* -------------------------------------------------------------- FAQ block */
.faq { display: grid; gap: var(--space-xs); }
.faq__item {
  border-bottom: 1px solid var(--border);
  background: transparent;
}
.faq__summary {
  display: flex; align-items: flex-start; gap: var(--space-md);
  padding: var(--space-lg) 0;
  min-height: 44px;
  cursor: pointer; list-style: none;
  font-family: var(--font-display);
  font-size: var(--step-1); font-weight: 600; line-height: 1.3;
  font-variation-settings: 'SOFT' 28, 'WONK' 1;
  color: var(--ink-strong);
  transition: color var(--dur) var(--ease);
}
.faq__summary:hover { color: var(--accent-deep); }
.faq__summary::-webkit-details-marker { display: none; }
.faq__sign {
  margin-left: auto; flex: none; width: 26px; height: 26px; margin-top: 3px;
  position: relative; color: var(--accent);
}
.faq__sign::before, .faq__sign::after {
  content: ''; position: absolute; inset: 50% 0 auto; height: 1.5px;
  background: currentColor; transition: transform var(--dur) var(--ease);
}
.faq__sign::after { transform: rotate(90deg); }
.faq__item[open] .faq__sign::after { transform: rotate(0deg); }
.faq__panel { padding: 0 3rem var(--space-lg) 0; color: var(--ink-soft); max-width: 74ch; }
.faq__panel ul { margin: var(--space-sm) 0 0; padding-left: 1.15rem; }
.faq__panel li { margin-bottom: var(--space-xs); }

/* ------------------------------------------------------------------ forms */
.form { display: grid; gap: var(--space-lg); }
.field { display: grid; gap: var(--space-xs); }
.field__label { font-weight: 600; font-size: 0.95rem; color: var(--ink-strong); }
.field__req { color: var(--accent-deep); margin-left: 2px; }
.field__hint { font-size: var(--step--1); color: var(--ink-mute); }

.input, .select, .textarea {
  width: 100%;
  min-height: 52px;                       /* touch-friendly */
  padding: var(--space-sm) var(--space-md);
  font-family: var(--font-body);
  font-size: 1rem;                        /* >=16px prevents iOS zoom-on-focus */
  color: var(--ink-strong);
  background: var(--paper);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.textarea { min-height: 128px; padding-top: var(--space-md); resize: vertical; line-height: 1.6; }
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%234A443A' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-md) center;
  padding-right: var(--space-2xl);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-soft); }
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--accent-deep);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
.input[aria-invalid='true'], .select[aria-invalid='true'], .textarea[aria-invalid='true'] {
  border-color: #B3261E;
}
.input[aria-invalid='true']:focus { box-shadow: 0 0 0 3px #F7DEDC; }

.field__error {
  display: none;
  align-items: flex-start; gap: 6px;
  font-size: var(--step--1); font-weight: 500; color: #8C1D18;
}
.field__error[data-show='true'] { display: flex; }
.field__error svg { flex: none; width: 15px; height: 15px; margin-top: 2px; }

/* checkbox group */
.checks { display: grid; gap: var(--space-xs); }
@media (min-width: 560px) { .checks { grid-template-columns: repeat(2, 1fr); } }
.check {
  display: flex; align-items: center; gap: var(--space-sm);
  min-height: 48px; padding: var(--space-xs) var(--space-md);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--paper);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.check:hover { border-color: var(--ink-soft); background: var(--cream); }
.check:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }
.check:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
.check input { width: 20px; height: 20px; accent-color: var(--accent); flex: none; margin: 0; }
.check span { font-size: 0.95rem; }

fieldset { border: 0; margin: 0; padding: 0; }
legend { padding: 0; font-weight: 600; font-size: 0.95rem; margin-bottom: var(--space-xs); }

/* honeypot — hidden from humans, visible to naive bots */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* error summary */
.form-summary {
  display: none;
  border: 1.5px solid #B3261E; background: #FCEEEC;
  border-radius: var(--radius-sm); padding: var(--space-md) var(--space-lg);
}
.form-summary[data-show='true'] { display: block; }
.form-summary h3 { font-family: var(--font-body); font-size: 1rem; color: #8C1D18; margin-bottom: var(--space-xs); }
.form-summary ul { margin: 0; padding-left: 1.1rem; }
.form-summary a { color: #8C1D18; font-size: 0.95rem; }

/* success state */
.form-success {
  display: none;
  text-align: center;
  padding: var(--space-3xl) var(--space-xl);
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.form-success[data-show='true'] { display: block; }
.form-success__mark {
  width: 68px; height: 68px; border-radius: 50%;
  background: var(--accent-wash); color: var(--accent-deep);
  display: grid; place-items: center; margin: 0 auto var(--space-lg);
}
.form-status { font-size: var(--step--1); color: var(--ink-mute); text-align: center; }

/* ------------------------------------------------------------------- CTA */
.cta-panel {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--ink);
  display: grid;
}
@media (min-width: 860px) { .cta-panel { grid-template-columns: 1.05fr 1fr; } }
.cta-panel__body { padding: var(--space-2xl); display: flex; flex-direction: column;
  justify-content: center; gap: var(--space-md); align-items: flex-start; }
@media (min-width: 860px) { .cta-panel__body { padding: var(--space-3xl); } }
.cta-panel__title { font-size: var(--step-3); color: var(--cream); margin: 0; }
.cta-panel__text { color: var(--on-dark-mute); margin: 0; max-width: 46ch; }
.cta-panel__media { position: relative; min-height: 260px; }
.cta-panel__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* ---------------------------------------------------------------- footer */
.site-footer { background: var(--ink); color: var(--on-dark-mute); padding-block: var(--space-3xl) var(--space-xl); }
/* WCAG 2.2 asks for a 24x24 CSS px pointer target. The legal and email
   links sat at 18-23px tall, so give them vertical padding rather than
   changing the type size. */
.site-footer a { color: var(--on-dark-mute); text-decoration: none;
  display: inline-block; padding-block: 3px; }
.site-footer a:hover { color: var(--accent-soft); }
.footer__grid { display: grid; gap: var(--space-2xl); }
/* Grid items default to min-width:auto, so a column refuses to shrink below
   its own min-content. At 320px that pushed the footer 20px wider than the
   viewport and scrolled the whole page sideways. 375px never showed it. */
.footer__grid > * { min-width: 0; }
@media (min-width: 760px)  { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 1040px) { .footer__grid { grid-template-columns: 1.5fr 1fr 1fr 1.3fr; } }
.footer__brand { display: inline-flex; align-items: center; gap: var(--space-sm); margin-bottom: var(--space-md); }
.footer__brand img { width: 40px; height: 40px; }
.footer__brand span { font-family: var(--font-display); font-size: 1.2rem; font-weight: 600;
  color: var(--cream); font-variation-settings: 'SOFT' 30, 'WONK' 1; }
.footer__heading {
  font-family: var(--font-body); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.15em; text-transform: uppercase; color: var(--cream);
  margin-bottom: var(--space-md);
}
.footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-xs); }
.footer__list a { display: inline-flex; min-height: 32px; align-items: center; font-size: 0.95rem; }
.footer__phone {
  font-family: var(--font-display); font-size: var(--step-1); color: var(--cream) !important;
  font-variation-settings: 'SOFT' 28, 'WONK' 1;
}
.footer__map {
  border-radius: var(--radius-md); overflow: hidden; border: 1px solid #34302A;
  aspect-ratio: 16 / 10; background: #221F1A;
  /* The embed is fixed at zoom 9, which covers ~51km of latitude at 200px
     tall, so below about 160px it starts cropping the end markets off.
     This floor keeps Murrieta, Temecula and Menifee in frame. */
  min-height: 200px;
  /* min-height and aspect-ratio together were driving the WIDTH to 320px
     (200 x 1.6), which is wider than the content box on a 320px phone and
     scrolled every page sideways. The ratio gives way, the floor holds. */
  max-width: 100%;
}
.footer__map iframe { width: 100%; height: 100%; border: 0; display: block; filter: grayscale(0.35) contrast(0.95); }
.footer__base {
  margin-top: var(--space-2xl); padding-top: var(--space-lg);
  border-top: 1px solid #34302A;
  display: flex; flex-wrap: wrap; gap: var(--space-md) var(--space-xl);
  align-items: center; font-size: 0.86rem;
}
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--space-lg); margin-left: auto; }

/* ------------------------------------------------------------ page header */
.page-head { padding-block: var(--space-3xl) var(--space-2xl); border-bottom: 1px solid var(--border); }
.page-head__title { font-size: var(--step-4); margin-bottom: var(--space-md); }
.page-head__lede { font-size: var(--step-1); color: var(--ink-soft); max-width: 60ch; margin: 0; }

.breadcrumb { display: flex; gap: var(--space-xs); align-items: center;
  font-size: var(--step--1); color: var(--ink-mute); margin-bottom: var(--space-lg); list-style: none; padding: 0; }
.breadcrumb a { color: var(--ink-mute); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent-deep); text-decoration: underline; }
.breadcrumb li { display: flex; gap: var(--space-xs); align-items: center; }
.breadcrumb li + li::before { content: '/'; color: var(--border-strong); }

/* --------------------------------------------------------------- prose */
.prose h2 { font-size: var(--step-2); margin-top: var(--space-2xl); }
.prose h3 { font-size: var(--step-1); margin-top: var(--space-xl); }
.prose > :first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.3rem; margin-bottom: var(--space-md); color: var(--ink-soft); }
.prose li { margin-bottom: var(--space-xs); }
.prose p { color: var(--ink-soft); }

/* ------------------------------------------------------------- animation */
/* Scroll reveals are opt-IN, gated on the .js-reveal class that site.js puts
   on <html>. Content is therefore fully visible by default — with JavaScript
   disabled, blocked, or broken, nothing is hidden. Never make the readability
   of the page depend on a script running. */
@media (prefers-reduced-motion: no-preference) {
  .js-reveal [data-reveal]:not(.is-in) { opacity: 0; transform: translateY(18px); }
  .js-reveal [data-reveal] {
    transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
  }
  .js-reveal [data-reveal].is-in:nth-child(2) { transition-delay: 60ms; }
  .js-reveal [data-reveal].is-in:nth-child(3) { transition-delay: 120ms; }
  .js-reveal [data-reveal].is-in:nth-child(4) { transition-delay: 180ms; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------------ print */
@media print {
  body::before, .site-header, .nav-toggle, .cta-panel { display: none !important; }
  body { background: #fff; color: #000; }
  .section { padding-block: 1rem; }
}

/* ========================================================= CITY SITE ONLY
   Components specific to the homeowner-facing city sites. Built from the
   same tokens as everything above — the only per-city variance is --accent. */

/* ------------------------------------------------------------ service card */
.svc {
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.svc:hover { border-color: var(--border-strong); }
.svc__media { aspect-ratio: 16 / 10; background: var(--cream); overflow: hidden; }
.svc__media img { width: 100%; height: 100%; object-fit: cover; }
.svc__body { padding: var(--space-xl); display: flex; flex-direction: column; flex: 1; }
.svc__name { font-size: var(--step-1); margin-bottom: var(--space-xs); }
.svc__blurb { color: var(--ink-soft); font-size: 0.97rem; margin-bottom: var(--space-lg); }
.svc__links { margin-top: auto; display: flex; flex-wrap: wrap; gap: var(--space-sm); }
.svc__links .btn { flex: 1 1 auto; min-width: 0; }

/* --------------------------------------------------------- local knowledge */
.local { display: grid; gap: var(--space-2xl); }
@media (min-width: 900px) { .local { grid-template-columns: 1.1fr 1fr; } }

.hoods { display: flex; flex-wrap: wrap; gap: var(--space-xs); list-style: none; margin: 0; padding: 0; }
.hoods li {
  font-size: 0.9rem; color: var(--ink-soft);
  background: var(--paper); border: 1px solid var(--border);
  padding: 6px 12px; border-radius: var(--radius-pill);
}

.season { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-md); }
.season li {
  display: grid; gap: var(--space-2xs);
  padding-left: var(--space-md);
  border-left: 3px solid var(--accent);
}
.season__when {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--accent-deep);
}
.season__what { color: var(--ink-soft); font-size: 0.95rem; margin: 0; }

/* --------------------------------------------------------- work checklist */
.worklist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-sm); }
@media (min-width: 620px) { .worklist { grid-template-columns: repeat(2, 1fr); } }
.worklist li {
  display: flex; gap: var(--space-sm); align-items: flex-start;
  color: var(--ink-soft); font-size: 0.96rem; line-height: 1.45;
}
.worklist svg { flex: none; width: 16px; height: 16px; margin-top: 4px; color: var(--accent); }

/* ------------------------------------------------------ featured partner */
.partner-empty {
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-2xl);
  text-align: center;
  background: var(--cream-deep);
}
.partner-empty p { color: var(--ink-mute); max-width: 48ch; margin-inline: auto; }

/* ----------------------------------------------------------- blog listing */
/* auto-fit rather than a fixed column count: one article looks deliberate,
   two sit side by side, three or more wrap without the template changing. */
.posts { display: grid; gap: var(--space-lg); }
@media (min-width: 760px) {
  .posts { grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
}
.post-card {
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--space-xl);
}
.post-card__meta {
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--accent-deep);
  margin-bottom: var(--space-sm);
}
.post-card__title { font-size: var(--step-1); margin-bottom: var(--space-xs); }
.post-card__title a { color: inherit; text-decoration: none; }
.post-card__title a:hover { color: var(--accent-deep); text-decoration: underline; }
.post-card__excerpt { color: var(--ink-soft); font-size: 0.96rem; margin-bottom: var(--space-lg); }
.post-card a.btn { margin-top: auto; align-self: flex-start; }

/* --------------------------------------------------------------- article */
.article { max-width: 72ch; margin-inline: auto; }
.article h2 { font-size: var(--step-2); margin-top: var(--space-2xl); }
.article h3 { font-size: var(--step-1); margin-top: var(--space-xl); }
.article > :first-child { margin-top: 0; }
.article p, .article li { color: var(--ink-soft); }
.article ul, .article ol { padding-left: 1.3rem; margin-bottom: var(--space-md); }
.article li { margin-bottom: var(--space-xs); }
.article__meta {
  display: flex; flex-wrap: wrap; gap: var(--space-md);
  font-size: var(--step--1); color: var(--ink-mute);
  padding-bottom: var(--space-lg); margin-bottom: var(--space-xl);
  border-bottom: 1px solid var(--border);
}
.article__sources {
  margin-top: var(--space-3xl); padding-top: var(--space-lg);
  border-top: 1px solid var(--border);
  font-size: var(--step--1);
}
/* The one place an article asks for anything. Set apart so it reads as an
   offer rather than as another paragraph of the piece. */
.article__cta {
  margin-top: var(--space-2xl);
  padding: var(--space-lg) var(--space-xl);
  background: var(--accent-wash);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
}
.article__cta { color: var(--ink-strong) !important; }

.article__sources ol { padding-left: 1.2rem; }
.article__sources li { margin-bottom: var(--space-xs); overflow-wrap: anywhere; }

/* ------------------------------------------------------------ trust strip */
.trust {
  display: flex; flex-wrap: wrap; gap: var(--space-md) var(--space-2xl);
  align-items: center; justify-content: center;
  padding: var(--space-lg); border-radius: var(--radius-md);
  background: var(--cream-deep);
}
.trust span {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  font-size: 0.93rem; font-weight: 500; color: var(--ink-soft);
}
.trust svg { width: 17px; height: 17px; color: var(--accent); flex: none; }
/* On a phone the three items each wrap onto their own line, and `justify-content:
   center` then centres every line INDEPENDENTLY. Three labels of different
   lengths therefore get three different left edges, which reads as broken
   rather than as centred. Stack them against one shared edge instead.
   The third label also wraps to two lines; centring its icon against a
   two-line block leaves it sitting lower than the icons above it, so pin the
   icon to the first line and nudge it onto the cap height. */
@media (max-width: 40rem) {
  .trust {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: var(--space-sm);
  }
  .trust span { align-items: flex-start; }
  .trust svg { margin-top: 0.15em; }
}

/* ------------------------------------------------------- consent checkbox */
/* Deliberately quiet. It is an opt-in, not a call to action, and the wording
   is legally required rather than persuasive, so it should read as fine print
   without being unreadable: 0.88rem at 8.95:1 on cream. */
.field--consent { margin-top: calc(var(--space-md) * -0.25); }
.check--consent {
  display: flex; gap: var(--space-sm); align-items: flex-start;
  padding: var(--space-md);
  background: var(--cream-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.check--consent input { margin-top: 0.2rem; flex: none; width: 18px; height: 18px; accent-color: var(--accent); }
.check--consent span { font-size: 0.88rem; line-height: 1.55; color: var(--ink-soft); }
.check--consent:hover { border-color: var(--border-strong); }

/* Below 380px the header runs out of room: brand + gap + toggle exceeds the
   shell, which pushed the menu button off the right edge and scrolled every
   page sideways. The tagline under the wordmark is the widest and least
   load-bearing part of the lockup, so it is what gives way. The site name
   and the menu button both stay. */
@media (max-width: 380px) {
  .brand, .brand__name { min-width: 0; }
  .brand__name > span { display: none; }
}
