/* Herriman Handyman Co. brand + layout
   Palette: navy #0D4B72, orange #D85F18, bone #FBF7EE, sampled from the client's logo. */

:root {
  /* Palette taken from the client's logo (navy wordmark + orange "HOME SERVICE"),
     2026-09-24. It previously ran on Herriman's navy + gold, which is a different
     client's brand and clashed with this one's own logo.

     Three oranges, not one, because the brand orange is too light to carry small text:
       --accent      #D85F18, the logo orange exactly. Surfaces, bars, borders. White on
                     it is only 3.77:1, so it must never carry small text.
       --accent-600  the logo orange darkened 10%. Button backgrounds: white on it is
                     4.53:1, which passes AA at the 16px bold the buttons actually use.
                     16px bold is NOT "large text" under WCAG, so the raw orange fails.
       --accent-700  darkened 14%. Small text on bone: 4.56:1.
     Both derived by darkening the real orange in even steps until the ratio was met,
     so they stay recognisably the brand colour rather than being picked by eye.
     The old gold eyebrow was 2.34:1, which failed AA outright, so this is a fix as
     well as a rebrand. */
  --navy: #0D4B72;
  --navy-700: #093A5A;
  --navy-500: #1A6A9E;
  --accent: #D85F18;
  --accent-600: #C25616;
  --accent-700: #BA5215;
  --bone: #FBF7EE;
  --white: #FFFFFF;
  --ink: #0D4B72;
  --body: #3B4759;
  --muted: #6B7688;
  --line: #E7E3DA;
  --ok: #187A3C;
  --ok-bg: #E9F6EE;
  --err: #B42318;
  --radius: 14px;
  --radius-sm: 9px;
  --shadow-sm: 0 1px 2px rgba(20,38,75,.06), 0 2px 8px rgba(20,38,75,.05);
  --shadow-md: 0 8px 30px rgba(20,38,75,.12);
  --wrap: 1180px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font);
  color: var(--body);
  background: var(--bone);
  line-height: 1.6;
  font-size: 17px;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation: none !important; transition: none !important; }
}

h1, h2, h3 { color: var(--ink); line-height: 1.12; margin: 0 0 .5em; font-weight: 800; letter-spacing: -.01em; }
h1 { font-size: clamp(2.1rem, 5vw, 3.25rem); }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); }
h3 { font-size: 1.18rem; }
p { margin: 0 0 1rem; }
a { color: var(--navy-700); }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 22px; }
.section { padding: 72px 0; }
.section--navy { background: var(--navy); color: #DCE4F2; }
.section--navy h2, .section--navy h3 { color: #fff; }
.section--bone { background: var(--bone); }
.section--white { background: var(--white); }
.eyebrow { text-transform: uppercase; letter-spacing: .12em; font-weight: 700; font-size: .8rem; color: var(--accent-700); margin: 0 0 .6rem; }
.section--navy .eyebrow { color: var(--accent); }
.lead { font-size: 1.14rem; color: var(--body); max-width: 60ch; }
.section--navy .lead { color: #C6D2E8; }
.center { text-align: center; }
.center .lead { margin-left: auto; margin-right: auto; }

/* Skip link */
.skip { position: absolute; left: -999px; top: 0; background: var(--navy); color: #fff; padding: 10px 16px; z-index: 200; border-radius: 0 0 8px 0; }
.skip:focus { left: 0; }

/* Buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .5rem; font-weight: 800; font-size: 1rem; padding: 14px 24px; border-radius: 999px; border: 2px solid transparent; cursor: pointer; text-decoration: none; transition: transform .12s ease, background .12s ease, box-shadow .12s ease; }
.btn:active { transform: translateY(1px); }
.btn--gold { background: var(--accent-600); color: #fff; border-color: var(--accent-600); }
.btn--gold:hover { background: var(--accent-700); border-color: var(--accent-700); }
.btn--ghost { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn--ghost:hover { background: var(--navy); color: #fff; }
.btn--ghost-light { background: transparent; color: #fff; border-color: rgba(255,255,255,.6); }
.btn--ghost-light:hover { background: #fff; color: var(--navy); }
.btn--block { width: 100%; }
.btn--lg { padding: 16px 30px; font-size: 1.05rem; }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Header */
.site-header { position: sticky; top: 0; z-index: 100; background: rgba(251,250,247,.92); backdrop-filter: saturate(1.4) blur(8px); border-bottom: 1px solid var(--line); }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; height: 68px; gap: 18px; }
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; color: var(--navy); font-weight: 900; letter-spacing: -.02em; font-size: 1.12rem; }
.brand svg { flex: 0 0 auto; }
.brand b { color: var(--navy); }
.brand span { color: var(--accent-700); }
.nav { display: flex; align-items: center; gap: 26px; }
.nav a { color: var(--navy); text-decoration: none; font-weight: 600; font-size: .96rem; }
.nav a:hover { color: var(--accent-700); }
.header-cta { display: flex; align-items: center; gap: 14px; }
.header-phone { font-weight: 800; color: var(--navy); text-decoration: none; white-space: nowrap; }
.header-phone:hover { color: var(--accent-700); }
@media (max-width: 860px) {
  .nav { display: none; }
  .header-phone { display: none; }
}
.btn { white-space: nowrap; }
@media (max-width: 560px) {
  .brand > span { display: none; }   /* logo icon only on small phones */
  /* The header CTA never had a phone size, so it rendered at full desktop scale: 202px
     wide and 58px tall inside a 68px header on a 375px screen. That is 61% of the width,
     which left 43px of dead space beside the mark and squeezed the menu button into a
     10px gap against the edge. Sized down here, and the wrap padding comes in to buy back
     another 12px. */
  .site-header .wrap { gap: 12px; padding-left: 16px; padding-right: 16px; }
  .header-cta { gap: 12px; }
  .site-header .btn { font-size: .9rem; padding: 11px 16px; }
}
@media (max-width: 345px) {
  /* Only on the genuinely tiny phones. At 375px the full "Get a free estimate" fits with
     room to spare once the button is sized down, and the first version of this dropped
     "Get a" there for no reason. Measured, not guessed. */
  .site-header .btn { padding: 11px 13px; }
  .site-header .btn .btn-long { display: none; }
}

/* Hero */
.hero { background: linear-gradient(180deg, #fff 0%, var(--bone) 100%); border-bottom: 1px solid var(--line); }
/* align-items was "start", which pinned a short copy column to the top of a much taller
   form and left the dead space below it. Centering balances the two columns whatever the
   headline length. Padding trimmed so the hero stops overflowing a 768px viewport: it
   measured 823px tall, i.e. 107% of the screen, so nothing below it was ever visible. */
.hero .wrap { display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: center; padding-top: 34px; padding-bottom: 34px; }
/* The global h1 clamp tops out at 3.25rem, which ran the hero headline to three lines in
   a 489px column and pushed the hero past the full height of a 768px viewport. Scoped down
   here only; every other h1 on the site keeps the larger size. */
.hero__copy h1 { font-size: clamp(2rem, 4.1vw, 2.75rem); }
.hero__copy h1 span.geo { color: var(--navy-700); }
.hero__sub { font-size: 1.2rem; color: var(--body); max-width: 46ch; margin-bottom: 1.4rem; }
.trust-list { list-style: none; padding: 0; margin: 0 0 1.6rem; display: grid; gap: 10px; }
.trust-list li { display: flex; align-items: flex-start; gap: 10px; font-weight: 600; color: var(--navy); }
.trust-list svg { flex: 0 0 auto; margin-top: 3px; }
.hero__note { color: var(--muted); font-size: .95rem; }

/* Photo hero (homepage) */
.hero--photo { background: linear-gradient(100deg, rgba(15,23,42,.86) 0%, rgba(17,30,60,.64) 38%, rgba(20,38,75,.28) 64%, rgba(20,38,75,.16) 100%), url('/assets/hero/hero.jpg') center/cover no-repeat; border-bottom: 3px solid var(--accent); }
.hero--photo .wrap { padding-top: 44px; padding-bottom: 44px; }
.hero--photo .hero__copy { text-shadow: 0 2px 14px rgba(8,15,30,.5); }
.hero--photo .hero__copy h1 { color: #fff; }
.hero--photo .hero__copy h1 .geo { color: var(--accent); }
.hero--photo .hero__sub { color: #EAF0FA; }
.hero--photo .trust-list li { color: #fff; }
.hero--photo .eyebrow { color: var(--accent); }
@media (max-width: 900px) {
  .hero--photo { background: linear-gradient(180deg, rgba(15,23,42,.88), rgba(20,38,75,.9)), url('/assets/hero/hero.jpg') center/cover no-repeat; }
  .hero--photo .hero__copy { text-shadow: 0 2px 14px rgba(8,15,30,.6); }
}

@media (max-width: 900px) {
  .hero .wrap { grid-template-columns: 1fr; gap: 32px; }
  .section { padding: 56px 0; }
}

/* Form card */
.bid-card { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-md); padding: 26px; }
.bid-card h2 { font-size: 1.5rem; margin-bottom: .25rem; }
.bid-card .sub { color: var(--muted); margin-bottom: 1.1rem; font-size: .98rem; }
.field { margin-bottom: 12px; }
/* Paired fields. Six full-width rows made the card 1073px, which drove the whole hero to
   1.34x the viewport at 1440x900 and left the H1 sitting 461px down the page. Name+Phone
   and City+Job type are short inputs that read fine side by side. */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 12px; }
.field label { display: block; font-weight: 700; color: var(--navy); font-size: .9rem; margin-bottom: 5px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 12px 13px; border: 1.5px solid var(--line); border-radius: var(--radius-sm);
  font: inherit; font-size: 1rem; color: var(--ink); background: #fff; transition: border-color .12s ease;
}
.field textarea { min-height: 88px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--navy-500); outline: none; box-shadow: 0 0 0 3px rgba(44,78,133,.14); }
.field.invalid input, .field.invalid select, .field.invalid textarea { border-color: var(--err); }
.field .err { color: var(--err); font-size: .82rem; margin-top: 4px; display: none; }
.field.invalid .err { display: block; }
.consent { display: flex; gap: 10px; align-items: flex-start; margin: 6px 0 14px; }
.consent-note{font-size:.78rem;line-height:1.5;color:var(--muted,#5b6672);margin:10px 0 0}

.consent input { width: 18px; height: 18px; margin-top: 3px; flex: 0 0 auto; }
.consent label { font-size: .82rem; color: var(--muted); font-weight: 500; line-height: 1.45; }
.form-note{margin:.4rem 0 .85rem;font-size:.86rem;line-height:1.45;color:#4a5158;background:#f4f6f8;border-left:3px solid #187A3C;padding:.6rem .75rem;border-radius:.25rem}
.form-foot { color: var(--muted); font-size: .86rem; margin-top: 10px; text-align: center; }
.form-foot a { color: var(--navy-700); font-weight: 700; }
.form-success { display: none; background: var(--ok-bg); border: 1px solid #B7E3C6; color: #14532d; padding: 18px; border-radius: var(--radius-sm); font-weight: 600; }
.form-success.error { background: #FDECEA; border-color: #F5C2BD; color: #7A271A; }

/* Steps */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.step { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; box-shadow: var(--shadow-sm); }
.step .num { width: 38px; height: 38px; border-radius: 50%; background: var(--navy); color: var(--accent); display: grid; place-items: center; font-weight: 900; margin-bottom: 12px; }
.step h3 { margin-bottom: .35rem; }
.step p { margin: 0; color: var(--body); font-size: .98rem; }

/* Services */
/* Herriman has 8 services, so a fixed 4-column grid gave it two clean rows. Woodbury has
   FIVE, which left one orphan tile alone on row two. auto-fit reflows to 5 / 4 / 3 across
   without caring how many services there are. */
.svc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(198px, 1fr)); gap: 18px; }
.svc { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow-sm); }
.svc .ico { width: 44px; height: 44px; border-radius: 10px; background: rgba(244,180,26,.16); display: grid; place-items: center; margin-bottom: 12px; }
.svc h3 { font-size: 1.06rem; margin-bottom: .3rem; }
.svc p { margin: 0; font-size: .93rem; color: var(--muted); }
.svc-note { margin-top: 22px; color: var(--muted); font-size: .96rem; text-align: center; }

@media (max-width: 900px) { .svc-grid { grid-template-columns: repeat(2, 1fr); } .steps { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .svc-grid { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; } }

/* Services photo backdrop
   Hovering (or keyboard-focusing) a service tile fades that job's photo in behind
   the whole section; the other tiles go translucent so the photo reads through.
   Opt-in per section via .has-photo-backdrop + a .svc-bg layer. Enabled by
   js/services-backdrop.js, and only on real hover pointers with motion allowed,
   so touch and reduced-motion visitors keep the plain bone section. */
.has-photo-backdrop { position: relative; overflow: hidden; isolation: isolate; }
.has-photo-backdrop > .wrap { position: relative; z-index: 1; }
.svc-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: 1; transition: opacity .22s ease; }
.svc-bg img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity .28s ease;
}
.svc-bg img.is-shown { opacity: 1; }
/* Bone scrim. Weighted, not flat: heaviest across the top band where the eyebrow, heading
   and lead sit directly on the photo, then it opens up over the grid, where the tiles
   supply their own contrast.

   The top band is in PIXELS, not percentages. Herriman's stops were all percentages, which
   works there because its 8 services make two rows and a ~690px section. Woodbury has five
   services in ONE row and a 521px section, so "opens up at 38%" landed at 198px instead of
   262px, i.e. directly on the lead paragraph, which then sat in a 42% wash over autumn
   leaves. The header block is a fixed height whatever the tile count, so anchoring it to
   px makes the scrim independent of how many services a site has. */
.svc-bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(251,250,247,.93) 0px,
    rgba(251,250,247,.88) 60px,
    rgba(251,250,247,.82) 140px,
    rgba(251,250,247,.62) 200px,
    rgba(251,250,247,.34) 250px,
    rgba(251,250,247,.26) 80%,
    rgba(251,250,247,.46) 100%);
}
.has-photo-backdrop.is-showing .svc-bg { opacity: 1; }

@media (hover: hover) and (pointer: fine) {
  .svc-grid.backdrop-ready .svc { transition: background-color .3s ease, border-color .2s ease, transform .12s ease, box-shadow .2s ease; }
  /* While a photo is up, unhovered tiles thin out and let it show through. */
  .has-photo-backdrop.is-showing .svc-grid .svc { background: rgba(255,255,255,.72); border-color: rgba(255,255,255,.8); box-shadow: none; }
  .has-photo-backdrop.is-showing .svc-grid .svc p { color: var(--body); }
  .has-photo-backdrop.is-showing .svc-grid .svc.is-active {
    background: #fff; border-color: var(--accent); box-shadow: var(--shadow-md); transform: translateY(-3px);
  }
  .has-photo-backdrop.is-showing .svc-grid .svc.is-active p { color: var(--muted); }
}
@media (prefers-reduced-motion: reduce) {
  /* Keep the always-on background image, just drop the fade/swap motion. */
  .svc-bg, .svc-bg img { transition: none; }
}

/* Why / feature list */
.why-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px 40px; margin-top: 10px; }
.why-item { display: flex; gap: 14px; align-items: flex-start; }
.why-item svg { flex: 0 0 auto; margin-top: 2px; }
.why-item h3 { color: #fff; font-size: 1.05rem; margin-bottom: .2rem; }
.why-item p { margin: 0; color: #C6D2E8; font-size: .96rem; }
@media (max-width: 720px) { .why-grid { grid-template-columns: 1fr; } }

/* Area */
.area-chips { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 8px; }
.area-chips span { background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px; font-weight: 700; color: var(--navy); font-size: .95rem; }

/* FAQ */
.faq { max-width: 780px; margin: 0 auto; }
.faq details { background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 4px 20px; margin-bottom: 12px; box-shadow: var(--shadow-sm); }
.faq summary { cursor: pointer; font-weight: 700; color: var(--navy); padding: 14px 0; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.5rem; color: var(--accent-700); font-weight: 400; }
.faq details[open] summary::after { content: "\2212"; }
.faq details[open] summary { color: var(--navy); }
.faq .ans { padding: 0 0 16px; color: var(--body); }
.faq .ans p { margin: 0; }

/* CTA band */
.cta-band { background: var(--navy); color: #fff; text-align: center; }
.cta-band h2 { color: #fff; }
.cta-band .lead { color: #C6D2E8; margin: 0 auto 1.6rem; }
.cta-actions { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }

/* Footer */
.site-footer { background: #0F1D3A; color: #A9B6D0; padding: 54px 0 28px; font-size: .95rem; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 32px; margin-bottom: 34px; }
.site-footer h4,
.site-footer .foot-h { color: #fff; font-size: .95rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; margin: 0 0 14px; }
.site-footer a { color: #A9B6D0; text-decoration: none; }
.site-footer a:hover { color: var(--accent); }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 9px; }
.foot-brand b { color: #fff; }
.foot-brand span { color: var(--accent); }
.foot-nap { margin-top: 12px; line-height: 1.7; }
.foot-bottom { border-top: 1px solid rgba(255,255,255,.12); padding-top: 20px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; font-size: .86rem; }
.foot-bottom a { font-weight: 700; color: #C6D2E8; }
.disclaimer { color: #6E7EA0; font-size: .82rem; margin-top: 14px; max-width: 70ch; }
@media (max-width: 720px) { .footer-grid { grid-template-columns: 1fr; gap: 26px; } }

/* ---- Sub-page components (service + location pages) ---- */
.two-col { display: grid; grid-template-columns: 1.15fr .85fr; gap: 46px; align-items: start; }
@media (max-width: 860px) { .two-col { grid-template-columns: 1fr; gap: 30px; } }
.prose-narrow { max-width: 66ch; }
.before-after { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 18px; }
.before-after figure { margin: 0; }
.before-after img { display: block; width: 100%; height: auto; border-radius: var(--radius-sm); }
.before-after figcaption { margin-top: 6px; font-weight: 700; font-size: .92rem; color: var(--navy); }
.job-list { list-style: none; padding: 0; margin: 20px 0 0; display: grid; gap: 10px; }
.job-list li { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px 16px; box-shadow: var(--shadow-sm); }
.job-list .job { font-weight: 600; color: var(--navy); }
.job-list .price { color: var(--accent-700); font-weight: 800; white-space: nowrap; font-size: .95rem; }
.callout { background: #FDF2EC; border: 1px solid #F3D5C4; border-left: 4px solid var(--accent); border-radius: var(--radius-sm); padding: 14px 18px; margin-top: 22px; color: #6B3A21; font-size: .96rem; }
.callout strong { color: #5A4A16; }
.rel-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.rel-links a { background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 9px 16px; font-weight: 700; color: var(--navy); text-decoration: none; font-size: .95rem; }
.rel-links a:hover { border-color: var(--accent); color: var(--accent-700); }
.breadcrumb { font-size: .86rem; color: var(--muted); margin: 0 0 14px; }
.breadcrumb a { color: var(--navy-700); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent-700); }
.section h2.tight { margin-top: 0; }
.svc-grid a.svc { text-decoration: none; color: inherit; display: block; transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease; }
.svc-grid a.svc:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--accent); }
.area-chips a { background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px; font-weight: 700; color: var(--navy); font-size: .95rem; text-decoration: none; }
.area-chips a:hover { border-color: var(--accent); color: var(--accent-700); }
.lang-switch { font-weight: 700; color: var(--navy); text-decoration: none; font-size: .85rem; border: 1.5px solid var(--line); border-radius: 999px; padding: 6px 11px; white-space: nowrap; }
.lang-switch:hover { border-color: var(--accent); color: var(--accent-700); }
.brand-logo { display: block; border-radius: 22%; flex: 0 0 auto; }

/* About / meet the owner */
.about-grid { display: grid; grid-template-columns: 360px 1fr; gap: 46px; align-items: center; }
.about-photo { width: 100%; height: auto; display: block; border-radius: var(--radius); box-shadow: var(--shadow-md); aspect-ratio: 665 / 1000; object-fit: cover; }
.about-copy .btn { margin-top: 6px; }

/* Contractor / pro band + navy button */
.btn--navy { background: var(--navy); color: #fff; border-color: var(--navy); }
.btn--navy:hover { background: var(--navy-700); border-color: var(--navy-700); }
.pro-band { background: var(--accent); }
.pro-band .wrap { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-top: 24px; padding-bottom: 24px; flex-wrap: wrap; }
.pro-band p { margin: 0; font-weight: 800; color: var(--navy); font-size: 1.12rem; }
@media (max-width: 620px) { .pro-band .wrap { flex-direction: column; align-items: flex-start; } }

/* Contractor application funnel (multi-step) */
.funnel-req { background: #FFF7E6; border: 1px solid #F3DFA6; border-left: 4px solid var(--accent); border-radius: var(--radius-sm); padding: 12px 14px; font-size: .9rem; color: #6B5A1E; margin-bottom: 16px; }
.funnel-progress { margin-bottom: 16px; }
.funnel-progress .lbl { display: block; font-size: .8rem; font-weight: 700; color: var(--muted); margin-bottom: 6px; }
.funnel-progress .bar { height: 6px; background: var(--line); border-radius: 999px; overflow: hidden; }
.funnel-progress .bar i { display: block; height: 100%; background: var(--accent); border-radius: 999px; transition: width .25s ease; }
.funnel-step { display: none; }
.funnel-step.active { display: block; }
.funnel-nav { display: flex; gap: 10px; margin-top: 4px; }
.funnel-nav .btn { flex: 1; }
.consent.invalid label { color: var(--err); font-weight: 600; }
@media (max-width: 800px) { .about-grid { grid-template-columns: 1fr; gap: 24px; } .about-photo-wrap { max-width: 300px; } }

/* FAQ question as a real heading. An <h3> inside <summary> puts the question in
   the page outline where it belongs; this styles it back to the bare summary text
   it replaced, so nothing moves. font:inherit also kills the h3 UA margins. */
.faq-q { display: inline; margin: 0; font: inherit; color: inherit; letter-spacing: normal; }
/* letter-spacing is NOT covered by `font: inherit`, so without it these h3s inherit the
   -.01em tightening from the global h1,h2,h3 rule and render fractionally tighter than
   the plain <summary> text they replaced. Caught 2026-09-15 by diffing computed style,
   not the stylesheet: there is no declaration to read, the delta comes from a rule that
   only applies once the element is a heading. */

/* Utility pages (/privacy, /terms, /accessibility) use a plain heading block instead of
   the lead-capture hero, so the two-column grid and its form-side spacing do not apply. */
/* .hero .wrap is a two-column grid for the copy-plus-form layout. A utility page has no
   form, so without this the heading and the subtitle land in separate columns. */
.hero--plain .wrap { display: block; padding-top: 34px; padding-bottom: 26px; }
.hero--plain .hero__sub { margin-bottom: 0; }

/* ---------------------------------------------------------------------------
   Mobile disclosure nav
   ---------------------------------------------------------------------------
   Below 860px the primary nav and the header phone number were both display:none
   and nothing took their place, so a phone visitor had no navigation and no way to
   call. On a contractor's site the phone number is the more costly of the two.

   Built on <details> so it needs no JavaScript, announces its own expanded state,
   and is keyboard operable out of the box. Hidden entirely at desktop, where .nav
   does the job, so only ONE of the two is ever in the accessibility tree. */
.mnav { display: none; position: relative; }
.mnav__btn {
  list-style: none; cursor: pointer; display: grid; place-items: center;
  width: 42px; height: 42px; border-radius: 10px; color: var(--navy);
  border: 1px solid var(--line); background: #fff;
}
.mnav__btn::-webkit-details-marker { display: none; }   /* Safari's default triangle */
.mnav__btn:hover { border-color: var(--accent); }
.mnav__btn:focus-visible { outline: 3px solid var(--navy-500); outline-offset: 2px; }
.mnav__ico--close { display: none; }
.mnav[open] .mnav__ico--open { display: none; }
.mnav[open] .mnav__ico--close { display: block; }
.mnav__panel {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 120;
  min-width: min(78vw, 290px);
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-md); padding: 8px;
}
.mnav__panel nav { display: flex; flex-direction: column; }
.mnav__panel nav a {
  color: var(--navy); text-decoration: none; font-weight: 600;
  padding: 13px 14px; border-radius: 9px;
}
.mnav__panel nav a:hover { background: var(--bone); color: var(--accent-700); }
.mnav__phone {
  display: block; margin-top: 6px; padding: 13px 14px; border-radius: 9px;
  background: var(--navy); color: #fff; text-decoration: none;
  font-weight: 700; text-align: center;
}
.mnav__phone:hover { background: var(--navy-700); }
@media (max-width: 860px) { .mnav { display: block; } }

/* Brand lockup. The client's artwork replaced a house icon plus styled text that only
   approximated it: the real logo sets its own type and spacing, and reproducing that in
   CSS is a copy of a logo rather than the logo. */
.brand-lockup { display: block; height: 44px; width: auto; }
.brand-mark { display: none; }
@media (max-width: 560px) {
  /* A 193px wordmark and a phone header cannot both have the space, so fall back to the
     square mark. It carries the same navy and orange, so the brand still reads. */
  .brand-lockup { display: none; }
  .brand-mark { display: block; }
}
.foot-brand img { height: 50px; width: auto; }

/* Citation line under an on-page statistic. Small and quiet, but present: a number a
   reader cannot check is worth less than one they can. */
.source { margin-top: .9rem; font-size: .85rem; color: var(--muted); }
