/* Groundwater Pros — shared design system.
   Extracted verbatim from the approved homepage so every page matches.
   fonts.css is linked directly from each page's <head> (not @import'd from here) so the
   browser can discover and fetch it in parallel with this file instead of waiting for
   this file to load first. */
:root{
  /* Colour system sampled directly from logo-badge.png:
     logo blue #0166EE · logo navy hue ~222deg (#030A1A core) */
  --stone-050:#F7F8FA; --stone-100:#EEF1F4; --stone-200:#E0E4EA; --stone-300:#CBD2DB;
  --navy-950:#04091A; --navy-900:#08132A; --navy-800:#0C1C3A; --navy-700:#14315E;
  --blue-700:#023E92; --blue-600:#0357C6; --blue-500:#0A6EF0; --blue-400:#3B8EFF;
  --ink:#0B1420; --body:#434b57;
  --disp:'Oswald','Arial Narrow',sans-serif;
  --sans:'Barlow','Helvetica Neue',Arial,sans-serif;
  --pad:clamp(18px,3vw,56px);
  --max:1460px;
  /* real photographed granite texture (Higgsfield-generated), tiled — replaces the earlier
     procedural SVG noise which read as uniform "glitter" instead of actual stone grain */
  --granite:url('granite-texture.jpg');
  /* shared premium photo grade — cools + tightens contrast so every photo on the
     site reads like one shoot instead of raw, oversaturated phone camera jpgs */
  --grade:saturate(.82) contrast(1.07) brightness(.97);
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font-family:var(--sans);color:var(--ink);background:#fff;line-height:1.5;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
.bleed{padding-left:var(--pad);padding-right:var(--pad)}
/* Skip-to-content: invisible until keyboard-focused, then drops into view above the
   sticky header so keyboard/screen-reader users can bypass nav. No visual change for
   mouse/touch users — purely an a11y addition, not a design change. */
.skip-link{position:absolute;left:12px;top:-60px;z-index:200;background:var(--navy-950);color:#fff;padding:12px 18px;border-radius:6px;font-family:var(--disp);text-transform:uppercase;letter-spacing:.05em;font-weight:600;font-size:.9rem;transition:top .15s ease}
.skip-link:focus{top:12px}
.cap{max-width:var(--max);margin:0 auto}
h1,h2,h3,.disp{font-family:var(--disp);text-transform:uppercase;letter-spacing:.006em;line-height:.94}
.mbr{display:inline}
.eyebrow{font-family:var(--disp);text-transform:uppercase;letter-spacing:.14em;font-weight:700;font-size:.82rem;color:var(--blue-500)}

.btn{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--disp);text-transform:uppercase;letter-spacing:.05em;font-weight:600;font-size:clamp(.9rem,1vw,1.06rem);padding:.82rem 1.6rem;border-radius:5px;border:0;cursor:pointer;transition:.18s}
.btn-blue{background:var(--blue-500);color:#fff;box-shadow:0 10px 22px rgba(20,58,107,.3)}
.btn-blue:hover{background:var(--blue-400);transform:translateY(-2px)}
.btn-white{background:#fff;color:var(--navy-900)}
.btn-white:hover{background:var(--stone-100);transform:translateY(-2px)}
.btn-lg{font-size:clamp(1rem,1.16vw,1.2rem);padding:1rem 1.9rem}
.link{font-family:var(--disp);text-transform:uppercase;letter-spacing:.14em;font-weight:700;color:var(--blue-400);font-size:.82rem;display:inline-flex;align-items:center;gap:6px}
.link:hover{gap:11px;color:var(--blue-500)}
.link-pending{cursor:default;color:#8a94a6}.link-pending:hover{gap:6px;color:#8a94a6}
.btn-pending{cursor:default}.btn-pending:hover{background:var(--blue-500);transform:none}

/* ===== HEADER — compact, balanced logo ===== */
/* Dark header so the bar reads as one piece with the hero rather than a white
   contractor-template strip sitting on top of a photograph. Structure unchanged. */
.header{position:sticky;top:0;z-index:60;background:var(--navy-950);border-bottom:1px solid rgba(43,131,255,.16);box-shadow:0 2px 26px rgba(0,0,0,.4)}
.header .cap{display:flex;align-items:center;gap:20px;height:clamp(84px,7.2vw,108px);padding-left:var(--pad);padding-right:var(--pad)}
.brand{flex:none;display:flex;align-items:center}
.brand img{height:clamp(58px,5.4vw,80px);width:auto;filter:drop-shadow(0 2px 14px rgba(120,170,255,.18))}
.nav{display:flex;align-items:center;gap:clamp(16px,2.2vw,40px);margin-left:auto;font-family:var(--disp);text-transform:uppercase;font-weight:600;font-size:clamp(.8rem,1vw,1.05rem);letter-spacing:.09em}
.nav a{color:#c3cede;padding:5px 0;white-space:nowrap;border-bottom:2px solid transparent}
.nav a:hover,.nav a.on{color:#fff;border-color:var(--blue-400)}
.hphone{display:none;align-items:center;font-family:var(--disp);font-weight:700;font-size:clamp(1.45rem,1.78vw,1.92rem);color:#fff;white-space:nowrap}
.hphone:hover{color:var(--blue-400)}
.nav-toggle{display:none;flex:none;align-items:center;justify-content:center;width:44px;height:44px;background:transparent;border:0;cursor:pointer}
.nav-toggle span{position:relative;display:block;width:22px;height:2px;background:#fff;border-radius:2px;transition:background-color .15s .15s}
.nav-toggle span::before,.nav-toggle span::after{content:"";position:absolute;left:0;width:22px;height:2px;background:#fff;border-radius:2px;transition:top .15s .15s,transform .15s}
.nav-toggle span::before{top:-7px}
.nav-toggle span::after{top:7px}
.nav-toggle[aria-expanded="true"] span{background:transparent}
.nav-toggle[aria-expanded="true"] span::before{top:0;transform:rotate(45deg);transition:top .15s,transform .15s .15s}
.nav-toggle[aria-expanded="true"] span::after{top:0;transform:rotate(-45deg);transition:top .15s,transform .15s .15s}

/* ===== SCROLL-REVEAL + HERO MOTION — plain CSS/JS, no framework ===== */
@media(prefers-reduced-motion:no-preference){
  [data-reveal]{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s ease}
  [data-reveal].is-visible{opacity:1;transform:none}
  .cards[data-reveal] .card,.card[data-reveal]{transition-delay:calc(var(--rd,0) * 90ms)}
  .cards .card:nth-child(1){--rd:0}.cards .card:nth-child(2){--rd:1}
  .cards .card:nth-child(3){--rd:2}.cards .card:nth-child(4){--rd:3}
  /* Zoom range halved (was 1 -> 1.06) — the source photo (hero-desktop-faded.jpg, 1672x941)
     is already being upscaled by background-size:cover on most real screens, and the extra
     6% zoom was compounding that softness at the peak of the cycle. This is a stopgap, not
     a fix — the real fix is a higher-resolution source photo; see project notes. */
  .hero-bg{animation:heroZoom 24s ease-in-out infinite alternate}
}
@keyframes heroZoom{from{transform:scale(1)}to{transform:scale(1.03)}}

/* ===== HERO ===== */
.hero{position:relative;min-height:min(clamp(440px,56.4vw,1000px),calc(100vh - 124px));background:var(--navy-950);overflow:hidden}
.hero-bg{position:absolute;inset:0;background:url('hero-desktop-faded.jpg?v=9') no-repeat;background-size:cover;background-position:center 50%;filter:var(--grade)}
/* Two stacked scrims: a top fade that ties the dark header into the photo, and a
   left-to-right scrim that clears by ~68% so the rig stays the bright focal point.
   Strengthened for the higher-res hero photo, which reads hazy/flat across the sky
   and mountains without it — this also lifts text contrast over that same area. */
.hero-bg::after{content:"";position:absolute;inset:0;background:
  linear-gradient(180deg,rgba(3,7,18,.72) 0%,rgba(3,7,18,.32) 16%,rgba(3,7,18,.08) 30%,rgba(3,7,18,0) 42%),
  linear-gradient(100deg,rgba(3,7,18,.68) 0%,rgba(3,7,18,.42) 26%,rgba(3,7,18,.14) 50%,rgba(3,7,18,0) 70%)}
.hero-inner{position:relative;z-index:2;max-width:var(--max);margin:0 auto;padding:0 var(--pad);min-height:inherit;display:flex;align-items:center}
.hero-copy{max-width:clamp(320px,53vw,790px);padding:clamp(18px,2.4vw,34px) 0 clamp(56px,7vw,104px)}
.hero-copy>*{text-shadow:0 2px 22px rgba(3,7,18,.62)}
/* small technical rule above the eyebrow — the one piece of industrial detailing */
.hero .eyerule{display:block;width:52px;height:3px;background:var(--blue-500);margin-bottom:clamp(14px,1.5vw,20px);box-shadow:0 0 18px rgba(43,131,255,.55)}
.hero .kick{font-family:var(--disp);text-transform:uppercase;letter-spacing:.22em;font-weight:700;font-size:clamp(.86rem,1.3vw,1.3rem);color:var(--blue-500);text-shadow:0 1px 3px rgba(3,7,18,.85)}
.hero h1{font-size:clamp(2.4rem,6.3vw,6.3rem);font-weight:700;line-height:1.02;color:#fff;margin:clamp(14px,1.5vw,21px) 0 0;white-space:normal}
.hero .rp{font-family:var(--sans);text-transform:none;letter-spacing:0;font-weight:400;line-height:1.58;font-size:clamp(1.04rem,1.3vw,1.3rem);color:#e6eef8;max-width:42ch;margin-top:clamp(17px,1.9vw,26px);text-shadow:0 1px 3px rgba(3,7,18,.9),0 2px 20px rgba(3,7,18,.6)}
.hero-act{display:flex;flex-direction:column;align-items:flex-start;gap:clamp(15px,1.6vw,21px);margin-top:clamp(26px,3vw,40px)}

/* ===== TRUST BAR ===== */
/* ==========================================================================
   HERO PROOF STRIP — SITE-WIDE STANDARD (documented 2026-08-31)
   ==========================================================================
   This is the reference implementation of the "hero proof strip": the row of
   credibility markers that sits directly under every page's hero (here it's
   .trust; on the 4 service pages it's the .svc-intro-facts / .svc-fact-row /
   .svc-credential-list area inside .svc-intro — see service-page.css and each
   page's page-scoped <style> block). The owner has flagged this element
   looking a different size from page to page more than once. It shouldn't —
   these are the values every version of it should match, since .trust is the
   oldest/most established implementation on the site:

     DESKTOP (~1440px reference)
       - outer vertical rhythm: ~48-49px section padding on the service pages'
         .svc-intro (var(--svc-py-lg)); .trust's own .cap padding is
         clamp(11px,1.2vw,17px) — resolves to 17px top/bottom at this width.
       - secondary/proof-point text: .72rem (11.52px) — this is the size used
         for de-emphasized fact/credential text (.svc-fact span on Well
         Drilling, Hydrofracking, and Water Filtration). Primary credential
         labels (.svc-credential-head span) run larger, 1.15rem (18.4px).
       - de-emphasis: secondary fact rows sit at opacity:.82 on the service
         pages (.svc-fact-row{opacity:.82}) so the primary credential/callout
         content reads first.
       - icon size 26x26 (.trust .ic), Google mark 30x30 (.trust .gmark).
       - item gap 10px; row/column gap between stacked fact groups: 24px
         (.svc-intro-facts{gap:1.5rem}).

     MOBILE (375px reference)
       - .cap padding: 11px 18px (.trust); service-page equivalent section
         padding: clamp(1.4rem,6vw,1.9rem) 0.
       - item padding: 11px 0; item gap: 9px.
       - label/credential text: .9rem (14.4px); do not let this drop below
         .78rem or grow past 1rem — that's the range already in use.
       - EVERY page must show *something* in this strip on mobile — never let
         it collapse to empty padding. (A 2026-08-31 audit found Water
         Filtration's mobile proof area was empty — 17px of dead padding and
         nothing else — because its callout, fact-row, AND fact-line were all
         hidden with no credential-block fallback like the other 3 service
         pages have. Fixed by showing .svc-fact-line at .9rem/#c7d3de instead
         of leaving it display:none. See body.svc-water-filtration
         .svc-fact-line in services/water-filtration/index.html.)

   The 4 service pages' equivalent element should match these values. Minor
   deviation is fine when a page's content genuinely differs (e.g. Pump
   Service's .svc-fact-row uses a bordered checklist-card treatment instead of
   the plain 3-column grid — that's a deliberate, documented wrapping fix, not
   drift) — but font-size, color tokens, and the de-emphasis opacity should
   stay identical unless there's a documented reason, so a page never *reads*
   larger or smaller than its siblings when a user scrolls between them.
   Before shipping a change to any hero proof strip, measure it (getBounding-
   ClientRect / getComputedStyle) at 375px and 1440px and diff it against
   these numbers rather than eyeballing it.
   ========================================================================== */
/* off-white to match the reviews panel — pure #fff was the only stark surface on the page.
   The blue top rule mirrors the header’s bottom rule, so the hero photo is bracketed by
   matching brand hairlines instead of running into raw white. */
.trust{background-color:#0A1B38;background-image:linear-gradient(140deg,#071126 0%,#153A6B 52%,#0A1B38 100%);border-top:1px solid rgba(43,131,255,.16);border-bottom:1px solid rgba(43,131,255,.16)}
.trust .cap{display:grid;grid-template-columns:repeat(4,1fr);padding:clamp(11px,1.2vw,17px) var(--pad)}
.trust .item{display:flex;align-items:center;gap:10px;padding:2px clamp(12px,1.8vw,32px);border-left:1px solid rgba(255,255,255,.16)}
.trust a.item{color:inherit;text-decoration:none;transition:opacity .18s}
.trust a.item:hover{opacity:.8}
.trust .item:first-child{border-left:0;padding-left:0}
.trust .gmark{width:30px;height:30px;flex:none}
.trust .ic{width:26px;height:26px;flex:none;color:var(--blue-500);stroke-width:1.7}
.trust .score{font-family:var(--disp);font-weight:700;font-size:1.7rem;color:#fff;line-height:1}
.trust .stars{color:#E8A100;font-size:1.18rem;letter-spacing:1.5px}
.trust .sub{font-size:.86rem;color:#c9d5e6;display:block;white-space:nowrap;margin-top:1px}
.trust b{font-family:var(--disp);text-transform:uppercase;font-size:.95rem;color:#fff;line-height:1.06;display:block}
.trust span.t{font-size:.78rem;color:#c9d5e6;line-height:1.3;display:block}

/* ===== SECTION HEADS ===== */
/* Switched to a light stone panel (2026-09-17, owner feedback: two rounds of shading
   within the navy family still read as too subtle -- same-hue luminance shifts are hard
   to see without a hard reference point). Matches the .revs panel's stone-100 treatment
   elsewhere on this page, giving this section genuine, unmistakable contrast against the
   dark hero/cards above and the dark .why section below, instead of another shade of navy. */
.sec{padding:clamp(34px,3.4vw,58px) 0;background:var(--stone-100)}
.head-c{max-width:900px;margin:0 auto clamp(20px,2.1vw,32px);text-align:center}
.sec .head-c .eyebrow{color:var(--blue-400);margin-bottom:clamp(8px,.85vw,12px);display:block}
.titlerow{display:flex;align-items:center;justify-content:center;gap:clamp(14px,2vw,28px)}
.titlerow .ln{flex:0 0 clamp(30px,4vw,64px);height:2px;background:linear-gradient(90deg,transparent,var(--blue-500))}
.titlerow .ln:last-child{background:linear-gradient(90deg,var(--blue-500),transparent)}
.head-c h2{font-size:clamp(1.8rem,3vw,2.9rem);font-weight:700;color:var(--ink);white-space:nowrap}
.head-c p{color:var(--body);font-size:clamp(.95rem,1.06vw,1.08rem);margin-top:8px}

/* ===== SERVICE CARDS — clean, photo-led, no icon ===== */
.cards{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:1fr;gap:clamp(12px,1.3vw,22px)}
.card{position:relative;border-radius:8px;overflow:hidden;background:var(--navy-900);border:1px solid rgba(140,175,225,.13);box-shadow:0 10px 26px rgba(11,20,32,.12);display:flex;flex-direction:column;transition:.25s}
.card:hover{transform:translateY(-4px);border-color:rgba(43,131,255,.42);box-shadow:0 16px 34px rgba(11,20,32,.18)}
/* primary service — a single hairline of blue, no badge */
.card-lead::after{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--blue-500);z-index:3}
/* aspect-ratio box + object-fit:cover => photo scales with the card and can never stretch */
.card .ph{aspect-ratio:23/20;overflow:hidden;position:relative;flex:none}
.card .ph img{width:100%;height:100%;object-fit:cover;object-position:center 42%;transition:.55s;filter:var(--grade)}
.card .ph img.img-frack{object-position:center;filter:var(--grade) brightness(1.12)}
.card .ph img.img-drill{object-position:50% 95%}
.card .ph::after{content:"";position:absolute;inset:0;background:rgba(6,14,32,.14);mix-blend-mode:multiply;pointer-events:none}
.card:hover .ph img{transform:scale(1.06)}
.card .cbody{background:var(--navy-900);color:#fff;padding:clamp(13px,1.15vw,17px) clamp(14px,1.25vw,19px) clamp(14px,1.2vw,18px);flex:1;display:flex;flex-direction:column}
.card h3{font-size:clamp(1rem,1.24vw,1.28rem);font-weight:600;color:#fff}
.card .ul{width:30px;height:3px;background:var(--blue-500);margin:7px 0 8px}
.card p{font-family:var(--sans);text-transform:none;color:#aebbcb;font-size:clamp(.84rem,.92vw,.94rem);line-height:1.45;margin-bottom:12px}
.card .link{margin-top:auto}
.hero-cta{margin-top:0;padding:.9rem 1.7rem;text-shadow:none;background-image:linear-gradient(115deg,var(--blue-600),var(--blue-500) 55%,var(--blue-500));box-shadow:0 10px 24px rgba(3,20,45,.4),0 0 0 rgba(94,169,255,0);transition:box-shadow .25s ease,transform .18s ease,background-image .25s ease}
.hero-cta:hover{background-image:linear-gradient(115deg,var(--blue-500),var(--blue-500) 55%,var(--blue-400));box-shadow:0 10px 26px rgba(3,20,45,.45),0 0 26px 4px rgba(59,142,255,.5);transform:translateY(-2px)}

/* ===== NORTH GEORGIA SERVICE AREA — terrain plate + real-coordinate location layer ===== */
.area{position:relative;overflow:hidden;background:#0A1526}
/* Brightened 2026-09-17 (owner feedback: the map read almost as dark as the footer).
   brightness(1.13) lifts terrain midtone/shadow detail roughly the requested 10-15%;
   saturate(1.06) keeps the lifted image reading as rich navy/charcoal/blue rather than
   washed-out grey. Photo itself is untouched — this is a live filter, not a re-export. */
.area-bg{position:absolute;inset:0;background:url('north-georgia-terrain-desktop.jpg') center/cover no-repeat;filter:brightness(1.24) saturate(1.1)}
/* scrim sits behind the stacked heading + paragraph at the top; clears before the full-width map below.
   Strength reduced ~30% relative (2026-09-17) to match the brighter terrain underneath — the heading/
   copy keep their own text-shadow (below) to stay readable with a lighter scrim behind them. */
.area-bg::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(6,14,28,.30) 0%,rgba(6,14,28,.19) 22%,rgba(6,14,28,.07) 40%,rgba(6,14,28,0) 54%)}
.area .cap{position:relative;z-index:2;padding:clamp(34px,3.4vw,58px) var(--pad);min-height:clamp(400px,34vw,540px)}
/* text-shadow added 2026-09-17 alongside the scrim reduction above, so the heading/copy
   stay just as readable against the now-lighter, brighter terrain photo. */
.area .head-c h2{color:#fff;text-shadow:0 2px 14px rgba(3,7,18,.65)}
.area-grid{display:flex;flex-direction:column;gap:0}
.area-copy{text-align:center}
.area-map{position:relative}
.area h2{font-size:clamp(1.8rem,3vw,2.9rem);font-weight:700;line-height:1.02}
.area-copy>p{font-family:var(--sans);color:#d7e1f0;font-size:clamp(1rem,1.15vw,1.15rem);line-height:1.55;max-width:900px;margin-top:0;text-shadow:0 1px 10px rgba(3,7,18,.6)}
.area-515{font-family:var(--sans);color:#d7e1f0;font-size:clamp(1rem,1.15vw,1.15rem);line-height:1.55;max-width:900px;margin:0 auto;text-shadow:0 1px 10px rgba(3,7,18,.6)}
.area-map svg{width:100%;height:auto;overflow:visible}
.map-note{display:block;position:absolute;left:16px;right:16px;bottom:12px;z-index:3;text-align:center;font-family:var(--sans);
  background:rgba(4,9,20,.68);border-radius:10px;padding:10px 14px;backdrop-filter:blur(2px)}
.map-note strong{display:block;font-family:var(--disp);text-transform:uppercase;letter-spacing:.08em;font-weight:600;font-size:clamp(1rem,1.3vw,1.3rem);color:#fff;text-shadow:0 1px 7px rgba(3,7,18,.95)}
.map-note span{display:block;font-size:clamp(.95rem,1.1vw,1.1rem);color:#eef4fb;line-height:1.4;margin-top:2px;text-shadow:0 1px 7px rgba(3,7,18,.95)}
.area-map .map-wide{display:block}
.area-map .map-narrow{display:none}
.area-map .halo{fill:rgba(43,131,255,.16);stroke:rgba(43,131,255,.4);stroke-width:1.5}
.area-map .corridor{fill:none;stroke:var(--blue-400);stroke-width:1.6;stroke-opacity:.35;stroke-linecap:round;filter:blur(1.8px)}
.area-map .pt{fill:var(--blue-400);stroke:rgba(255,255,255,.9);stroke-width:1.5}
.area-map .pt.t1{fill:#fff;stroke:var(--blue-500);stroke-width:4}
.area-map .pt.t3{fill:rgba(140,190,255,.9);stroke:rgba(255,255,255,.55);stroke-width:1}
/* Stroke bumped slightly (3.4->3.8, .72->.8 opacity) 2026-09-17 to hold the same
   readability against the brighter terrain photo above. */
.area-map .lb{font-family:var(--disp);text-transform:uppercase;letter-spacing:.05em;fill:#fff;paint-order:stroke;stroke:rgba(4,10,22,.85);stroke-width:4;stroke-linejoin:round}
.area-map .lb.t1{font-weight:700;letter-spacing:.09em}
.area-map .lb.t2{font-weight:600;fill:#eaf1fb}
.area-map .lb.t3{font-weight:400;fill:#cbdaee;letter-spacing:.03em}
.area-map .sub{font-family:var(--disp);text-transform:uppercase;letter-spacing:.16em;font-weight:600;fill:var(--blue-400);paint-order:stroke;stroke:rgba(4,10,22,.72);stroke-width:3;stroke-linejoin:round}
/* Clickable map towns (2026-09-17) — wraps just the dot + label for the towns that have
   an existing /service-areas/ page; every other town on the map stays plain, non-interactive
   text exactly as before. Subtle hover/focus state only (no popup/tooltip/modal, no change
   to the map's default appearance) so it's clear these are links without redesigning the map. */
.area-map a.town-link{cursor:pointer}
.area-map a.town-link:hover .pt,
.area-map a.town-link:focus-visible .pt{stroke:var(--blue-400);stroke-width:2.6}
.area-map a.town-link:hover .pt.t1,
.area-map a.town-link:focus-visible .pt.t1{stroke-width:5.5}
.area-map a.town-link:hover .lb,
.area-map a.town-link:focus-visible .lb{fill:var(--blue-400)}
.area-map a.town-link:focus-visible{outline:2px solid var(--blue-400);outline-offset:3px;border-radius:4px}
/* Desktop-only: the town network read too small/thin against the large terrain canvas.
   Circle/font sizes were bumped in the markup itself (~15-20%, larger for the smaller t3
   labels specifically per readability feedback); these outline/fill tweaks scale the
   stroke weights and secondary-label contrast to match, without touching mobile (already
   dense) or moving any town's cx/cy/x/y. */
@media(min-width:1041px){
  .area-map .pt{stroke-width:1.6}
  .area-map .pt.t1{stroke-width:4.5}
  .area-map .pt.t3{stroke-width:1.2}
  .area-map .lb{stroke-width:4}
  .area-map .lb.t3{fill:#cdddf2;font-weight:500}
  .area-map .corridor{stroke-width:1.9;stroke-opacity:.45;filter:blur(1.4px)}
}

/* ===== WHY US — the answer band. Diagonal navy gradient: distinct from the flat
   navy services above and from the blue CTA below. Blue hairlines top and bottom. ===== */
.why{background-color:#0A1B38;background-image:linear-gradient(140deg,#071126 0%,#153A6B 52%,#0A1B38 100%);
  border-top:1px solid rgba(43,131,255,.16);border-bottom:1px solid rgba(43,131,255,.16);
  padding:clamp(34px,3.4vw,58px) 0}
.why .head-c .eyebrow{display:block;color:var(--blue-400);margin-bottom:clamp(8px,.85vw,12px)}
.why .head-c h2{color:#fff}
.why-sub{text-align:center;font-family:var(--sans);color:#c9d5e6;font-size:clamp(1rem,1.15vw,1.15rem);max-width:54ch;margin:0 auto clamp(24px,2.6vw,40px)}
.why-sub2{display:none}
.why-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(18px,2.6vw,48px);max-width:1180px;margin:0 auto}
.wcol .num{font-family:var(--disp);font-weight:700;font-size:clamp(1.5rem,1.9vw,1.9rem);color:var(--blue-400);display:block;line-height:1}
.wcol h3{font-size:clamp(1.05rem,1.3vw,1.3rem);font-weight:600;color:#fff;margin:10px 0 8px}
.wcol p{font-family:var(--sans);text-transform:none;color:#c3d0e2;font-size:clamp(.92rem,1.02vw,1.04rem);line-height:1.55}

/* ===== REVIEWS — carousel, deliberately LIGHT against the dark section above ===== */
.revs{padding:clamp(34px,3.4vw,58px) 0;background:var(--stone-100)}
.revs .head-c .eyebrow{display:block;margin-bottom:clamp(8px,.85vw,12px)}
.rcar{position:relative;max-width:1120px;margin:0 auto;display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:clamp(6px,1.2vw,20px)}
.rviewport{overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}
.rviewport::-webkit-scrollbar{display:none}
.rtrack{display:flex;align-items:stretch}
.rslide{flex:0 0 100%;scroll-snap-align:center;background:#fff;border:1px solid var(--stone-200);border-radius:10px;
  padding:clamp(16px,1.8vw,26px) clamp(18px,2.4vw,40px) clamp(16px,1.7vw,24px);text-align:left;
  display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;box-shadow:0 10px 30px rgba(11,27,52,.07)}
.rhead{display:flex;align-items:center;flex-wrap:wrap;gap:6px 12px;margin-bottom:clamp(9px,1vw,13px)}
.rname{font-family:var(--disp);text-transform:uppercase;letter-spacing:.07em;font-weight:600;font-size:.92rem;color:var(--navy-800)}
.rhead .stars{color:#f4b400;font-size:.98rem;letter-spacing:2px;line-height:1}
.rsrc{font-family:var(--sans);font-size:.72rem;color:#98a0ab;flex-basis:100%;margin-top:-2px}
.rslide .quote{font-family:var(--sans);font-style:italic;color:#2c3543;font-size:clamp(.96rem,1.1vw,1.1rem);line-height:1.6}
.rslide .quote.clamped{display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical;overflow:hidden}
.rmore{margin-top:10px;align-self:flex-start;background:none;border:0;padding:4px 2px;cursor:pointer;font-family:var(--disp);text-transform:uppercase;
  letter-spacing:.14em;font-weight:700;font-size:.82rem;color:var(--blue-500);border-bottom:1px solid rgba(1,102,238,.4);transition:.18s}
.rmore:hover{color:var(--blue-600);border-bottom-color:var(--blue-600)}
.rnav{width:clamp(38px,3.1vw,46px);height:clamp(38px,3.1vw,46px);border-radius:50%;background:#fff;border:1px solid var(--stone-300);
  color:var(--navy-900);font-family:var(--disp);font-size:1.55rem;line-height:0;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:.18s;flex:none}
.rnav:hover:not(:disabled){background:var(--blue-500);border-color:var(--blue-500);color:#fff}
.rnav:disabled{opacity:.32;cursor:default}
.rdots{grid-column:1/-1;display:flex;justify-content:center;gap:8px;margin-top:clamp(9px,1vw,13px)}
.rdot{width:7px;height:7px;padding:0;border:0;border-radius:50%;background:#c3cbd6;cursor:pointer;transition:.2s}
.rdot:hover{background:#a9b3c0}
.rdot.is-on{background:var(--blue-500);width:17px;border-radius:4px}
.rlink{text-align:center;margin-top:clamp(9px,1vw,13px)}
.rgoogle{display:inline-flex;align-items:center;gap:9px;font-family:var(--disp);text-transform:uppercase;letter-spacing:.14em;font-weight:700;font-size:.82rem;color:var(--blue-500)}
.rgoogle:hover{color:var(--blue-600)}
.rgoogle .gmark{width:18px;height:18px;flex:none}
@media(prefers-reduced-motion:reduce){.rviewport{scroll-behavior:auto}}

/* ===== FINAL CTA — simplified ===== */
.fcta{background-color:var(--navy-800);background-image:linear-gradient(115deg,var(--navy-800),var(--blue-600) 60%,var(--navy-800));color:#fff}
.fcta .cap{display:flex;align-items:center;justify-content:center;text-align:center;gap:clamp(18px,3vw,50px);flex-wrap:wrap;padding:clamp(34px,3.4vw,58px) var(--pad)}
.fcta h2{font-size:clamp(1.8rem,3vw,2.9rem);font-weight:700}
.fcta p{font-family:var(--sans);text-transform:none;color:#d9e4f6;font-size:clamp(1rem,1.15vw,1.15rem);line-height:1.5;max-width:62ch;margin:clamp(20px,2.1vw,32px) auto 0}

/* ===== FOOTER ===== */
.footer{background:var(--navy-950);color:#98a0ac}
.footer > .cap{display:flex;align-items:center;justify-content:space-between;gap:22px;flex-wrap:wrap;padding:clamp(18px,1.9vw,28px) var(--pad)}
/* .fb (logo+location, ~209px) and .soc (two icons, ~82px) are very different widths, so
   justify-content:space-between only equalized the GAPS around .fnav, not its position —
   it visually landed well right of center, not centered above .footbar's counties line
   below it (owner-reported, 2026-09-09). Giving both flanking items equal flex-grow makes
   them resolve to the same rendered width regardless of their content, which is what
   actually centers .fnav on the row. Mobile (max-width:1040px) stacks all three full-width
   and centered already, untouched by this. */
.footer .fb{display:flex;align-items:center;gap:14px;flex:1 1 0}
.footer .flogo{height:clamp(38px,3.4vw,48px);width:auto}
/* Location tag next to the footer logo, sized and colored to match the footer's other small
   labels (.fnav). City + phone now stack in a small column (.floc) instead of sitting inline
   with the logo, so the phone reads as a second line under the city, not a third flex item
   racing the logo for space. */
.footer .floc{display:flex;flex-direction:column;gap:3px}
.footer .loc{font-family:var(--disp);text-transform:uppercase;letter-spacing:.05em;font-weight:600;font-size:.92rem;color:var(--blue-400)}
.footer .loc-phone{font-family:var(--disp);letter-spacing:.03em;font-weight:600;font-size:.82rem;color:#98a0ac;transition:.18s}
.footer .loc-phone:hover{color:var(--blue-400)}
.footer .fnav{display:flex;gap:clamp(12px,1.6vw,26px);font-family:var(--disp);text-transform:uppercase;letter-spacing:.05em;font-size:.82rem;font-weight:600;flex-wrap:wrap}
.footer .fnav a:hover{color:var(--blue-400)}
.footer .soc{display:flex;gap:10px;flex:1 1 0;justify-content:flex-end}
.footer .soc a{width:36px;height:36px;border-radius:50%;background:var(--blue-500);display:flex;align-items:center;justify-content:center;color:#fff;transition:.18s}
.footer .soc a:hover{background:var(--blue-400);transform:translateY(-2px)}
.footer .soc svg{width:17px;height:17px}
.footbar{border-top:1px solid rgba(154,162,174,.13)}
.footbar .cap{display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;padding:12px var(--pad);font-size:.8rem;color:#a9b6c7}
/* Service-area counties, footer (site-wide, 2026-08-31 owner request) — same 12-county list
   already approved and live in the homepage's "Service Areas" map section (.area-counties);
   just repeated here so it's present on every page regardless of scroll position, for
   on-page local-SEO signal. No new facts — copy of the existing verified list. */
.footbar .counties{font-size:.76rem;color:#8b94a1;max-width:760px;line-height:1.5}

.mobile-call{display:none}
@media(max-width:1040px){
  .header .cap{justify-content:space-between;height:70px}
  .hphone{font-size:1.18rem}
  .hphone{display:inline-flex}
  .nav-toggle{display:inline-flex}
  .nav{position:fixed;top:70px;left:0;right:0;flex-direction:column;align-items:stretch;gap:0;margin-left:0;max-height:0;overflow:hidden;background:var(--navy-950);border-bottom:1px solid rgba(43,131,255,.16);box-shadow:0 16px 28px rgba(0,0,0,.35);transition:max-height .25s ease}
  /* Open INSTANTLY (transition:none): if the opening animation is ever throttled or frozen
     (background tabs, previews, low-power mode), an animated open leaves the menu stuck at
     0 height and taps fall through to the page behind it — the "menu won't work" bug.
     Closing still animates via the base .nav transition. */
  .nav.is-open{max-height:400px;transition:none}
  .nav a{width:100%;padding:15px var(--pad);border-bottom:1px solid rgba(255,255,255,.08)}
  .nav a:last-child{border-bottom:0}
  /* mobile only: badge scaled down so it reads at the same weight as the phone number,
     and the bar tightened so the smaller logo does not float in empty space */
  .brand img{height:48px}
  .footer .flogo{height:42px}
  /* mobile hero: an adapted version of the desktop hero, NOT a stacked strip. The same
     photograph fills the frame; copy sits on it behind a diagonal scrim that keeps the
     top-left dark for text while the truck and mast stay bright at lower-right.
     Framing is the middle ground: tight enough that the rig reads large, wide enough
     that truck front, bed and raised mast are all in frame. */
  /* 372px is the tallest the hero can be while cover still reveals enough width to hold
     the whole rig — truck front through mast — with ~21px clear on each side */
  .hero{min-height:clamp(390px,100vw,440px);background:var(--navy-950)}
  /* Safe baseline for the FULL mobile range (up to 1040px wide, height capped at 440px —
     at the wide end of that range the box is proportionally wider than the source photo
     itself, so background-size MUST stay the `cover` keyword here, not a fixed zoom
     percentage, or the mast/rig can end up clipped or the image can fail to fill the box.
     The tighter "zoomed in, shifted down+right" framing below is layered on top ONLY for
     true phone-width screens (<=440px), where the box is verified square and safe for it. */
  .hero-bg{background:url('HeroImage.jpg?v=8') no-repeat;background-size:cover;background-position:100% 50%;filter:var(--grade)}
  .hero-bg::after{background:radial-gradient(125% 92% at 4% 8%,rgba(3,7,18,.93) 0%,rgba(3,7,18,.82) 24%,rgba(3,7,18,.5) 44%,rgba(3,7,18,.2) 60%,rgba(3,7,18,.04) 74%,rgba(3,7,18,0) 86%)}
  .hero-inner{min-height:inherit;align-items:flex-start;padding:0 var(--pad)}
  .hero-copy{max-width:min(91vw,372px);padding:clamp(70px,15vw,92px) 0 0}
  .hero .eyerule{width:38px;height:2px;margin-bottom:13px}
  .hero .kick{font-size:.92rem;letter-spacing:.16em;color:var(--blue-400)}
  /* Owner-requested mobile-only bump: title one step bigger than before, but the SAME
     size on both lines — a differentiated size read as two mismatched headlines. */
  .hero h1{font-size:clamp(2.15rem,9.6vw,2.7rem);line-height:1.06;margin-top:14px}
  .hero h1 .thr{display:block}
  .hero .rp{display:none}
  /* CTA button and Google rating removed from the mobile hero — the sticky bar is the
     mobile CTA, and the trust strip below already carries the Google rating. */
  .hero-act{display:none}
  .trust .cap{grid-template-columns:1fr 1fr;gap:14px}
  .trust .cap{gap:0}
  .trust .item{border-left:0;padding:11px 0;gap:9px}
  .trust .item:nth-child(2),.trust .item:nth-child(4){border-left:1px solid rgba(255,255,255,.16);padding-left:13px}
  .trust .item:nth-child(3),.trust .item:nth-child(4){border-top:1px solid rgba(255,255,255,.16)}
  .trust b{font-size:.9rem;line-height:1.16}
  /* 2x2 kept. Portrait crop + trimmed navy panel so the photo dominates each tile. */
  .sec{padding:clamp(24px,6vw,32px) 0}
  .cards{grid-template-columns:1fr 1fr;gap:11px}
  .card .ph{aspect-ratio:23/20}
  .img-drill{object-position:50% 95% !important}
  .img-filt{object-position:50% 74% !important}
  .img-pump{object-position:50% 40% !important}
  .img-frack{object-position:center !important}
  .card .cbody{padding:10px 11px 11px}
  .card h3{font-size:.97rem;line-height:1.02}
  .card .ul{width:24px;height:2px;margin:5px 0 5px}
  .card p{font-size:.78rem;line-height:1.38;margin-bottom:8px}
  /* mobile: stack copy above the map so the work pins stay fully visible */
  .area{display:flex;flex-direction:column-reverse}
  /* mobile: copy -> map -> list. The terrain moves onto the map plate itself so the map
     reads as the focus instead of a small overlay on a section-wide background. */
  .area{background:var(--navy-950)}
  .area-bg{display:none}
  .area .cap{padding:clamp(24px,6vw,32px) var(--pad);min-height:0}
  .area-grid{grid-template-columns:1fr;grid-template-areas:"copy" "map";grid-template-rows:auto auto;gap:0}
  .area-copy{margin-bottom:16px}
  .area-copy{align-self:auto;text-align:center}
  .area-copy>p{max-width:none;margin-left:auto;margin-right:auto}
  .area-515{max-width:none;text-align:center;margin-left:auto;margin-right:auto}
  /* full-bleed so the map uses every pixel of width available */
  /* explicit plate height so more of the 1003x1568 portrait terrain is revealed;
     the map SVG keeps its own aspect and centres inside it, so markers and labels
     hold their approved relative positions */
  /* Terrain image moved onto a ::before layer (2026-09-17) so the brightness/saturate
     filter below only affects the photo, not the SVG dots/labels stacked on top of it —
     filter on .area-map itself would have filtered its SVG children too. Matches the
     same lift applied to desktop's .area-bg for consistency between the two images. */
  /* overflow:hidden added (pre-launch QA fix): the map SVG scales to 100% of the
     container's width with a fixed aspect ratio, so its rendered height grows well past
     this container's fixed 390px height at wider mobile/tablet widths (~600-900px) — the
     svg's own overflow:visible then let the excess (including city labels near the top
     edge, e.g. "Chatsworth") bleed upward into the copy text above. Clipping here keeps
     the intentional "porthole" window into the larger map without that bleed, at every
     width in this breakpoint, not just narrow phones where the overflow was small enough
     to go unnoticed. */
  .area-map{margin-left:calc(-1 * clamp(24px,5.5vw,34px));margin-right:calc(-1 * clamp(24px,5.5vw,34px));
    position:relative;height:390px;display:flex;align-items:center;overflow:hidden}
  .area-map::before{content:"";position:absolute;inset:0;background:url('north-georgia-terrain-mobile.jpg') center 64%/cover no-repeat;filter:brightness(1.24) saturate(1.1);z-index:1}
  .area-map svg{position:relative;z-index:2}
  .area-map .map-wide{display:none}
  .map-note{bottom:18px}
  .area-map .map-narrow{display:block}
  /* restrained on mobile — thinner, fainter than desktop so it never competes with labels */
  .area-map .corridor{stroke-width:1.8;stroke-opacity:.25;filter:blur(1.4px)}
  .map-note strong{font-size:1rem}
  .map-note span{font-size:.92rem}
  /* mobile: the band stays short — the 1-2-3 grid collapses into one condensed line */
  .why-grid{display:none}
  .why-sub2{display:block;text-align:center;font-family:var(--sans);color:#c3d0e2;font-size:clamp(.95rem,3.9vw,1.02rem);line-height:1.55;max-width:34ch;margin:-8px auto 0;text-wrap:balance}
  .why{padding:clamp(24px,6vw,32px) 0}
  .why-sub{margin-bottom:12px}
  .rcar{gap:5px}
  .rslide{padding:22px 16px}
  .rslide .quote{font-size:.96rem;line-height:1.55}
  .rnav{width:34px;height:34px;font-size:1.3rem}
  .rdots{margin-top:6px;gap:6px}
  .rdot{width:6px;height:6px}
  .rdot.is-on{width:14px}
  .rlink{margin-top:6px}
  .revs{padding:clamp(24px,6vw,32px) 0}
  .fcta .cap{justify-content:center;text-align:center;padding:clamp(24px,6vw,32px) var(--pad)}
  .footer > .cap{justify-content:center;text-align:center}
  /* emblem pinned to the left (in line with the header logo); the Talking Rock lines
     centre independently of it, on the same axis as the nav, socials and copyright */
  .footer .fb{width:100%;justify-content:center}
  .footer .fnav{width:100%;justify-content:center}
  .footer .soc{width:100%;justify-content:center;margin-top:4px}
  .head-c h2,.area h2,.fcta h2{white-space:normal;font-size:clamp(1.42rem,6vw,1.9rem)}
  .titlerow .ln{display:none}
  .titlerow{gap:0}
  /* Sizing matched to the service pages' compact treatment (2026-08-31, owner request —
     button text/height was inconsistent site-wide: homepage/404 ran larger than the 4
     service pages, which all deliberately share one smaller size). */
  .mobile-call{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:70;background-color:var(--blue-600);background-image:linear-gradient(115deg,var(--blue-700),var(--blue-500) 55%,var(--blue-600));color:#fff;justify-content:center;align-items:center;gap:11px;padding:12px 15px;font-family:var(--disp);text-transform:uppercase;letter-spacing:.06em;font-weight:700;font-size:1.05rem;border-top:1px solid rgba(255,255,255,.22);box-shadow:0 -4px 16px rgba(0,0,0,.28)}
  body{padding-bottom:0}
  .footbar{padding-bottom:70px}
}

/* ===== SERVICE PAGE COMPONENTS (shared by all /services/ pages) ===== */
.svc-hero{position:relative;min-height:clamp(320px,38vw,520px);background:#cfe0f2;overflow:hidden}
.svc-hero .bg{position:absolute;inset:0;background-size:cover;background-position:center 46%;filter:var(--grade)}
.svc-hero .bg::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(7,16,32,.72) 0%,rgba(7,16,32,.5) 38%,rgba(7,16,32,.12) 68%,rgba(7,16,32,0) 100%)}
.svc-hero .cap{position:relative;z-index:2;padding:clamp(30px,4vw,64px) var(--pad);min-height:inherit;display:flex;flex-direction:column;justify-content:center}
.svc-hero .crumb{font-family:var(--disp);text-transform:uppercase;letter-spacing:.16em;font-size:.74rem;color:#cfdaea;margin-bottom:12px}
.svc-hero .crumb a:hover{color:#fff}
.svc-hero h1{font-size:clamp(2rem,4.2vw,4.2rem);font-weight:700;color:#fff;max-width:16ch}
.svc-hero p{font-family:var(--sans);text-transform:none;color:#e4eaf3;font-size:clamp(1rem,1.25vw,1.25rem);max-width:46ch;margin-top:14px;line-height:1.5}
.svc-hero .btn{margin-top:22px;align-self:flex-start}

.prose{padding:clamp(30px,3.4vw,56px) 0}
.prose .cap{max-width:1180px}
.prose-grid{display:grid;grid-template-columns:1.5fr 1fr;gap:clamp(26px,3.4vw,60px);align-items:start}
.prose h2{font-size:clamp(1.5rem,2.3vw,2.3rem);font-weight:700;color:var(--ink);margin-bottom:14px}
.prose h3{font-size:clamp(1.1rem,1.4vw,1.4rem);font-weight:600;color:var(--ink);margin:26px 0 8px}
.prose p{color:var(--body);font-size:clamp(.98rem,1.06vw,1.08rem);line-height:1.65;margin-bottom:14px}
.prose ul{list-style:none;display:grid;gap:10px;margin:14px 0 18px}
.prose ul li{position:relative;padding-left:26px;color:var(--body);font-size:clamp(.98rem,1.06vw,1.08rem);line-height:1.55}
.prose ul li::before{content:"";position:absolute;left:0;top:.55em;width:9px;height:9px;border-radius:50%;background:var(--blue-500)}
.prose .lede{font-size:clamp(1.05rem,1.2vw,1.22rem);color:var(--ink);font-weight:500;line-height:1.6}
.prose a.inline{color:var(--blue-600);text-decoration:underline;text-underline-offset:2px}

.aside{background:var(--stone-050);border:1px solid var(--stone-200);border-radius:10px;padding:clamp(20px,1.9vw,28px);position:sticky;top:clamp(96px,8vw,120px)}
.aside h3{font-family:var(--disp);text-transform:uppercase;letter-spacing:.03em;font-size:1.05rem;color:var(--ink);margin-bottom:12px}
.aside .row{display:flex;gap:11px;margin-bottom:13px;align-items:flex-start}
.aside .row svg{width:19px;height:19px;color:var(--blue-500);flex:none;margin-top:2px}
.aside .row span{font-size:.95rem;color:var(--body);line-height:1.45}
.aside .btn{width:100%;justify-content:center;margin-top:6px}

/* .note is only used on services/well-drilling and services/pump-service (not the
   homepage) — sizes bumped 2026-09-19 (owner legibility feedback): .8rem/.96rem were
   both below the site's normal body-text size and hard to read on a phone. */
.note{border-left:3px solid var(--blue-500);background:var(--stone-050);padding:16px 18px;border-radius:0 6px 6px 0;margin:18px 0}
.note b{font-family:var(--disp);text-transform:uppercase;letter-spacing:.04em;font-size:.92rem;color:var(--blue-600);display:block;margin-bottom:6px}
.note p{margin:0;font-size:1.05rem;color:var(--body);line-height:1.55}
.src{font-size:.84rem;color:#7c838f;margin-top:10px}
.src a{text-decoration:underline;text-underline-offset:2px}

.rel{background:var(--stone-050);padding:clamp(30px,3.4vw,54px) 0}
.rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(12px,1.4vw,20px)}
.rel-card{display:block;background:#fff;border:1px solid var(--stone-200);border-radius:8px;padding:clamp(18px,1.8vw,24px);transition:.2s}
.rel-card:hover{transform:translateY(-3px);box-shadow:0 14px 30px rgba(11,27,52,.12);border-color:var(--blue-500)}
.rel-card h3{font-size:clamp(1.02rem,1.2vw,1.2rem);font-weight:600;color:var(--ink)}
.rel-card p{font-family:var(--sans);text-transform:none;color:var(--body);font-size:.94rem;line-height:1.45;margin:8px 0 10px}

@media(max-width:1040px){
  .prose-grid{grid-template-columns:1fr}
  .aside{position:static}
  .rel-grid{grid-template-columns:1fr}
  .svc-hero .bg::after{background:linear-gradient(90deg,rgba(7,16,32,.8),rgba(7,16,32,.55) 60%,rgba(7,16,32,.3))}
}

/* Tighter hero framing for true phone-width screens only. Below 440px wide, .hero's
   min-height:clamp(390px,100vw,440px) keeps the box exactly square (height==width), which
   stays narrower than the source photo's own aspect ratio — safe territory for a fixed zoom
   percentage. Zoomed in and shifted down+right per owner feedback (rig reads bigger, less
   empty sky, mast still fully clear at this width). Do not raise this breakpoint above
   440px without re-verifying the mast doesn't clip once the box aspect uncaps. */
@media(max-width:440px){
  .hero-bg{background-size:auto 110%;background-position:87% 32%}
}

/* ==========================================================================
   HOMEPAGE MOTION LAYER (2026) — every rule below is scoped to body.home, so
   none of it can affect the four service pages, which reuse these same
   component classes (.card, .head-c, .fcta, [data-reveal]) from this same
   shared stylesheet. Builds on the EXISTING scroll-reveal system (reveal.js
   + [data-reveal] / .is-visible) — no new JS dependency was added.

   Motion language adapted from the purchased Noctis template after reading
   its actual source (src/lib/motion-variants.ts, hero/scramble-word.tsx,
   hero/index.tsx): the masked upward line-reveal (overflow:hidden wrapper +
   inner element translateY 100%->0%), the line-draw underline/rule
   (scaleX 0->1), the image-scale settle on reveal, and its signature easing
   curve cubic-bezier(.22,1,.36,1). Deliberately NOT ported: Lenis smooth-
   scroll, the cursor-follower, the loader gate, per-letter stagger, the
   continuous mouse-tilt on the headline, and the infinite bouncing scroll
   arrow — all explicitly out of scope for this site.

   Fail-safe: every hidden/animated state below requires BOTH (a)
   prefers-reduced-motion allowing it and (b) .js already present on <html>
   (added by a tiny inline, non-deferred script at the top of <head> — see
   index.html). If JavaScript never runs, .js never appears, so nothing here
   ever matches and all content renders in its normal, fully visible,
   un-transformed state. ========================================== */
body.home{--ease-premium:cubic-bezier(.22,1,.36,1)}

/* Give the site's existing [data-reveal] fades the same premium easing as
   everything new below, on the homepage only — the mechanism (opacity/
   translateY via reveal.js) is untouched; only the timing curve/duration
   is upgraded here, so service pages keep their original feel. */
@media(prefers-reduced-motion:no-preference){
  body.home [data-reveal]{transition-duration:.8s;transition-timing-function:var(--ease-premium)}
}

/* ---- Masked heading reveal ----
   Markup: <span class="h-mask"><h2>…</h2></span> (sections) or
   <span class="h-mask"><span class="h-mask-inner">…</span></span> (hero).
   The outer .h-mask is the static clipping edge; the inner element is what
   actually rises into view. Reused identically for every homepage section
   heading so the language reads as one system. */
@media(prefers-reduced-motion:no-preference){
  .js body.home .h-mask{display:block;overflow:hidden}
  .js body.home .h-mask>h2,.js body.home .h-mask>.h-mask-inner{transform:translateY(100%);opacity:0;transition:transform .7s var(--ease-premium),opacity .7s var(--ease-premium)}
  .js body.home [data-reveal].is-visible .h-mask>h2{transform:translateY(0);opacity:1}
}
/* Desktop-only: owner asked these three headings frozen (no mask reveal) while
   Complete Well Solutions keeps it and the map's own marker animation is untouched. */
/* Frozen on BOTH breakpoints (owner asked for mobile to match desktop here): Straight
   Answers and Real People/Real Reviews (heading + all supporting content), the map's
   own heading (its terrain/pins/corridor animation is untouched), and the final CTA. */
@media(prefers-reduced-motion:no-preference){
  .js body.home .why .head-c .h-mask>h2,
  .js body.home .revs .head-c .h-mask>h2,
  .js body.home .area .head-c .h-mask>h2,
  .js body.home .fcta [data-reveal] .h-mask>h2,
  .js body.home .why .head-c[data-reveal],
  .js body.home .revs .head-c[data-reveal],
  .js body.home .area .head-c[data-reveal],
  .js body.home .why-sub[data-reveal],
  .js body.home .why-grid[data-reveal],
  .js body.home .rcar[data-reveal],
  .js body.home .fcta [data-reveal]{transform:none;opacity:1;transition:none}
}
/* Trust bar stays desktop-only frozen, as originally requested. */
@media(prefers-reduced-motion:no-preference) and (min-width:1041px){
  .js body.home .trust .cap[data-reveal]{transform:none;opacity:1;transition:none}
}

/* ---- Service cards ----
   Entrance (fade+up+stagger) and the underline draw already exist in the
   shared .card CSS above; this only (a) tightens the stagger on mobile so
   four cards never make the user wait, and (b) adds the restrained desktop-
   only image-scale interaction on hover, replacing the previous 1.06 scale
   with the smaller 1.035 this task specifies, on the premium easing curve. */
@media(prefers-reduced-motion:no-preference) and (max-width:900px){
  body.home .cards[data-reveal] .card,body.home .card[data-reveal]{transition-delay:calc(var(--rd,0) * 45ms)}
}
@media(hover:hover) and (pointer:fine){
  body.home .card .ph img{transition:transform .5s var(--ease-premium),filter .5s var(--ease-premium)}
  body.home .card:hover .ph img{transform:scale(1.035)}
}
/* Touch devices never get the shared hover-scale "stuck" mid-zoom after a tap. */
@media not all and (hover:hover){
  body.home .card:hover .ph img{transform:none}
}

/* ---- North Georgia map ----
   Its own motion story, deliberately different from the masked-heading system used
   elsewhere on the page: HOME BASE -> 515 CORRIDOR -> SERVICE TOWNS, then it stops
   completely. Terrain is already visible when the section enters view (no fly-in/
   zoom/pan). Talking Rock settles first with a one-time glow (not a loop), then the
   corridor spine draws outward from it once, then the surrounding towns fade in as
   three geographic groups rather than 18 individual pops. Triggered by [data-reveal]
   on .area-map itself; finishes at roughly 1.95s and holds still. */
@media(prefers-reduced-motion:no-preference){
  .js body.home .area-map[data-reveal] .pt{opacity:0;transform:scale(.7);transform-origin:center;transition:opacity .45s var(--ease-premium),transform .45s var(--ease-premium)}
  .js body.home .area-map[data-reveal] .lb{opacity:0;transform:translateY(6px);transition:opacity .45s var(--ease-premium),transform .45s var(--ease-premium)}
  .js body.home .area-map[data-reveal] .halo{opacity:0;transform:scale(.5);transform-origin:center}
  .js body.home .area-map[data-reveal] .corridor{stroke-dasharray:100;stroke-dashoffset:100;opacity:0}
  .js body.home .area-map[data-reveal].is-visible .pt{opacity:1;transform:scale(1)}
  .js body.home .area-map[data-reveal].is-visible .lb{opacity:1;transform:translateY(0)}
  .js body.home .area-map[data-reveal].is-visible .halo{animation:gwpHomeBaseGlow .5s var(--ease-premium) both}
  .js body.home .area-map[data-reveal].is-visible .corridor{animation:gwpCorridorDraw .55s var(--ease-premium) .45s both}
  /* group 1 — the six named corridor/core towns, right after the spine draws */
  .js body.home .area-map[data-reveal] .pt.t2,.js body.home .area-map[data-reveal] .lb.t2{transition-delay:1.1s}
  /* group 2 — nearer outlying communities */
  .js body.home .area-map[data-reveal] .pt.t3,.js body.home .area-map[data-reveal] .lb.t3{transition-delay:1.3s}
  /* group 3 — farther-north communities settle last */
  .js body.home .area-map[data-reveal] .pt.t3.g3,.js body.home .area-map[data-reveal] .lb.t3.g3{transition-delay:1.5s}
}
@keyframes gwpHomeBaseGlow{0%{opacity:0;transform:scale(.5)}55%{opacity:1;transform:scale(1.22)}100%{opacity:1;transform:scale(1)}}
@keyframes gwpCorridorDraw{from{stroke-dashoffset:100;opacity:0}15%{opacity:1}to{stroke-dashoffset:0;opacity:1}}

/* ---- Final CTA ---- the supporting line settles a beat after the heading. */
@media(prefers-reduced-motion:no-preference){
  .js body.home .fcta [data-reveal] p{transition-delay:.15s}
}

/* ==========================================================================
   HERO ENTRANCE — plays once on load rather than on scroll (the hero is
   always above the fold), so it is plain CSS animation, not the
   IntersectionObserver reveal system. Same fail-safe gating as above: no
   .js class or reduced-motion enabled => the hero renders fully visible,
   statically, immediately. The hero photograph itself is untouched — only
   the copy layer (line, eyebrow, headline, paragraph, CTA) animates. ===== */
@media(prefers-reduced-motion:no-preference){
  .js body.home .hero .eyerule{transform-origin:left;animation-name:gwpLineDraw;animation-duration:.45s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-fill-mode:both}
  .js body.home .hero .kick{animation-name:gwpFadeUp;animation-duration:.55s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-delay:.25s;animation-fill-mode:both}
  .js body.home .hero h1 .h-mask{display:block;overflow:hidden}
  .js body.home .hero h1 .h-mask-a .h-mask-inner{display:block;animation-name:gwpMaskUp;animation-duration:.65s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-fill-mode:both;animation-delay:.25s}
  /* Deliberate reading pause after "The Water's Down There." settles before "We Go Get
     It." begins — owner-requested beat so the first line is read on its own before the
     payoff line. Shortened 2026-09-17 (owner feedback: the pause ran too long) — the
     letter-fill reveal itself was slowed down instead (see FILL_STAGGER/WORD_PAUSE in
     the inline script) so "We Go Get It." now starts sooner but reads out more
     deliberately once it begins. --wgg-delay is the single source of truth for when
     that payoff line's letter-fill sequence (below) begins; read at runtime by the
     inline script that builds it, so JS and CSS never drift apart. */
  .js body.home .hero h1 .h-mask-b{--wgg-delay:1.1s}
  /* transform:none overrides the generic section-heading mask rule above, which also
     matches this element (same .h-mask/.h-mask-inner class names) and would otherwise
     leave it permanently shifted translateY(100%) since nothing here uses that reveal
     mechanism for this line anymore — the letters below handle their own reveal. */
  .js body.home .hero h1 .h-mask-b .h-mask-inner{display:block;opacity:0;transform:none}
  .js body.home .hero .rp{animation-name:gwpFadeUp;animation-duration:.55s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-delay:.25s;animation-fill-mode:both}
  .js body.home .hero-act{animation-name:gwpFadeUp;animation-duration:.55s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-delay:.35s;animation-fill-mode:both}

  /* ---- "We Go Get It." — signature letter-by-letter fill+glow reveal ----
     Adapted from the Noctis template's loader.tsx (LetterFill component) after reading
     its source: each letter is transparent with a faint stroked outline that appears
     first (so the whole word reads as an outline together), then — after a short beat —
     a solid white fill wipes up through each letter left to right, with a brief glow
     flash right as each letter's fill completes. NOT used as a loading screen (that part
     of Noctis was intentionally not ported) — just this one line's reveal treatment.
     Built by a small inline script at the end of <body> that only runs when
     prefers-reduced-motion allows it; if it never runs, the plain text already sitting
     in .hgo just displays normally, so failure is always safe. Real accessible text
     stays on .lf-letter itself (the outline layer); the fill/glow are ::before/::after
     pseudo-elements so no text is duplicated for assistive tech. */
  .lf-letter{position:relative;display:inline-block;color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.34);opacity:0;animation-name:lfOutlineIn;animation-duration:.3s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-fill-mode:both;animation-delay:var(--od,0s)}
  .lf-letter::before{content:attr(data-ch);position:absolute;inset:0;color:#fff;clip-path:inset(100% 0 0 0);animation-name:lfFillWipe;animation-duration:.32s;animation-timing-function:cubic-bezier(.22,1,.36,1);animation-fill-mode:both;animation-delay:var(--fd,0s)}
  .lf-letter::after{content:attr(data-ch);position:absolute;inset:0;color:transparent;text-shadow:0 0 10px rgba(255,255,255,.85),0 0 22px rgba(255,255,255,.5);opacity:0;animation-name:lfGlowFlash;animation-duration:.35s;animation-timing-function:ease-out;animation-fill-mode:both;animation-delay:var(--gd,0s)}
}
@keyframes lfOutlineIn{from{opacity:0}to{opacity:1}}
@keyframes lfFillWipe{from{clip-path:inset(100% 0 0 0)}to{clip-path:inset(0% 0 0 0)}}
@keyframes lfGlowFlash{0%{opacity:0}35%{opacity:.85}100%{opacity:0}}
@keyframes gwpLineDraw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes gwpFadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:translateY(0)}}
@keyframes gwpMaskUp{from{opacity:0;transform:translateY(100%)}to{opacity:1;transform:translateY(0)}}

/* Mobile: same sequence, noticeably faster and lighter — never make a phone
   user wait for the hero to finish performing. */
@media(prefers-reduced-motion:no-preference) and (max-width:1040px){
  .js body.home .hero .eyerule{animation-duration:.35s}
  .js body.home .hero .kick{animation-duration:.45s;animation-delay:.18s}
  /* Mobile-only timing: "3 Licensed Georgia Well Drillers" pops up, a 1000ms pause,
     "The Water's Down There.", then the "We Go Get It." letter-fill sequence begins
     (--wgg-delay, read at runtime by the inline script). Pause before the letter-fill
     sequence shortened 2026-09-17 (owner feedback: too long) from 2000ms to ~700ms —
     the reveal itself was slowed down instead (FILL_STAGGER/WORD_PAUSE in the inline
     script), so .rp/.hero-act's delays below are pushed out to match the resulting
     longer reveal and still land just after it finishes, not during it. */
  .js body.home .hero h1 .h-mask-a .h-mask-inner{animation-duration:.5s;animation-delay:.18s}
  .js body.home .hero h1 .h-mask-b{--wgg-delay:.9s}
  .js body.home .hero .rp{animation-duration:.45s;animation-delay:3.4s}
  .js body.home .hero-act{animation-duration:.45s;animation-delay:3.5s}
}

/* ===== HOMEPAGE DESKTOP-ONLY REFINEMENTS =====
   Gated to min-width:1041px (the exact complement of this file's mobile breakpoint,
   @media(max-width:1040px) above) so none of this can ever touch the mobile layout —
   mobile keeps its own already-tuned .area/.why rules from that block untouched.
   (The trust strip's dark navy/blue gradient used to live here as a desktop-only
   override; it's now the base .trust rule itself, applied on both breakpoints.) */
@media(min-width:1041px){
  /* ---- Service area map: the section's real height came from the map SVG itself
     (width:100% at this container width renders it ~900px tall, well past the old
     min-height floor). Capping the map's own height — not its content — is what
     actually shrinks the section; artwork, labels and coordinates are untouched. ---- */
  .area .cap{padding:clamp(24px,2.6vw,40px) var(--pad);min-height:0}
  .area-map .map-wide{width:auto;height:auto;max-height:clamp(340px,30vw,440px);margin:0 auto}

  /* Replace the full-width translucent overlay bar with a small, unboxed caption that
     sits in normal flow right under the map — reads as a note, not a banner or button. */
  .map-note{position:static;left:auto;right:auto;bottom:auto;width:auto;max-width:440px;
    margin:14px auto 0;background:none;backdrop-filter:none;border-radius:0;padding:0;text-align:center}
  .map-note strong{font-size:.98rem;letter-spacing:.05em}
  .map-note span{font-size:.88rem;margin-top:2px;color:#c3d0e2}

  /* ---- Final CTA: tighten so map -> CTA -> footer reads as one compact close instead
     of three equally-tall bands. ---- */
  .fcta .cap{padding:clamp(26px,2.6vw,40px) var(--pad)}

  /* ---- "When You Call, We Answer": bigger 01/02/03 and slightly stronger step headings.
     Section padding, heading-to-paragraph gap, and grid gap were previously tightened here
     too, but that made this section's rhythm noticeably different from Services/Reviews/
     Service Area (43.5px section padding, 26.9px heading gap everywhere else vs. this
     section's 38.4px/15.4px) — reverted so all sections share one consistent spacing
     rhythm again. This is also the visual reference the Well Drilling "What Happens Next?"
     section is styled to match (see that page's own <style> block) — its padding already
     mirrors the site-wide default, so no change needed there. ---- */
  .wcol .num{font-size:clamp(2.2rem,3.2vw,3rem)}
  .wcol h3{font-weight:700;font-size:clamp(1.1rem,1.4vw,1.4rem)}
}

/* ===== HOMEPAGE FINAL-CTA CALL BUTTON (owner-requested 2026-08-30) =====
   New page element: a visible desktop CTA in the "Your Water. Done Right." band, which
   previously had no action. New .fcta-call class only — no frozen selector is edited
   (per HOMEPAGE-LOCK §2, adding a scoped rule instead of touching shared ones).
   Hidden on mobile, where the sticky "Call Now" bar already covers the same action. */
@media(max-width:1040px){
  .fcta-call{display:none}
}

/* ===== NOCTIS-FEEL POLISH PASS (owner-requested 2026-08-30) =====
   All rules below are ADDITIVE (new selectors / pseudo-elements only — no frozen
   selector is edited, per HOMEPAGE-LOCK §2). Three effects, translated from the
   owner's purchased Noctis template into plain CSS:
   1. Site-wide film grain — kills the flat "AI gradient" look on the navy bands.
   2. Card underline draw-in — accents animate in with the reveal.
   3. Counties line under the service-area map. */

/* 1. Film grain: fixed full-viewport SVG turbulence at ~4% via overlay blend.
   Static texture (not animated), pointer-transparent, sits over everything the
   way the template's GrainOverlay component does. */
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:190;opacity:.04;mix-blend-mode:overlay;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='gwpn'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23gwpn)'/%3E%3C/svg%3E")}

/* 2. Card underline draws in left-to-right after the card reveals. */
@media(prefers-reduced-motion:no-preference){
  .card[data-reveal] .ul{transform:scaleX(0);transform-origin:left;transition:transform .55s cubic-bezier(.22,1,.36,1) calc(var(--rd,0) * 90ms + .3s)}
  .card[data-reveal].is-visible .ul{transform:scaleX(1)}
}

/* 3. Counties served — SEO/coverage line under the service-area map. */
.area-counties{position:relative;z-index:2;text-align:center;font-family:var(--sans);color:#9fb3cc;font-size:.92rem;line-height:1.55;max-width:72ch;margin:16px auto 0}
@media(max-width:1040px){.area-counties{margin-top:14px;font-size:.88rem}}

/* Links inside .note callouts (e.g. the EPD license-list link on the Well Drilling page). */
.note a{color:var(--blue-600);text-decoration:underline;text-underline-offset:2px}
.note a:hover{color:var(--blue-500)}


/* ===== TWO-TONE HEADINGS — reverted 2026-08-31 per owner direction: the small blue
   eyebrow labels/accent lines stay blue, but the big section/hero titles themselves go
   back to solid white (or solid ink on the light Reviews section) — no more half-white,
   half-blue split within a single headline. .mbr/.hgo now just inherit their parent
   heading's color, since nothing else styles them once the color override is gone. */

