/* ============================================================
   Shore Home Exteriors — design system
   Brand tokens sampled directly from the supplied logo files:
     #002844  navy      (wordmark on the light lockup)
     #061F2E  deep navy (background of the truck-sign lockup)
     #2489BE  accent    (the wave + "EXTERIORS" rule)
     #5DB8E9  accent-lt (wave highlight on the dark lockup)
   ============================================================ */

:root {
  --navy:        #002844;
  --navy-deep:   #061F2E;
  --navy-soft:   #0C3556;
  --accent:      #2489BE;
  --accent-lt:   #5DB8E9;
  --accent-dark: #1A6F9C;

  --sand:        #F6F3EE;
  --paper:       #FFFFFF;
  --ink:         #16242E;
  --ink-mid:     #47606F;
  /* Darkened from #6E8593, which measured 3.86:1 on white and 3.49:1 on
     --sand — both below the WCAG AA 4.5:1 minimum for normal text. It is
     used on .form-card__fallback, which carries the phone number and email
     a lead falls back to when the embed does not load, so it is the last
     copy that should be hard to read. Now 5.24:1 on white, 4.73:1 on sand. */
  --ink-soft:    #5A6F7E;
  --line:        #DFE6EB;

  --radius:      14px;
  --radius-sm:   9px;
  --shadow-sm:   0 1px 2px rgba(6,31,46,.06), 0 2px 8px rgba(6,31,46,.05);
  --shadow-md:   0 4px 12px rgba(6,31,46,.08), 0 12px 32px rgba(6,31,46,.09);
  --shadow-lg:   0 12px 28px rgba(6,31,46,.12), 0 28px 60px rgba(6,31,46,.14);

  --wrap:        1180px;
  --gutter:      clamp(1.1rem, 4vw, 2.5rem);

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--accent-dark); }

h1, h2, h3, h4 {
  line-height: 1.15;
  letter-spacing: -0.021em;
  color: var(--navy);
  margin: 0 0 .6em;
  font-weight: 800;
}
h1 { font-size: clamp(2.1rem, 5.4vw, 3.5rem); }
h2 { font-size: clamp(1.65rem, 3.6vw, 2.4rem); }
h3 { font-size: clamp(1.15rem, 2vw, 1.35rem); }
p  { margin: 0 0 1.1em; }

.wrap { width: min(var(--wrap), 100% - (var(--gutter) * 2)); margin-inline: auto; }
.section { padding: clamp(3.4rem, 7vw, 6rem) 0; }
.section--sand { background: var(--sand); }
.section--navy { background: var(--navy-deep); color: #DCE8F0; }
.section--navy h2, .section--navy h3 { color: #fff; }

.eyebrow {
  display: inline-block;
  font-size: .765rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--accent-dark);
  margin-bottom: .85rem;
}
.section--navy .eyebrow { color: var(--accent-lt); }

.lede { font-size: clamp(1.06rem, 1.7vw, 1.2rem); color: var(--ink-mid); max-width: 62ch; }
.section--navy .lede { color: #B9CEDC; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .92rem 1.6rem;
  border-radius: var(--radius-sm);
  font-weight: 700; font-size: 1rem;
  text-decoration: none; border: 2px solid transparent; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
  min-height: 48px;
}
.btn:hover { transform: translateY(-1px); }
.btn--primary { background: var(--accent); color: #fff; box-shadow: var(--shadow-sm); }
.btn--primary:hover { background: var(--accent-dark); box-shadow: var(--shadow-md); }
.btn--ghost { background: transparent; color: #fff; border-color: rgba(255,255,255,.5); }
.btn--ghost:hover { background: rgba(255,255,255,.1); border-color: #fff; }
.btn--outline { background: #fff; color: var(--navy); border-color: var(--line); }
.btn--outline:hover { border-color: var(--accent); color: var(--accent-dark); }

/* ---------- header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 900;
  background: rgba(255,255,255,.94);
  border-bottom: 1px solid var(--line);
}
/* NOTE: no backdrop-filter here. On the General Solutions build a
   backdrop-filter on the sticky header created a containing block for
   position:fixed descendants and trapped the mobile nav drawer inside the
   header. Caught only on a real phone. Don't reintroduce it. */
.header-inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .7rem 0; }
/* flex-shrink:0 because .header-inner > * carries min-width:0 (see the overflow
   note further down). Without it the logo is a shrinkable flex item and at
   ~1100px it was being compressed to 254px against its natural 266px — the
   wordmark silently rendered 4.5% narrow than tall, i.e. distorted. */
.brand { display: flex; align-items: center; text-decoration: none; flex-shrink: 0; }
/* The shipped logo-navy.png was 760x428 with the lockup floating in white
   padding — the ink was only 32% of the image height, so at height:48px the
   wordmark rendered 74x15.6px, i.e. the same height as one line of .nav text.
   That, not the nominal 48px, was why the branding read smaller than the nav.
   The asset is now trimmed to its ink (1320x278, transparent) so the height
   below is the height of the wordmark itself. Don't reintroduce padding into
   the asset — it silently shrinks the brand without changing any CSS. */
.brand img { height: 56px; width: auto; display: block; }

.nav { display: flex; align-items: center; gap: clamp(.95rem, 1.9vw, 1.7rem); }
.nav a { color: var(--navy); text-decoration: none; font-weight: 600; font-size: .97rem; white-space: nowrap; }
.nav a:hover { color: var(--accent-dark); }
/* "Get an Estimate" duplicates the .header-cta button on desktop. It is kept
   in the markup because the mobile drawer hides that button and would
   otherwise carry no CTA at all — shown only where the button is not. */
.nav__cta { display: none; }
.header-cta { display: flex; align-items: center; gap: .75rem; }
.header-phone {
  font-weight: 800; color: var(--navy); text-decoration: none; font-size: 1.02rem; white-space: nowrap;
}
.header-phone:hover { color: var(--accent-dark); }

.nav-toggle {
  display: none; background: none; border: 0; padding: .5rem; cursor: pointer;
  width: 46px; height: 46px;
}
.nav-toggle span { display: block; height: 2px; width: 26px; background: var(--navy); margin: 5px auto; border-radius: 2px; transition: .2s; }

/* ------------------------------------------------------------------
   Header width escalation.

   The header carries brand + 5 nav items + phone + CTA button. With the
   brand at its true size (266px, not the old collapsed 85px) and a sixth
   destination added, all of it together measures ~1043px — fine inside the
   1180px wrap, but the gutter is 4vw at medium widths, so at a 950px
   viewport only ~874px of content width exists. That is the squeeze, and it
   bites well above the 900px hamburger breakpoint.

   Rather than push everything behind a hamburger earlier, one element steps
   out at each tier, cheapest first, so a call and an estimate are always one
   tap away:
     >1180  brand 56 + nav + phone + button
     <1180  button out  (phone is the stronger contractor CTA; nav has one)
      <1000 nav out to the drawer, which then shows its own estimate link
      <720  phone out  (.callbar below carries Call + Free Estimate)

   Both thresholds were moved up from the values a 5-item nav could afford,
   because each was measured to land on zero slack once the sixth destination
   and the full-size brand were in:
     button 1100 -> 1180 : at a 1101px viewport slack was 13px
     drawer  900 -> 1000 : at a  901px viewport slack was  0px
   Zero is not "fits" — .nav uses system-ui, so the same markup renders a few
   px wider on a machine that resolves it to something other than the font
   measured here, and the nav would overflow or start shrinking the brand.
   At 1001px the same header now clears by ~55px.
   ------------------------------------------------------------------ */
@media (max-width: 1180px) {
  .brand img { height: 52px; }
  .header-cta .btn { display: none; }
}

@media (max-width: 1000px) {
  .nav-toggle { display: block; }
  .nav {
    position: fixed; inset: 0 0 0 auto; width: min(320px, 84vw);
    background: #fff; flex-direction: column; align-items: flex-start;
    padding: 5.5rem 1.75rem 2rem; gap: 1.4rem;
    transform: translateX(100%); transition: transform .25s ease;
    box-shadow: var(--shadow-lg); overflow-y: auto;
  }
  .nav[data-open="true"] { transform: translateX(0); }
  .nav a { font-size: 1.1rem; }
  .nav__cta { display: block; }
}

@media (max-width: 720px) {
  /* Hiding the phone leaves the row holding only brand + burger, so the brand
     scales with the viewport to use it: 53px at 390px (SHORE HOME renders 37px
     tall), floored at 44px so brand + gap + the 46px burger still clear the
     gutters on a 320px screen, capped at 60px approaching the 720px edge. */
  .brand img { height: clamp(44px, 13.5vw, 60px); }
  /* Trimmed from .7rem so the taller logo does not grow the header and push
     #estimate down: the header stays ~70px, i.e. where it was at 48px. */
  .header-inner { padding: .55rem 0; }
  /* Redundant with .callbar, which is fixed on screen from here down. */
  .header-phone { display: none; }
}

/* ---------- hero ---------- */
.hero { position: relative; color: #fff; background: var(--navy-deep); }
.hero__media { position: absolute; inset: 0; overflow: hidden; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, rgba(6,31,46,.95) 0%, rgba(6,31,46,.86) 42%, rgba(6,31,46,.55) 100%);
}
.hero__inner { position: relative; z-index: 1; padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(3rem, 6vw, 4.5rem); }
.hero__grid { display: grid; grid-template-columns: 1.06fr .94fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
@media (max-width: 940px) { .hero__grid { grid-template-columns: 1fr; } }

.hero h1 { color: #fff; margin-bottom: .55rem; }
.hero__tagline {
  font-size: clamp(1.02rem, 1.9vw, 1.22rem);
  color: var(--accent-lt); font-weight: 600; font-style: italic;
  margin: 0 0 1.15rem;
}
.hero__copy { color: #C6D8E4; font-size: 1.09rem; max-width: 54ch; }
.hero__points { list-style: none; padding: 0; margin: 1.5rem 0 1.9rem; display: grid; gap: .72rem; }
.hero__points li { display: flex; gap: .7rem; align-items: flex-start; color: #DCE8F0; font-size: 1.01rem; }
.hero__points svg { flex: 0 0 auto; margin-top: .28rem; color: var(--accent-lt); }
.hero__actions { display: flex; flex-wrap: wrap; gap: .85rem; }

/* form card */
.form-card { background: #fff; border-radius: var(--radius); padding: clamp(1.4rem, 2.6vw, 2rem); box-shadow: var(--shadow-lg); }
.form-card h2 { font-size: 1.4rem; margin-bottom: .3rem; }
.form-card__sub { color: var(--ink-mid); font-size: .96rem; margin-bottom: 1.2rem; }
.ms-form__loading { color: var(--ink-soft); font-size: .95rem; }
.form-card__fallback { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line); font-size: .9rem; color: var(--ink-soft); }

/* ---------- service cards ---------- */
.grid { display: grid; gap: 1.15rem; }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

.card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.5rem; box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: #C9D8E2; }
.card h3 { margin-bottom: .4rem; }
.card p { color: var(--ink-mid); margin: 0; font-size: .97rem; }
.card__icon {
  width: 44px; height: 44px; border-radius: 11px;
  background: rgba(36,137,190,.11); color: var(--accent-dark);
  display: grid; place-items: center; margin-bottom: 1rem;
}
.section--navy .card { background: rgba(255,255,255,.055); border-color: rgba(255,255,255,.13); }
.section--navy .card p { color: #B9CEDC; }
.section--navy .card__icon { background: rgba(93,184,233,.16); color: var(--accent-lt); }

/* ---------- gallery ---------- */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(275px, 1fr)); gap: 1rem; }
.gallery figure { margin: 0; border-radius: var(--radius); overflow: hidden; background: #E9EEF2; box-shadow: var(--shadow-sm); }
.gallery img { width: 100%; aspect-ratio: 4/3; object-fit: cover; transition: transform .4s ease; }
.gallery figure:hover img { transform: scale(1.04); }
.gallery figcaption { padding: .7rem .9rem; font-size: .87rem; color: var(--ink-mid); background: #fff; }

/* Homepage variant. The gallery now sits directly under the hero, so it is
   the first thing below the fold and carries the "these people actually do
   the work" job on a site with no reviews yet. The lead photo runs 2x2 to
   give the block editorial weight without a carousel.
   Guarded to >=960px: below that the grid is one or two columns and a
   two-column span would overflow its own track. */
@media (min-width: 960px) {
  .gallery--feature > figure:first-child { grid-column: span 2; grid-row: span 2; display: flex; flex-direction: column; }
  .gallery--feature > figure:first-child img { aspect-ratio: auto; flex: 1 1 auto; height: 100%; }
  .gallery--feature > figure:first-child figcaption { font-size: .95rem; }
}

/* ---------- service area ---------- */
.towns { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.4rem; padding: 0; list-style: none; }
.towns li {
  background: #fff; border: 1px solid var(--line); border-radius: 999px;
  padding: .5rem 1.05rem; font-weight: 600; font-size: .95rem; color: var(--navy);
}
.section--navy .towns li { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.16); color: #fff; }

/* ---------- FAQ ---------- */
.faq { display: grid; gap: .8rem; max-width: 860px; }
.faq details {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 1.05rem 1.25rem;
}
.faq summary {
  cursor: pointer; font-weight: 700; color: var(--navy); font-size: 1.03rem;
  list-style: none; display: flex; justify-content: space-between; gap: 1rem; align-items: center;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.4rem; color: var(--accent); font-weight: 400; line-height: 1; }
.faq details[open] summary::after { content: "−"; }
.faq details p { margin: .85rem 0 0; color: var(--ink-mid); }

/* ---------- footer ---------- */
.site-footer { background: var(--navy-deep); color: #9FB6C6; padding: clamp(2.6rem, 5vw, 4rem) 0 1.5rem; }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 2.2rem; }
@media (max-width: 1000px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer img.footer-logo { height: 54px; width: auto; margin-bottom: 1rem; }
/* Footer column labels are <p class="footer-heading">, not <h4> — a real h4
   after the page's h2s is a heading-level skip flagged by a11y tooling. */
.site-footer .footer-heading { color: #fff; font-size: .8rem; font-weight: 700; letter-spacing: .11em; text-transform: uppercase; margin: 0 0 .9rem; }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .55rem; }
.site-footer a { color: #B9CEDC; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer-bottom {
  margin-top: 2.4rem; padding-top: 1.3rem; border-top: 1px solid rgba(255,255,255,.12);
  display: flex; flex-wrap: wrap; gap: .8rem; justify-content: space-between; font-size: .86rem;
}

/* ---------- long-form inner pages ---------- */
/* Added with the 15-page expansion. Service, town and guide pages are body
   copy, not card grids, so they need a measure-constrained prose column. */
.prose { max-width: 74ch; }
.prose h2 { margin-top: 2.4rem; }
.prose h3 { margin-top: 1.9rem; margin-bottom: .45rem; }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose ul, .prose ol { padding-left: 1.25rem; margin: 0 0 1.1em; }
.prose li { margin-bottom: .5rem; }
.prose li::marker { color: var(--accent); }

/* Page hero for inner pages — navy band, no background image. */
.page-hero { background: var(--navy-deep); color: #DCE8F0; padding: clamp(2.6rem, 6vw, 4.4rem) 0 clamp(2.4rem, 5vw, 3.6rem); }
.page-hero h1 { color: #fff; }
.page-hero .lede { color: #B9CEDC; }
.page-hero .eyebrow { color: var(--accent-lt); }
.page-hero__actions { display: flex; flex-wrap: wrap; gap: .85rem; margin-top: 1.6rem; }

/* Breadcrumb trail — mirrors the BreadcrumbList in each page's JSON-LD. */
.crumbs { font-size: .87rem; color: #93AFC1; margin-bottom: 1rem; }
.crumbs a { color: #B9CEDC; text-decoration: none; }
.crumbs a:hover { color: #fff; text-decoration: underline; }
.crumbs span { margin: 0 .4rem; opacity: .55; }

/* Callout — used for "confirm this with the town/county" notes. These exist
   because several figures on this site are deliberately NOT published; the
   callout points the reader at the authority instead of guessing for them. */
.callout {
  background: var(--sand); border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm); padding: 1.15rem 1.35rem; margin: 1.6rem 0;
}
.callout p:last-child { margin-bottom: 0; }
.callout strong { color: var(--navy); }
.section--sand .callout { background: #fff; }
.section--navy .callout { background: rgba(255,255,255,.06); border-left-color: var(--accent-lt); }
.section--navy .callout strong { color: #fff; }

/* Numbered process steps */
.steps { list-style: none; padding: 0; margin: 1.6rem 0 0; display: grid; gap: 1.1rem; counter-reset: step; }
.steps li {
  position: relative; padding-left: 3.1rem; counter-increment: step;
}
.steps li::before {
  content: counter(step);
  position: absolute; left: 0; top: 0;
  width: 2.2rem; height: 2.2rem; border-radius: 50%;
  background: var(--accent); color: #fff;
  display: grid; place-items: center; font-weight: 800; font-size: .95rem;
}
.steps h3 { margin: 0 0 .3rem; font-size: 1.08rem; }
.steps p { margin: 0; color: var(--ink-mid); font-size: .98rem; }

/* Related-page link rows */
.pill-links { display: flex; flex-wrap: wrap; gap: .6rem; padding: 0; margin: 1.4rem 0 0; list-style: none; }
.pill-links a {
  display: inline-block; background: #fff; border: 1px solid var(--line);
  border-radius: 999px; padding: .5rem 1.05rem; font-weight: 600; font-size: .95rem;
  color: var(--navy); text-decoration: none;
}
.pill-links a:hover { border-color: var(--accent); color: var(--accent-dark); }
.section--navy .pill-links a { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.16); color: #fff; }
.section--navy .pill-links a:hover { border-color: var(--accent-lt); color: var(--accent-lt); }

/* ---------- mobile call bar ---------- */
.callbar { display: none; }
@media (max-width: 720px) {
  /* ------------------------------------------------------------------
     The call bar sits 66px off the bottom, not flush against it.

     WHY: the MainStreet embed injects a "Talk to Us" chat bubble into a
     shadow root at z-index 2147483647 (max), fixed at bottom:16px right:16px,
     which lands on top of this bar's right-hand cell. Measured on a real
     390x844 mobile viewport, document.elementFromPoint() at the centre of
     the "Free Estimate" link returned the chat bubble, not the link — the
     primary mobile CTA was dead at its centre while looking perfectly fine.

     The bubble cannot be moved from here: it lives inside a shadow root, so
     it is unreachable from this stylesheet, and the host carries inline
     width/height that defeats restyling it from outside. Raising our own
     bar is the fix we actually control. 66px clears the bubble's top edge
     (viewport bottom minus 58px) with a small gap.

     The safe-area padding is dropped deliberately — it exists to clear the
     home indicator, and the bar is no longer adjacent to it.
     Re-verify with scripts/ if the embed's widget position ever changes.
     ------------------------------------------------------------------ */
  .callbar {
    display: grid; grid-template-columns: 1fr 1fr; gap: 0;
    position: fixed; left: 0; right: 0; bottom: 66px; z-index: 950;
    background: #fff; border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    margin: 0 .6rem;
    box-shadow: 0 4px 18px rgba(6,31,46,.18);
    overflow: hidden;
    transition: opacity .25s ease, transform .25s ease;
  }
  /* Hidden while the hero's own CTA row is on screen (main.js toggles this).
     At the initial 390x844 viewport the bar (viewport 720-778) sat exactly on
     top of the hero's Call button (734-794) — two call CTAs stacked, one half
     eclipsed. Hero padding cannot fix that: the bar is viewport-fixed and the
     button's document position is set by the content above it, so the only
     scroll position they can't collide at is "hero CTAs not on screen at all".
     That is precisely what this encodes. Pages without .hero__actions never
     get this class, so the bar shows immediately there; with JS disabled the
     class is never added and behavior falls back to always-visible. */
  .callbar--hero-visible {
    opacity: 0; transform: translateY(8px); pointer-events: none;
  }
  .callbar a {
    padding: .95rem .5rem; text-align: center; font-weight: 700; text-decoration: none; font-size: .97rem;
    display: flex; align-items: center; justify-content: center; gap: .45rem; min-height: 52px;
  }
  .callbar a:first-child { color: var(--navy); }
  .callbar a:last-child { background: var(--accent); color: #fff; }
  body { padding-bottom: 132px; } /* raised bar (66) + bar height (~57) + clearance */

  /* Footer and breadcrumb links measured 15-16px tall on a 390px viewport —
     under the WCAG 2.2 (2.5.8) 24px target minimum and genuinely fiddly to
     hit with a thumb. Padding rather than font-size so the layout is
     unchanged on desktop. */
  .site-footer ul a,
  .crumbs a,
  .footer-bottom a { display: inline-block; padding: .35rem 0; }
}

/* reveal on scroll */
.reveal { opacity: 0; transform: translateY(14px); transition: opacity .5s ease, transform .5s ease; }
.reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

/* a11y */
.skip-link {
  position: absolute; left: -9999px; top: 0; background: var(--navy); color: #fff;
  padding: .75rem 1.2rem; z-index: 1000; border-radius: 0 0 var(--radius-sm) 0;
}
.skip-link:focus { left: 0; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------------
   Mobile overflow fix.

   Grid and flex children default to min-width:auto, which means they
   refuse to shrink below their content's intrinsic width. The MainStreet
   embed injects its own form into .form-card inside .hero__grid, and on a
   390px viewport that pushed the grid — and therefore the whole document —
   wider than the screen. Every section then clipped on the right, header
   phone number included. Caught on the deployed build, not in review.
   ------------------------------------------------------------------ */
.hero__grid > *,
.footer-grid > *,
.grid > *,
.header-inner > * { min-width: 0; }

#mainstreet-form { max-width: 100%; }
#mainstreet-form * { max-width: 100%; box-sizing: border-box; }

/* Last-resort guard so a future embed change can never reintroduce a
   horizontally scrolling page. Vertical scrolling is unaffected. */
html, body { overflow-x: hidden; }
