/* Plus Jakarta Sans, one variable file covering 400 to 800, latin subset,
   served from this origin.

   It used to come from fonts.googleapis.com, so first paint waited on a DNS
   lookup, a TLS handshake and two round trips to a domain we do not control.
   Measured on this repo, with Google Fonts unreachable, first contentful paint
   went from 800ms to 13.7 seconds. That is not a normal figure, but it is the
   shape of the dependency: the whole render sat behind somebody else's uptime.

   font-display:swap so text paints immediately in the system font and swaps
   when the file lands, which is why CLS stays at zero. */
@font-face{font-family:'Plus Jakarta Sans';font-style:normal;font-weight:400 800;
  font-display:swap;src:url(/assets/fonts/plus-jakarta-sans-var.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* Each brand's own typeface, both under the SIL Open Font License, served
   from this origin like Plus Jakarta Sans above. */
@font-face{font-family:'Archivo';font-style:normal;font-weight:400 900;
  font-display:swap;src:url(/assets/fonts/archivo-latin.woff2) format('woff2')}
@font-face{font-family:'Manrope';font-style:normal;font-weight:200 800;
  font-display:swap;src:url(/assets/fonts/manrope.woff2) format('woff2')}

/* Area pages. One stylesheet, two brands: the generator stamps data-site on the
   root element, so the same markup wears the DampScan dark palette or the ATi
   light one. Deliberately compact rather than a copy of the home page CSS,
   which is inline there and would otherwise be duplicated on every area page. */
*,*::before,*::after{box-sizing:border-box}

:root[data-site="dampscan"]{
  --bg:#0c1a2b;--bg-2:#081321;--card:#14243a;
  --line:rgba(255,255,255,.08);--line-strong:rgba(255,255,255,.15);
  --accent:#4fa8e8;--accent-hi:#7cc3f5;--accent-soft:rgba(79,168,232,.12);
  --text:#f5f8fc;--muted:#aebbcc;--muted-2:#7f8ea4;--on-accent:#06121f;
  /* Roles the booking form needs on top of the page palette. */
  --line-strong:rgba(255,255,255,.15);--card-2:#101f33;--card-shadow:rgba(0,0,0,.85);
  --warn:#f0a08b;--warn-soft:rgba(232,131,107,.06);
  --head-bg:rgba(8,19,33,.86);--head-solid:#081321;
}
/* Verge Roofing and CoolRight, in the palettes their own sites wore before
   they moved into this project: Verge near-black with its orange, CoolRight
   deep navy with sky blue. Without these the two brands had no palette at all
   and rendered as a blank white page with invisible form fields. */
:root[data-site="roofing"]{
  --bg:#141414;--bg-2:#0d0d0d;--card:#1c1c1c;
  --line:rgba(217,217,217,.14);--line-strong:rgba(217,217,217,.26);
  --accent:#f4581c;--accent-hi:#ff7038;--accent-soft:rgba(244,88,28,.13);
  --text:#f6f5f4;--muted:#b9b6b2;--muted-2:#928e89;--on-accent:#ffffff;
  --card-2:#242424;--card-shadow:rgba(0,0,0,.85);
  --warn:#ff9b7a;--warn-soft:rgba(244,88,28,.08);
  --head-bg:rgba(20,20,20,.9);--head-solid:#141414;
}
:root[data-site="ac"]{
  --bg:#0f172a;--bg-2:#0a1120;--card:#151f36;
  --line:rgba(209,213,219,.14);--line-strong:rgba(209,213,219,.26);
  --accent:#38bdf8;--accent-hi:#7dd3fc;--accent-soft:rgba(56,189,248,.12);
  --text:#e7ecf5;--muted:#9fb0c9;--muted-2:#8193ae;--on-accent:#062033;
  --card-2:#101a2e;--card-shadow:rgba(0,0,0,.8);
  --warn:#f0a08b;--warn-soft:rgba(232,131,107,.06);
  --head-bg:rgba(15,23,42,.88);--head-solid:#0f172a;
}

:root[data-site="ati"]{
  --bg:#f5f5f3;--bg-2:#ebebe8;--card:#ffffff;
  --line:rgba(17,33,60,.13);--line-strong:rgba(17,33,60,.24);
  --accent:#17325a;--accent-hi:#2a5591;--accent-soft:rgba(23,50,90,.08);
  --text:#11213c;--muted:#4a5871;--muted-2:#5b6780;--on-accent:#ffffff;
  /* The form card stays flat and light here rather than fading to navy. */
  --line-strong:rgba(17,33,60,.24);--card-2:#ffffff;--card-shadow:rgba(17,33,60,.28);
  --warn:#a3341a;--warn-soft:rgba(163,52,26,.07);
  --head-bg:rgba(245,245,243,.9);--head-solid:#f5f5f3;
}

/* Visible only when focused. A keyboard user should not have to tab the whole
   header on every one of sixty-nine pages to reach the content. */
.skip-link{position:absolute;left:-9999px;top:0;z-index:200;padding:12px 18px;
  background:var(--accent);color:var(--on-accent);font-weight:700;
  border-radius:0 0 10px 0}
.skip-link:focus{left:0}

html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--text);line-height:1.65;
  font-family:'Plus Jakarta Sans',system-ui,-apple-system,Segoe UI,sans-serif;
  -webkit-font-smoothing:antialiased}
[data-site="roofing"] body{font-family:'Archivo',system-ui,-apple-system,Segoe UI,sans-serif}
[data-site="ac"] body{font-family:'Manrope',system-ui,-apple-system,Segoe UI,sans-serif}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hi)}
img{max-width:100%;height:auto}
h1,h2,h3{line-height:1.14;letter-spacing:-.02em;margin:0;font-weight:800}
p,ul{margin:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

.wrap{max-width:1200px;margin-inline:auto;padding:0 clamp(20px,4vw,40px)}

/* The header itself lives in header.css, shared with the home pages. What
   belongs here is only the room the fixed header needs, since these pages open
   with a breadcrumb rather than a tall hero. The value is a little over the
   header's real height so the crumb clears it without JavaScript. */
body{padding-top:92px}
@media (max-width:600px){body{padding-top:84px}}

/* Button roles the shared header needs and only book.css otherwise defines. */
.btn--primary{background:var(--accent);color:var(--on-accent)}
.btn--primary:hover{background:var(--accent-hi);color:var(--on-accent)}

/* ---------- content ---------- */
.crumb{font-size:13px;color:var(--muted-2);padding-top:26px}
.page-aside{padding-top:0}
.crumb a{color:var(--muted-2)}
.crumb a:hover{color:var(--accent)}

.hero{padding:18px 0 8px}
.hero h1{font-size:clamp(30px,5vw,46px)}
.hero .lede{margin-top:18px;font-size:clamp(17px,2vw,19px);color:var(--muted)}

.sec{padding:34px 0;border-top:1px solid var(--line);margin-top:34px}
.sec:first-of-type{border-top:0;margin-top:0}
.sec h2{font-size:clamp(22px,3vw,29px);margin-bottom:16px}
.sec h3{font-size:17px;margin:24px 0 8px}
.sec p + p{margin-top:14px}
.sec p{color:var(--muted)}

.ticks{list-style:none;padding:0;margin-top:16px;display:flex;flex-direction:column;gap:11px}
.ticks li{position:relative;padding-left:28px;color:var(--muted)}
.ticks li::before{content:"";position:absolute;left:4px;top:.62em;width:9px;height:9px;
  border-radius:50%;background:var(--accent)}

.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px;padding:0;list-style:none}
.chips li{border:1px solid var(--line-strong);border-radius:999px;padding:7px 14px;
  font-size:13.5px;color:var(--muted)}

/* Hub list: the link carries the weight, the summary underneath is what makes
   the hub worth landing on rather than a bare index of names. */
.hub-list{list-style:none;padding:0;margin-top:20px;display:grid;gap:2px;
  border-top:1px solid var(--line)}
.hub-list li{padding:15px 0;border-bottom:1px solid var(--line)}
.hub-list a{font-weight:700;font-size:16.5px}
.hub-list span{display:block;margin-top:4px;color:var(--muted);font-size:14.5px;line-height:1.55}
@media (min-width:760px){.hub-list{grid-template-columns:1fr 1fr;column-gap:clamp(24px,3vw,44px)}}

/* Pricing bands. The price is the biggest thing in the card because that is
   what the reader came for, but the scope sits directly under it so the number
   is never read on its own. */
.price-note{margin-top:22px;padding:14px 18px;border:1px solid var(--line-strong);
  border-radius:12px;background:var(--accent-soft);font-size:14.5px;color:var(--muted)}
.price-note strong{color:var(--text)}
.bands{display:grid;gap:16px;margin-top:22px;grid-template-columns:1fr}
@media (min-width:640px){.bands{grid-template-columns:1fr 1fr}}
.band{border:1px solid var(--line-strong);border-radius:14px;padding:22px}
.band--fixed{border-color:var(--accent);background:var(--accent-soft)}
.band h3{font-size:16px;margin-bottom:6px}
.band-price{font-size:clamp(28px,4vw,36px);font-weight:800;letter-spacing:-.03em;
  color:var(--accent);line-height:1.05;margin:0}
.band-scope{font-size:13px;letter-spacing:.08em;text-transform:uppercase;
  font-weight:700;color:var(--muted-2);margin-top:8px}
.band-best{margin-top:12px;font-size:15px}
.band-note{margin-top:10px;font-size:14px;color:var(--muted-2)}
.band-foot{margin-top:18px;font-size:14.5px;color:var(--muted)}
/* The invasive line sits at the foot of every card, separated by a rule so it
   reads as a condition of the price rather than as part of the description. */
.band-extra{margin-top:14px;padding-top:12px;border-top:1px solid var(--line);
  font-size:13.5px;line-height:1.5;color:var(--muted-2)}

/* These pages had no reduced motion rule of their own. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
  html{scroll-behavior:auto}
}

.qa{border-top:1px solid var(--line);padding:18px 0}
.qa summary{cursor:pointer;font-weight:700;font-size:16.5px;list-style:none}
.qa summary::-webkit-details-marker{display:none}
.qa[open] summary{color:var(--accent)}
.qa p{margin-top:12px}

/* ---------- two column layout: content left, booking form sticky right ----------
   The content keeps the order and shape it had. The form moves alongside it and
   follows the visitor down the page, so there is no scroll back to enquire.

   Below 1080px there is nowhere to put a sidebar, so it becomes a single column
   with the form after the content, and a fixed action bar gives a way to reach
   it from anywhere on the page. */
.page{display:grid;gap:clamp(28px,4vw,56px);grid-template-columns:minmax(0,1fr);
  padding-bottom:var(--bar-h,0px)}
.page-main{min-width:0}

@media (min-width:1080px){
  .page{grid-template-columns:minmax(0,1fr) 390px}
  /* The padding lines the form up with the breadcrumb rather than sitting
     tight under the header, and is what sticky then scrolls it out of.
     The header is fixed, so sticking at the top of the viewport would park the
     form underneath it: --head-h is what menu.js measures it as. */
  .page-aside{align-self:start;position:sticky;top:calc(var(--head-h,72px) + 24px);
    padding-top:26px;
    /* The form outgrew the viewport. Step 3 with the optional sections open is
       taller than a laptop screen, and a sticky block taller than the space it
       sticks in has its bottom pinned off screen: Book My Survey could only be
       reached by scrolling the whole article past the form first. So the column
       scrolls on its own, independently of the page beside it. */
    max-height:calc(100vh - var(--head-h,72px) - 48px);
    overflow-y:auto;
    /* Reaching the end of the form should not then start scrolling the article
       underneath. Two scrollers in one view are only tolerable if they stay out
       of each other's way. */
    overscroll-behavior:contain;
    /* The card's shadow reaches a few pixels to the sides and about 35 below,
       and overflow clips anything outside the box. Widened to make room, then
       pulled back by the same amount so the column still lines up. */
    padding-inline:8px;margin-inline:-8px;padding-bottom:36px}
}

.booking{margin-top:26px}
.booking h2{font-size:19px;margin-bottom:10px}
.booking > p{color:var(--muted);font-size:14.5px;margin-bottom:16px}
@media (min-width:1080px){ .booking{margin-top:0} }

/* ---------- mobile action bar ---------- */
.action-bar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:70;
  background:var(--bg-2);border-top:1px solid var(--line-strong);
  padding:10px 14px calc(10px + env(safe-area-inset-bottom));gap:10px}
.action-bar .btn{flex:1;min-height:52px;font-size:15px;padding:0 14px;margin-top:0}
.action-bar .btn--ghost{background:transparent;border:1px solid var(--line-strong);color:var(--text)}
.action-bar .btn--ghost:hover{background:var(--card);color:var(--text)}
@media (max-width:1079px){
  .action-bar{display:flex}
  body{--bar-h:78px}
  html{scroll-padding-top:20px}
}

/* ---------- footer ---------- */
.afoot{border-top:1px solid var(--line);background:var(--bg-2);margin-top:50px;
  padding:30px 0;font-size:13.5px;color:var(--muted-2)}
.afoot .wrap{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap}
.afoot a{color:var(--muted-2)}
.afoot a:hover{color:var(--accent)}

/* SurveyMate verified badge, under the booking form in the sidebar. */
.smate-badge{display:block;margin-top:18px;text-align:center;line-height:0}
.smate-badge img{display:inline-block;width:200px;height:64px}

/* WhatsApp chat button, for a brand that has a number for it. Sits above the
   mobile action bar rather than on top of it. */
.wa-float{position:fixed;right:18px;bottom:88px;z-index:40;width:56px;height:56px;border-radius:50%;display:grid;place-items:center;
  background:#25d366;color:#fff;box-shadow:0 10px 26px -10px rgba(0,0,0,.6)}
.wa-float:hover{color:#fff;transform:translateY(-1px)}
@media (min-width:900px){.wa-float{bottom:24px}}

/* A service's typical price range, and real reviews, on service pages. */
.price-range{font-size:clamp(26px,3.4vw,34px);font-weight:800;letter-spacing:-.01em;margin:4px 0 8px}
.price-range span{font-size:15px;font-weight:600;color:var(--muted)}
.quote-card{margin:0 0 14px;padding:16px 18px;background:var(--card);border:1px solid var(--line);border-radius:12px}
.quote-card p{margin:0 0 8px}
.quote-card cite{font-style:normal;font-size:14px;color:var(--muted-2)}
/* The in-season feature (scripts/season.js). */
.season-feature{margin-top:18px;padding:12px 16px;background:rgba(127,127,127,.08);border-radius:6px}
.season-feature a{margin-right:6px}

/* Footer list of every area page, grouped (scripts/footer-areas.js). */
.foot-areas{flex-basis:100%;display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:18px 26px;padding:0 0 22px;margin-bottom:18px;border-bottom:1px solid var(--line);font-size:13px}
.foot-areas ul{list-style:none;margin:0;padding:0}
.foot-areas li{margin:3px 0}
.foot-areas-h{font-weight:600;margin:0 0 6px;color:var(--text)}
.steps{padding-left:1.2em}
.steps li{margin:6px 0}
/* Price and Book button in the first screen of every town page. */
.hero-cta{margin-top:20px;display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center}
.hero-price{color:var(--muted);font-size:15px}
.band-timber{margin-top:8px;font-size:15px}
.extras-wrap{overflow-x:auto;margin-top:16px}
.extras{width:100%;border-collapse:collapse;font-size:15px}
.extras th,.extras td{text-align:left;padding:12px 10px;border-bottom:1px solid var(--line-strong);vertical-align:top}
.extras td{white-space:nowrap;font-weight:700}
.extras tbody th{font-weight:700}
.extras small{display:block;font-weight:400;color:var(--muted-2);margin-top:4px;font-size:13px}
.price-table td{font-size:18px}
.extras-h{margin-top:26px}
.more .qa h3{font-size:15px;margin:14px 0 4px}
