/* ============================================================
   site.css — layout specific to this website.
   Components and values come from brand-components.css / brand-tokens.css.
   No hex values here either: if you need a colour, it is a token.
   ============================================================ */

/* A little tighter than the brand default (3.25-5.5rem and 4-7rem): less scrolling between sections. */
:root { --section-y: clamp(2.5rem, 4.5vw, 4rem); --section-y-lg: clamp(3rem, 5.5vw, 5rem); }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
:target { scroll-margin-top: var(--space-5); }

/* ---------- brand lockup ----------
   The name is the loudest thing in the header after the badge, so it gets the
   display face at full weight and the brand green, not muted body-text brown. */
.logo b {
  font-weight: 700 !important;
  font-size: clamp(1.25rem, 1rem + .9vw, 1.6rem);   /* 20 -> 26px, so the nav has room beside it */
  color: var(--ui-heading);
  letter-spacing: .005em;
  line-height: 1.05;
}
.logo span { font-weight: 700; letter-spacing: .2em; font-size: var(--text-sm); margin-top: .2em; }

/* ---------- header ----------
   Deliberately quiet. On an upscale page the header is a shelf, not a band:
   no fill, one hairline, and the logo does the talking. */
.site-header {
  border-bottom: 1px solid var(--ui-rule);
  background: var(--white);
}
/* NOT sticky, deliberately. The lockup is 140px because the badge needs that much
   room to be readable, and a 165px bar following the reader down the page would eat
   a third of a phone screen. A shrink-on-scroll script was the obvious fix and was
   removed instead: it could not be verified in this environment, and unverified
   JavaScript on a live page is worse than a header that simply stays put. The
   mobile sticky call bar already keeps the phone number and the CTA within reach,
   which is the part that actually matters for conversion. */
.header-inner { display: flex; align-items: center; gap: clamp(var(--space-3), 2vw, var(--space-6)); padding-block: var(--space-3); }
/* The badge carries curved microtext ("QUALITY SINCE 1968") that turns to mush
   below about 96px. BRAND.md says so and the first header shipped it at 64px
   anyway. Either honour the floor or use the simplified mark: here the badge IS
   the brand, and a heritage mark at a confident size is the whole point. */
.logo { margin-right: auto; gap: var(--space-4); flex: none; }
.logo img { width: 96px; height: 96px; }
/* Navigation sits at body size, not caption size. It is the second thing a visitor
   uses after the logo, and shrinking it to 15px is a desktop-era habit. */
/* Labels never break mid-item. Two word labels like "Historic Homes" wrapping onto
   two lines is what made the header look broken, not the number of items. */
.nav { display: flex; gap: clamp(var(--space-4), 2vw, var(--space-6)); align-items: center; }
.nav a { white-space: nowrap; }
.nav a { font-weight: 400; font-size: var(--text-base); text-decoration: none; color: var(--ui-text); }
.nav a:hover { color: var(--ui-heading); text-decoration: underline; text-underline-offset: .3em; }

/* ---------- trust strip ----------
   Flush under the hero, in the deepest green so the two read as a single block.
   Not badges or icons: plain crawlable text, which an AI agent can read and which
   says the same things the Google Business Profile says. */
.trust-strip { padding-block: var(--space-4); }
/* Equal columns, not flex gaps. With flex the four claims are spaced by their own
   text widths, so "Fully insured" and "Free estimates, in person" sit at arbitrary
   intervals and the strip reads ragged. A four column grid puts each claim on a
   fixed rhythm and the dividers land evenly. */
.trust-list {
  display: grid; grid-template-columns: 1fr;
  gap: var(--space-3); text-align: center;
  list-style: none; margin: 0; padding: 0;
  font-size: var(--text-sm); font-weight: 600;
  letter-spacing: .04em;
  color: var(--ui-text);
}
@media (min-width: 760px) {
  .trust-list { grid-template-columns: repeat(3, 1fr); gap: 0; }
  .trust-list li + li { border-left: 1px solid var(--ui-rule); }
}
.trust-list li { display: flex; align-items: center; justify-content: center; }

/* ---------- full-bleed hero ----------
   The image runs edge to edge and the copy sits on it. The scrim is a gradient,
   densest behind the text and thinning toward the right so the photograph is still
   visible. Density is not a taste call: at 0.92 over a PURE WHITE photo, white text
   still measures 9.5:1, so the hero cannot fail contrast no matter what image lands
   in it later. A flat 0.7 scrim looks nicer and drops to 4.85, which fails AAA the
   day someone uploads a bright exterior shot. */
.hero-bleed { position: relative; isolation: isolate; overflow: hidden; }
.hero-bleed > .hero-media {
  position: absolute; inset: 0; z-index: -2; margin: 0;
}
.hero-bleed > .hero-media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.hero-bleed::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(100deg,
      rgba(31,60,37,.92) 0%,
      rgba(31,60,37,.84) 36%,
      rgba(31,60,37,.38) 62%,
      rgba(31,60,37,.12) 100%);
}
.hero-bleed .wrap { position: relative; z-index: 1; }
/* Stacked layout: copy runs the full width over the photo, so the side-weighted scrim leaves the right half bright
   (measured 3.4:1 on the lede). A flat even scrim keeps every line over 4.5:1 whatever the photo. */
@media (max-width: 899px) {
  .hero-bleed::after { background: linear-gradient(180deg, rgba(31,60,37,.9) 0%, rgba(31,60,37,.84) 100%); }
}

/* ---------- hero ----------
   Light, wide and airy. The old version was a saturated green slab with a
   brown button on it, which read heavy and muddy rather than composed. */
.hero-light { padding-top: var(--space-7); padding-bottom: var(--space-8); }
.hero-bleed { padding-block: clamp(1.5rem, 3vw, 2.25rem); }
.hero-light h1 { max-width: 16ch; }
.hero-light .lede { color: var(--ui-text); }
.hero .duo { align-items: start; }

/* ---------- section internals ---------- */
.cols-top, .steps-top { margin-top: var(--space-7); }


/* ---------- footer ----------
   Modelled on True Flow's: a brand column on the left carrying the mark, what the
   company does, how to reach it and the towns it covers as a sentence, then link
   columns beside it. Underlines are off here because a footer is a dense list of
   links and underlining every one turns it into noise; hover restores the cue. */
.site-footer { padding-block: var(--space-8) var(--space-6); }
.site-footer a { text-decoration: none; }
.site-footer a:hover { text-decoration: underline; text-underline-offset: .2em; }
.site-footer h3 {
  font-size: var(--text-sm); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ui-accent); margin-bottom: var(--space-4);
}
.footer-h3-gap { margin-top: var(--space-6); }
.footer-grid { display: grid; gap: var(--space-7); grid-template-columns: 1fr; }
@media (min-width: 700px)  { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; } }
.footer-brand p { font-size: var(--text-sm); max-width: 42ch; }
.footer-logo { width: 104px; height: 104px; margin-bottom: var(--space-5); }
.footer-contact a { display: inline-block; }
.footer-area { color: var(--ui-text-muted); }
.footer-list { list-style: none; padding: 0; margin: 0; font-size: var(--text-sm); }
.footer-list li { margin-bottom: var(--space-3); }
/* Bottom bar: copyright on the left, legal links on the right. Privacy lives here
   rather than in the Company column because it is a legal obligation, not something
   anyone is browsing for, and mixing it in with Services and Pricing gives it the
   same weight as a page we actually want people to open. */
.footer-note {
  display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6);
  align-items: baseline; justify-content: space-between;
  border-top: 1px solid var(--ui-rule); margin-top: var(--space-7);
  padding-top: var(--space-5); font-size: var(--text-sm); color: var(--ui-text-muted);
  max-width: none;
}
.footer-note p { margin: 0; max-width: none; }
.footer-legal a { color: var(--ui-text-muted); }
.footer-legal a:hover { color: var(--ui-text); }

/* ============================================================
   ONE-PAGE LAYOUT. Tokens only, no hex (the kit's check enforces it).
   ============================================================ */
.header-cta { white-space: nowrap; }
.header-phone { font-weight: 700; font-size: var(--text-base); color: var(--ui-heading); text-decoration: none; white-space: nowrap; }
.header-phone:hover { text-decoration: underline; text-underline-offset: .25em; }
[id] { scroll-margin-top: var(--space-4); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* hero: the form is a compact card laid over the right of the hero, vertically centered, so the
   hero is as tall as its copy and not as tall as a form. Mobile hides it; the contact form
   below carries the same fields and the hero button jumps there. */
.hero-wrap { position: relative; }
.hero-copy { max-width: 40rem; }
.hero-copy h1 { max-width: 18ch; }
.hero-copy .lede { max-width: 54ch; font-size: var(--text-base); }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-5); margin-top: var(--space-5); }
.cta-alt-call { font-weight: 700; }
.cta-alt-call a { color: var(--ui-link); }
.hero-form { position: absolute; right: 0; top: 50%; transform: translateY(-50%); width: 28rem; padding: var(--space-4) var(--space-5); display: grid; gap: var(--space-2); box-shadow: var(--shadow-card); }
.hero-form h2 { font-size: 1.8rem; margin: 0; white-space: nowrap; }
@media (min-width: 1240px) { .hero-form h2 { font-size: 2.3rem; } }
.hero-form p { margin: 0; }
.hero-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.hero-form input, .hero-form textarea, .hero-form select { width: 100%; min-width: 0; padding: .65rem .8rem; font: inherit; font-size: .875rem; color: var(--ui-text); background: var(--white); border: 1px solid var(--ui-rule-strong); border-radius: var(--radius-sm); }
.hero-form textarea { resize: none; }
.hero-form-note { font-size: calc(var(--text-xs) * .8); font-style: italic; line-height: 1.35; color: var(--ui-text-muted); }
@media (max-width: 1239px) { .hero-form-row { grid-template-columns: 1fr; gap: var(--space-2); } .hero-form { width: 22rem; } }
@media (max-width: 899px) { .hero-form { display: none; } .hero-copy { max-width: none; } }
@media (min-width: 900px) { .hero-copy { display: flex; flex-direction: column; justify-content: center; min-height: 26rem; } }  /* tall enough that the form card never touches the header or the strip */
@media (min-width: 900px) and (max-width: 1239px) { .hero-copy { min-height: 33rem; } }  /* the narrower form is taller, so the hero is too */
.field-pair { display: grid; gap: 0 var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 520px) { .field-pair { grid-template-columns: 1fr 1fr; } }
.form-status { margin: var(--space-2) 0 0; font-weight: 600; }
.form-status:empty { display: none; }
.form-status.is-error { color: var(--ui-accent); }
.form-status.is-ok { color: var(--ui-heading); }
.contact-form .hero-form-note { margin: 0; }

/* text-or-call: desktop shows the number, mobile shows Text and Call links */
.reach { margin-top: var(--space-5); font-weight: 600; }
.reach a { color: var(--ui-link); }
.reach-mob { display: none; }
@media (max-width: 1240px) { .header-phone { display: none; } }  /* the phone is in the hero and the tray; without this the header overflows between 881 and 1240px */
@media (max-width: 880px) { .reach-desk { display: none; } .reach-mob { display: inline; } .header-phone, .header-cta { display: none; } }

/* credentials: short cards with a big icon, label over a bold line */
.creds-band { padding-block: var(--space-6); }
.creds { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 640px) { .creds { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .creds { grid-template-columns: repeat(3, 1fr); } }
.cred { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3) var(--space-5); border: 1px solid var(--ui-rule); border-radius: var(--radius-md); background: var(--ui-bg); box-shadow: var(--shadow-card); }
.cred-icon { flex: none; width: 3.5rem; height: 3.5rem; fill: none; stroke: var(--ui-accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.cred small { display: block; font-size: var(--text-sm); color: var(--ui-text-muted); }
.cred b { display: block; font-size: var(--text-lg); line-height: 1.25; color: var(--ui-text); }

/* about: a small, short crew photo beside a taller story card (the reverse of a big photo with
   a small card), with room inside the card for the review carousel */
.about-grid { display: grid; gap: var(--space-5); align-items: center; }
@media (min-width: 900px) { .about-grid { grid-template-columns: .6fr 1.5fr; } }
.about-photo { margin: 0 auto; max-width: 360px; width: 100%; aspect-ratio: 3 / 4; border-radius: var(--radius-lg); overflow: hidden; border: 5px solid var(--white); box-shadow: var(--shadow-card); background: var(--ui-surface-alt); }
.about-photo img { width: 100%; height: 100%; object-fit: cover; object-position: center top; display: block; transform: scale(1.4); transform-origin: 53% 30%; }  /* zoomed on the BURGES shirt; the figure's overflow:hidden keeps the frame size */
.review-src { font-weight: 600; font-size: var(--text-sm); color: var(--ui-heading); }
.about-card { background: var(--ui-bg); padding: var(--space-7); border-radius: var(--radius-lg); }
.about-card .btn { margin-top: var(--space-5); }

/* review ribbon: compact and boxless. One line of Google mark, gold stars and the name, one short quote
   under it, then the dots and link on a single row. Cross-fades on its own; without JavaScript every
   review simply stacks. */
.reviews-band { padding-block: var(--space-4); }
.review-track { list-style: none; margin: 0 auto; padding: var(--space-3) var(--space-5); display: grid; gap: var(--space-4); max-width: 50rem; text-align: center; background: var(--white); border: 1px solid var(--ui-rule); border-radius: var(--radius-md); }
.review-top { display: flex; align-items: center; justify-content: center; gap: var(--space-3); }
.g-logo { width: 1.4rem; height: 1.4rem; flex: none; }
.stars { color: var(--star-gold); font-size: 1.2rem; letter-spacing: .08em; line-height: 1; }
.review-by { font-weight: 700; font-size: var(--text-sm); color: var(--ui-heading); }
.review blockquote { margin: var(--space-2) 0 0; }
.review blockquote p { margin: 0 auto; color: var(--ui-text); font-size: var(--text-base); max-width: none; min-height: 3.3em; }  /* room for two lines, so the box never jumps */
.js .review-track { gap: 0; }
.js .review { grid-area: 1 / 1; opacity: 0; visibility: hidden; transition: opacity 1.2s ease-in-out, visibility 1.2s; }
.js .review.is-active { opacity: 1; visibility: visible; }
.reviews-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-2) var(--space-5); margin-top: var(--space-3); }
.reviews-all { margin: 0; font-weight: 700; font-size: var(--text-sm); }
/* The cross-fade stays on for reduced-motion visitors: nothing moves, it only changes opacity. */

/* service tiles */
.tiles { list-style: none; margin: var(--space-7) 0 0; padding: 0; display: grid; gap: var(--space-5); grid-template-columns: 1fr; }
@media (min-width: 640px) { .tiles { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .tiles { grid-template-columns: repeat(3, 1fr); } }
.tile a { display: block; height: 100%; text-decoration: none; color: inherit; border: 1px solid var(--ui-rule); border-radius: var(--radius-lg); overflow: hidden; background: var(--ui-surface); transition: transform .15s var(--ease), border-color .15s var(--ease); }
.tile a:hover { transform: translateY(-2px); border-color: var(--ui-rule-strong); }
.tile img { width: 100%; height: auto; aspect-ratio: 8 / 5; object-fit: cover; display: block; background: var(--ui-surface-alt); }
.tile h3 { padding: var(--space-4) var(--space-5) 0; }
.tile p { padding: var(--space-2) var(--space-5) var(--space-5); color: var(--ui-text-muted); margin: 0; }
@media (prefers-reduced-motion: reduce) { .tile a, .tile a:hover { transition: none; transform: none; } }

/* faq accordion on native details, so it works without JavaScript */
.faq-list { margin-top: var(--space-6); border-top: 1px solid var(--ui-rule); }
.faq-item { border-bottom: 1px solid var(--ui-rule); }
.faq-item summary { cursor: pointer; padding: var(--space-4) 0; font-weight: 700; color: var(--ui-heading); min-height: var(--touch-min); }
.faq-a { padding-bottom: var(--space-4); color: var(--ui-text); }
#faq .wrap-sm { max-width: 48rem; margin-inline: auto; }
#faq .eyebrow, #faq h2 { text-align: center; margin-inline: auto; }
#faq .wrap-sm h2 { margin-inline: auto; }

/* contact block, modeled on True Flow's: a deep brand panel of contact rows beside the form */
.contact-block { display: grid; gap: var(--space-5); grid-template-columns: 1fr 1fr; align-items: stretch; max-width: 68rem; }
.contact-block > * { min-width: 0; }
.contact-info { padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); border: 0; background: var(--ui-bg); box-shadow: var(--shadow-card); }
.contact-info h2 { margin: 0; }
.contact-info .lede { margin: 0 0 var(--space-3); }
.contact-row { display: flex; gap: var(--space-4); align-items: center; padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: var(--ui-bg); }
.contact-row i { flex: none; width: 2.4rem; height: 2.4rem; border-radius: var(--radius-pill); background: var(--ui-heading); display: grid; place-items: center; }
.contact-row svg { width: 1.1rem; height: 1.1rem; stroke: var(--white); fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.contact-row small { display: block; font-weight: 700; font-size: var(--text-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--ui-text-muted); }
.contact-row a { color: var(--ui-text); }
.contact-row a[href^="mailto:"] { white-space: nowrap; }
.contact-form { background: var(--ui-bg); padding: var(--space-6); display: grid; gap: var(--space-3); align-content: start; box-shadow: var(--shadow-card); }
.contact-form h2 { margin: 0; }
.contact-form label { display: grid; gap: var(--space-1); font-weight: 600; font-size: var(--text-sm); color: var(--ui-heading); }
.contact-form input, .contact-form select, .contact-form textarea { width: 100%; min-width: 0; padding: .7rem .85rem; font: inherit; font-weight: 400; font-size: var(--text-sm); color: var(--ui-text); background: var(--white); border: 1px solid var(--ui-rule-strong); border-radius: var(--radius-sm); }
.contact-form textarea { resize: none; }
.contact-form-pair { display: grid; gap: var(--space-3); grid-template-columns: 1fr 1fr; }
.contact-form-last { display: grid; gap: var(--space-3); }
@media (max-width: 960px) { .contact-block { grid-template-columns: minmax(0, 1fr); } .contact-form-pair { grid-template-columns: 1fr; } }

/* mobile nav: the anchor links stay visible as a scrolling row under the logo */
@media (max-width: 880px) {
  .header-inner { flex-wrap: wrap; row-gap: 0; }
  .nav { display: flex; order: 3; width: 100%; overflow-x: auto; gap: var(--space-5); padding: var(--space-2) 0 var(--space-3); border-top: 1px solid var(--ui-rule); }
}

/* footer, modeled on True Flow's: brand and contact, then service, company and hours columns */
.footer-contact { font-style: normal; display: grid; gap: var(--space-2); margin-top: var(--space-4); }
.footer-contact-link { font-size: var(--text-sm); }
.footer-col h3 a { color: inherit; }
.footer-hours li { display: flex; justify-content: space-between; gap: var(--space-4); }
@media (min-width: 1040px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1.1fr; } }

/* service areas and at a glance, modeled on True Flow's */
.areas { padding-bottom: var(--space-6); }
.areas-inner { display: grid; gap: var(--space-7); align-items: start; }
@media (min-width: 960px) { .areas-inner { grid-template-columns: .9fr 1.1fr; } }
.areas-map { min-width: 0; }
.map-placeholder { aspect-ratio: 1 / 1; display: grid; place-items: center; text-align: center; padding: var(--space-6); border: 5px solid var(--white); border-radius: var(--radius-lg); background: var(--ui-surface-alt); box-shadow: var(--shadow-card); }
.map-placeholder p { margin: 0; color: var(--ui-text-muted); }
.map-embed { width: 100%; aspect-ratio: 1 / 1; border: 5px solid var(--white); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); }
.areas h2 { text-align: center; margin: 0; }
.areas .sub { text-align: center; text-transform: uppercase; letter-spacing: .08em; font-size: var(--text-xs); font-weight: 700; margin: var(--space-3) 0 var(--space-5); color: var(--ui-accent); }
.town-list { list-style: none; margin: 0; padding: 0; display: grid; grid-auto-flow: column; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, auto); column-gap: var(--space-5); row-gap: var(--space-4); }  /* a real grid, so the towns line up across rows */
@media (max-width: 640px) { .town-list { grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(3, auto); } }
.town-list li { margin: var(--space-2) 0; padding-left: var(--space-5); font-weight: 600; position: relative; break-inside: avoid; }
.town-list li::before { content: ""; position: absolute; left: .1rem; top: .25em; width: .35rem; height: .7rem; border: solid var(--ui-accent); border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); }
.areas-note { margin: var(--space-5) 0 0; }

.glance { padding-top: var(--space-6); }
.glance-inner { display: grid; gap: var(--space-7); align-items: stretch; }
@media (min-width: 960px) { .glance-inner { grid-template-columns: 1.05fr 1fr; } }
.glance-card { padding: var(--space-7); box-shadow: var(--shadow-card); background: var(--ui-bg); }
.glance-card h2 { margin: 0 0 var(--space-5); white-space: nowrap; }
.glance-card h2 em { font-style: normal; position: relative; white-space: nowrap; }
.glance-card h2 em svg { position: absolute; left: -2%; bottom: -.45em; width: 104%; height: .62em; overflow: visible; transform: rotate(-.8deg); }
.glance-card h2 em path { fill: var(--ui-accent-deco); stroke: none; }
.glance-card h2 em path.bristle { fill: none; stroke: var(--ui-accent-deco); stroke-width: 1.4; stroke-linecap: round; opacity: .7; }
/* The stroke is painted on left to right when the card scrolls into view. Without JavaScript,
   or with reduced motion, it simply sits there finished. */
.js .glance-card h2 em svg { clip-path: inset(-20% 100% -20% 0); }
.js .glance-card.is-drawn h2 em svg { animation: brush-on 1.1s cubic-bezier(.3,.6,.3,1) .2s forwards; }
@keyframes brush-on { to { clip-path: inset(-20% 0 -20% 0); } }
@media (prefers-reduced-motion: reduce) { .js .glance-card h2 em svg { clip-path: none; animation: none; } }
.glance-stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); margin: var(--space-5) 0 0; }
.glance-stat b { display: block; font-family: var(--font-display); font-size: var(--text-2xl); line-height: 1; color: var(--ui-heading); }
.glance-stat span { color: var(--ui-text); }
.glance-photos { position: relative; align-self: stretch; min-height: 22rem; }
.glance-photo { position: absolute; border: 5px solid var(--white); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); background: var(--ui-surface-alt); overflow: hidden; }
.glance-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.glance-photo-1 { left: 0; top: 0; width: 80%; height: 68%; }
.glance-photo-2 { right: 0; bottom: 0; width: 70%; height: 58%; }

/* sticky tray: phone plus the estimate button, on every screen size */
.sticky-tray { position: fixed; z-index: 120; left: 50%; bottom: var(--space-4); transform: translateX(-50%); display: flex; align-items: center; gap: var(--space-4); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5); background: var(--ui-bg); border-radius: var(--radius-pill); box-shadow: var(--shadow-card); border: 1px solid var(--ui-rule-strong); max-width: calc(100% - var(--space-5)); }
.sticky-tray a:not(.btn) { color: var(--ui-link); font-weight: 700; text-decoration: none; white-space: nowrap; }
.sticky-tray a:not(.btn):hover { text-decoration: underline; text-underline-offset: .25em; }
.sticky-tray .btn { white-space: nowrap; border-radius: var(--radius-pill); }
.tray-mob { display: none; }
/* The tray stays out of the way until the visitor starts scrolling, so it never covers the hero or the
   trust strip on first view. Without JavaScript it is simply always there. */
.js .sticky-tray { opacity: 0; visibility: hidden; transform: translate(-50%, calc(100% + 2rem)); transition: opacity .9s ease, transform 1s cubic-bezier(.16, 1, .3, 1), visibility 0s linear 1s; }
.js .sticky-tray.is-shown { opacity: 1; visibility: visible; transform: translateX(-50%); transition: opacity .9s ease, transform 1s cubic-bezier(.16, 1, .3, 1), visibility 0s; }
/* Reduced motion keeps the fade and drops the slide: opacity only, nothing travels. */
@media (prefers-reduced-motion: reduce) { .js .sticky-tray { transform: translate(-50%, 0); } }
@media (max-width: 880px) { .tray-desk { display: none; } .tray-mob { display: inline; } .sticky-tray { gap: var(--space-3); padding-left: var(--space-4); } }
.site-footer { padding-bottom: 7rem; }

/* Scroll reveal: sections slide in from the bottom or from well off the sides as they come into view.
   The head of the page sets .reveal-on before the first paint (only when the browser can do it), so nothing
   flashes; without JavaScript the class never appears and nothing is hidden. Reduced motion keeps the fade
   and drops the slide. */
main { overflow-x: clip; }
.reveal-on :is(.cred:nth-child(3n+2), .tile:nth-child(3n+2), .step:nth-child(3n+2), #services h2, #process h2, #work h2, .reviews, #faq .wrap-sm, .feature-banner) { --rv: translateY(64px); }
.reveal-on :is(.cred:nth-child(3n+1), .tile:nth-child(3n+1), .step:nth-child(3n+1), .ba-before, .about-photo, .areas-map, .glance-card, .contact-info) { --rv: translateX(-22vw); }
.reveal-on :is(.cred:nth-child(3n), .tile:nth-child(3n), .step:nth-child(3n), .ba-after, .about-card, .areas-inner > div:last-child, .glance-photos, .contact-form) { --rv: translateX(22vw); }
.reveal-on :is(.cred, .tile, #services h2, .reviews, #faq .wrap-sm, .about-photo, .areas-map, .glance-card, .contact-info, .about-card, .areas-inner > div:last-child, .glance-photos, .contact-form, .step, #process h2, #work h2, .ba-before, .ba-after, .feature-banner) { opacity: 0; transform: var(--rv); will-change: transform, opacity; transition: opacity 1s ease-out, transform 1.3s cubic-bezier(.22, .7, .2, 1); }
.reveal-on :is(.cred, .tile, #services h2, .reviews, #faq .wrap-sm, .about-photo, .areas-map, .glance-card, .contact-info, .about-card, .areas-inner > div:last-child, .glance-photos, .contact-form, .step, #process h2, #work h2, .ba-before, .ba-after, .feature-banner).in-view { opacity: 1; transform: none; will-change: auto; }
@media (prefers-reduced-motion: reduce) { .reveal-on :is(.cred, .tile, #services h2, .reviews, #faq .wrap-sm, .about-photo, .areas-map, .glance-card, .contact-info, .about-card, .areas-inner > div:last-child, .glance-photos, .contact-form, .step, #process h2, #work h2, .ba-before, .ba-after, .feature-banner) { --rv: none; } }

/* Footer text matches the footer links: the description and the hours read in the same white as the links. */
.site-footer .footer-brand p, .site-footer .footer-hours li { color: var(--ui-link); }

/* how it works: the three steps sit centered under their heading */
#process .steps { margin-top: var(--space-6); list-style: none; padding: 0; }
.step h3 { margin-bottom: var(--space-2); font-size: 1.7rem; }
.step p { margin: 0; }

/* before and after: two photos side by side, labeled */
.ba-grid { display: grid; gap: var(--space-5); margin: var(--space-5) auto 0; max-width: 720px; grid-template-columns: 1fr; }
@media (min-width: 700px) { .ba-grid { grid-template-columns: 1fr 1fr; } }
.ba-grid figure { margin: 0; position: relative; border-radius: var(--radius-lg); overflow: hidden; border: 5px solid var(--white); box-shadow: var(--shadow-card); background: var(--ui-surface-alt); }
.ba-grid img { width: 100%; height: auto; display: block; }
.ba-grid figcaption { position: absolute; left: var(--space-4); top: var(--space-4); padding: var(--space-1) var(--space-4); border-radius: var(--radius-pill); background: var(--white); color: var(--ui-heading); font-weight: 700; font-size: var(--text-sm); letter-spacing: .06em; text-transform: uppercase; }

/* The two contact headings share one size and each fits on a single row. */
@media (min-width: 960px) { .contact-info h2, .contact-form h2 { white-space: nowrap; } }

/* "More questions": a second native details holding the rest of the list. Closed, it is one tidy row; the answers stay in the page text. */
.faq-more { border-bottom: 1px solid var(--ui-rule); }
.faq-more-toggle { cursor: pointer; display: flex; align-items: center; justify-content: center; min-height: var(--touch-min); padding: var(--space-4) 0; font-weight: 700; color: var(--ui-link); list-style: none; }
.faq-more-toggle::-webkit-details-marker { display: none; }
.faq-more-toggle::after { content: "+"; margin-left: var(--space-2); font-size: 1.25em; line-height: 1; }
.faq-more[open] > .faq-more-toggle::after { content: "\2212"; }
.faq-more[open] > .faq-more-toggle { border-bottom: 1px solid var(--ui-rule); }
.faq-more > .faq-item:last-child { border-bottom: 0; }
.faq-more-toggle:focus-visible, .faq-item summary:focus-visible { outline: 3px solid var(--ui-focus, currentColor); outline-offset: 2px; }

.ba-grid img { aspect-ratio: 4 / 3; object-fit: cover; object-position: center 35%; }
.fb-logo { width: 22px; height: 22px; flex: none; }
.feature-banner { margin-top: var(--space-5); display: grid; grid-template-columns: 1fr; border: 1px solid var(--ui-rule); border-radius: var(--radius-lg); overflow: hidden; background: var(--ui-surface); }
.feature-banner img { width: 100%; height: auto; aspect-ratio: 900 / 903; object-fit: cover; display: block; }  /* the whole scene: spray, steeple, building, and the lift down to its base */
.feature-copy { padding: var(--space-5); display: flex; flex-direction: column; justify-content: center; gap: var(--space-3); align-items: flex-start; }
.feature-copy h3, .feature-copy p { margin: 0; }
.feature-copy p { color: var(--ui-text-muted); }
@media (min-width: 760px) { .feature-banner { grid-template-columns: minmax(0, 360px) 1fr; } .feature-copy { padding: var(--space-6); } }
.areas-embed { width: 100%; height: auto; aspect-ratio: 4 / 3; border: 0; border-radius: var(--radius-lg); display: block; }
.ba-grid.ba-tall img { aspect-ratio: 1 / 1; }
.ba-grid.ba-tall .ba-before img { object-position: center 45%; }
.ba-grid.ba-tall .ba-after img { object-position: center 22%; }  /* portrait shots: keep the faces in frame */

/* Card and tile headings never wrap: the card is a size container and the heading scales to it. */
.tile, .about-card, #faq .wrap-sm { container-type: inline-size; }
.tile h3 { white-space: nowrap; font-size: clamp(1rem, 6.6cqi, 1.5rem); }
.about-card h2, #faq h2 { white-space: nowrap; }
#about { padding-bottom: var(--space-5); }  /* the reviews ribbon sits just under the about card */
.areas-map-img { margin: 0; border-radius: var(--radius-lg); overflow: hidden; }
.areas-map-img img { width: 100%; height: auto; aspect-ratio: 1000 / 867; object-fit: cover; display: block; }
/* Service area copy: more air between the heading, the town list, and the call/text note. On desktop the column is
   centered against the map, nudged up, which is the taller side, so the section does not grow. */
.areas .sub { margin-bottom: var(--space-7); }
.areas h2 + .sub { margin-top: var(--space-4); }
.town-list li { margin: 0; }
.areas-note { margin-top: var(--space-7); }
@media (min-width: 960px) { .areas-inner > div:last-child { align-self: stretch; display: flex; flex-direction: column; justify-content: center; padding-bottom: var(--space-6); } }
/* Section rhythm. Each band pads itself top and bottom, so two neighbours on the same background double up;
   the lower one gives some of its top padding back. Targets: about 80 to 115px between one section's content
   and the next, never the 130-160px the doubling produced. */
.faq-list { margin-top: 0; }
#about { padding-top: var(--space-7); }
#process { padding-top: var(--space-4); padding-bottom: var(--space-6); }
#work { padding-top: var(--space-7); }
#areas { padding-top: var(--space-5); }
#faq { padding-top: var(--space-7); padding-bottom: var(--space-7); }
#contact { padding-top: var(--space-7); }
/* One size for every section heading (the hero form's own heading is sized to its narrow card). The size is the
   largest that still fits the two contact cards and the At a glance card on one line, and it scales with the screen. */
:root { --h2-size: clamp(1.3rem, 3.45vw, 2.75rem); }
@media (max-width: 520px) { :root { --h2-size: 1.3rem; } }
main h2 { font-size: var(--h2-size); }

/* Phone pass (640px and under): thumb-sized tap targets, shorter stacks, no wasted height. */
@media (max-width: 640px) {
  .nav a { padding-block: .7rem; }
  .nav { padding-block: 0; }
  .tile img { aspect-ratio: 2 / 1; }
  .tile p { padding-bottom: var(--space-4); }
  .ba-grid { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
  .ba-grid figure { border-width: 3px; }
  .ba-grid figcaption { left: var(--space-2); top: var(--space-2); padding: 2px var(--space-3); font-size: var(--text-xs); }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--space-6) var(--space-4); }
  .footer-grid > .footer-brand, .footer-grid > .footer-col:last-child { grid-column: 1 / -1; }
  .footer-list li { margin-bottom: 0; }
  .footer-list a, .footer-contact-link { display: block; padding-block: .55rem; }
  .hero-form-note { font-size: .75rem; }
  .town-list { grid-template-columns: repeat(2, auto); justify-content: center; column-gap: var(--space-7); }
  .areas-note { text-align: center; }
  .areas-note a[href^="tel:"] { white-space: nowrap; }
  .sticky-tray { width: calc(100vw - 2 * var(--space-4)); max-width: 30rem; box-sizing: border-box; justify-content: space-between; gap: var(--space-2); padding-left: var(--space-3); }
  .sticky-tray a:not(.btn) { padding: .75rem .25rem; flex: none; }
  .sticky-tray .btn { flex: 1 1 auto; min-width: 0; padding-inline: var(--space-3); text-align: center; font-size: clamp(.85rem, 4vw, 1rem); }
  .footer-col h3 a { display: inline-block; padding-block: .5rem; }
}

/* Centered headings carry a max-width (in ch); without auto side margins the box hugs the left edge and the centered text sits off-center. */
h2.center, .areas h2, #faq h2 { margin-inline: auto; }

