
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:#fff;color:#0F172A;color-scheme:light;
font-family:"Montserrat","Montserrat Fallback",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial;
overflow-x:hidden}
img{max-width:100%}
main{display:block}
/* "Montserrat Fallback" is named here and in template.py's .xhac-svc stack but is not
   declared yet. An undeclared family is skipped by the browser, so this is inert until
   the metric-overridden @font-face lands (performance.md 7.2, which measured this
   site's CLS as fonts rather than unsized images). Naming it in both stacks now means
   that swap is one @font-face block and no stack edits. */
/* The header is sticky, so a hash link would otherwise land its target underneath
   it. The embed script measured this at jump time; standalone it is one rule. */
[id]{scroll-margin-top:96px}
:where(a,button,input,summary):focus-visible{outline:3px solid #61BC47;outline-offset:2px}
.skip{position:absolute;left:-9999px;top:0;background:#fff;color:#5F2980;padding:12px 18px;
font-weight:800;z-index:1000;border-radius:0 0 10px 0}
.skip:focus{left:0}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;
animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}

/* ============================== header ============================== */
.xh-hd{position:sticky;top:0;z-index:900;background:#5E2C7E;color:#fff;
font-family:"Montserrat",ui-sans-serif,system-ui,sans-serif}
.xh-hd *{box-sizing:border-box}
.xh-hd a{text-decoration:none}
/* Color inheritance is scoped to the purple bar and the mobile panel. Applying it to
   every descendant forced the white dropdown's links to render white-on-lavender. */
.xh-bar a,.xh-panel a{color:inherit}
.xh-bar{max-width:1280px;margin:0 auto;padding:14px 40px;display:flex;align-items:center;
justify-content:space-between;gap:24px}
.xh-logo{display:flex;align-items:center;flex:none}
.xh-logo img{height:44px;width:auto;display:block}

.xh-nav{display:flex;align-items:center;gap:26px;font-weight:600;font-size:14px}
.xh-navitem{position:static}
.xh-hd{position:sticky}
.xh-navbtn{display:inline-flex;align-items:center;gap:6px;background:none;border:0;padding:10px 0;
color:#fff;font:inherit;font-weight:600;cursor:pointer;min-height:44px}
.xh-navbtn .car{font-size:9px;opacity:.6;transition:transform .18s ease}
/* NEW rides above the label, centred on it. The button is 44px tall for the tap
   target while the text is ~17px, so the chip sits in space the row already had. */
.xh-navbtn.has-new{position:relative}
.xh-navbtn .xh-new{position:absolute;left:50%;top:2px;transform:translateX(-50%);
background:#6BB85C;color:#0F172A;font-size:8.5px;font-weight:800;letter-spacing:1px;
line-height:1;border-radius:4px;padding:3px 5px;white-space:nowrap}
.xh-navitem[data-open="true"] .xh-navbtn .car{transform:rotate(180deg)}
.xh-nav a.xh-link{display:inline-flex;align-items:center;min-height:44px}
.xh-nav a.xh-link:hover,.xh-navbtn:hover{color:#8FD481}
.xh-nav .is-current{color:#8FD481}

.xh-actions{display:flex;align-items:center;gap:18px;flex:none}
.xh-phone{font-weight:800;font-size:15px;white-space:nowrap}
.xh-phone:hover{color:#8FD481}
.xh-cta{background:#6BB85C;color:#0F172A;font-weight:800;font-size:14px;padding:12px 20px;
border-radius:10px;border:0;cursor:pointer;font-family:inherit;min-height:44px;white-space:nowrap}
.xh-cta:hover{background:#8FD481}

/* ---- mega menu: full-width panel, matching the Framer desktop header ---- */
.xh-navbtn{position:relative}
.xh-navbtn .bar{position:absolute;left:0;right:0;bottom:-14px;height:3px;background:#6BB85C;
transform:scaleX(0);transform-origin:center;transition:transform .15s ease;border-radius:2px}
.xh-navbtn[aria-expanded="true"]{color:#6BB85C;font-weight:800}
.xh-navbtn[aria-expanded="true"] .bar{transform:scaleX(1)}

.xm-scrim{position:fixed;left:0;right:0;bottom:0;background:rgba(15,23,42,.45);z-index:890;display:none}
.xh-hd[data-menu] .xm-scrim{display:block}
.xm-shell{position:absolute;left:0;right:0;top:100%;z-index:900}
.xm-panel{background:#fff;border-top:1px solid #E7E7EA;
box-shadow:0 24px 60px rgba(15,23,42,.22);display:none}
.xh-hd[data-menu="hvac"] .xm-panel[data-menu="hvac"],
.xh-hd[data-menu="plumbing"] .xm-panel[data-menu="plumbing"]{display:block;animation:xmIn .15s ease-out both}
@keyframes xmIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){.xm-panel{animation:none!important}}

.xm-grid{max-width:1280px;margin:0 auto;padding:30px 40px 34px;
display:grid;grid-template-columns:1.1fr 1fr 340px;gap:40px}
.xm-label{font-weight:800;font-size:10.5px;letter-spacing:1.8px;color:#94A3B8;
padding-bottom:12px;border-bottom:1px solid #E7E7EA;margin-bottom:10px}
.xm-row{display:flex;align-items:flex-start;gap:12px;padding:11px 10px;border-radius:10px;
text-decoration:none;transition:background .13s ease}
.xm-row .txt{flex:1;display:flex;flex-direction:column;gap:2px}
.xm-row .t{font-weight:800;font-size:14px;color:#0F172A;display:flex;align-items:center;gap:8px}
.xm-row .d{font-weight:500;font-size:11.5px;color:#475569}
.xm-row .go{opacity:0;color:#6BB85C;font-weight:800;transition:opacity .13s ease}
.xm-row:hover{background:#F4F1F8}
.xm-row:hover .t{color:#5F2980}
.xm-row:hover .go{opacity:1}
.xm-row:focus-visible{outline:2px solid #5F2980;outline-offset:-2px}
.xm-row.slim{padding:10px}
.xm-glyph{position:relative;display:block;width:26px;height:26px;flex:none}
.xm-glyph i{position:absolute;inset:9.5px 2px;border-radius:2px}
.xm-glyph i:first-child{background:#5F2980;transform:rotate(45deg)}
.xm-glyph i:last-child{background:#6BB85C;transform:rotate(-45deg)}
.xm-badge{background:#EEF7EC;color:#4E9B41;font-weight:800;font-size:9.5px;letter-spacing:.6px;
border-radius:5px;padding:3px 7px}
.xm-chips{display:flex;flex-wrap:wrap;gap:6px;padding:2px 10px 8px 46px}
.xm-chip{background:#F4F1F8;color:#5F2980;font-weight:700;font-size:10.5px;border-radius:6px;
padding:5px 9px;text-decoration:none;transition:background .13s ease,color .13s ease}
.xm-chip:hover{background:#5F2980;color:#fff}
.xm-divider{height:1px;background:#E7E7EA;margin:12px 0}
.xm-viewall{display:inline-block;font-weight:800;font-size:13px;color:#5F2980;
text-decoration:none;padding:6px 10px}
.xm-viewall:hover{color:#3F852B}
.xm-aside{display:flex;flex-direction:column;gap:14px}
.xm-promo{border-radius:14px;padding:18px 20px}
.xm-promo.lav{background:#F4F1F8}
.xm-promo.mint{background:#EEF7EC}
.xm-promo .h{font-weight:800;font-size:15px;margin-bottom:6px}
.xm-promo.lav .h{color:#5F2980}
.xm-promo.mint .h{color:#3D7A33}
.xm-promo p{font-weight:500;font-size:12.5px;line-height:1.55;color:#475569;margin:0 0 10px}
.xm-promo a,.xm-promo button{font-weight:800;font-size:13px;color:#5F2980;text-decoration:none;
background:none;border:0;padding:0;cursor:pointer;font-family:inherit}
.xm-promo.mint a,.xm-promo.mint button{color:#3D7A33}
.xm-promo a:hover,.xm-promo button:hover{text-decoration:underline}

/* ---- mobile: bar trigger + full-screen panel, matching the Framer mobile header ---- */
.xh-burger{display:none;width:44px;height:44px;border:1.5px solid rgba(255,255,255,.4);
border-radius:12px;background:transparent;cursor:pointer;align-items:center;justify-content:center}
.xh-burger span{display:block;width:18px;height:2px;background:#fff;
box-shadow:0 5px 0 #fff,0 -5px 0 #fff}
.xh-burger:active{transform:scale(.96)}

.xh-panel{display:none;position:fixed;inset:0;z-index:950;flex-direction:column;
background:linear-gradient(160deg,#5E2C7E 0%,#542770 45%,#3A1A4E 100%);color:#fff}
.xh-panel[data-open="true"]{display:flex}
.xh-panel-bar{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;
border-bottom:1px solid rgba(255,255,255,.12);flex:none}
.xh-panel-bar .xh-logo img{width:min(52vw,200px);height:auto;margin:3px 0 0 -6px}
.xh-close{width:44px;height:44px;border:1.5px solid rgba(255,255,255,.45);border-radius:11px;
background:transparent;color:#fff;font-size:16px;cursor:pointer;display:grid;place-items:center}
.xh-close:active{transform:scale(.96)}
.xh-scroll{flex:1;overflow:auto;-webkit-overflow-scrolling:touch;padding:4px 20px 16px}

/* Rows are large italic display type, one per line with a rule beneath. */
.xh-acc>button,.xh-simple a{width:100%;display:flex;align-items:center;
justify-content:space-between;gap:10px;padding:16px 2px;min-height:44px;background:none;
border:0;border-bottom:1px solid rgba(255,255,255,.12);cursor:pointer;text-align:left;
font-style:italic;font-weight:900;font-size:19px;color:#fff;font-family:inherit;
text-decoration:none}
.xh-acc>button:focus-visible,.xh-simple a:focus-visible{outline:2px solid #fff;outline-offset:-2px}
.xh-caret{font-style:normal;font-size:13px;color:rgba(255,255,255,.55)}
.xh-acc[data-open="true"] .xh-caret{color:#6BB85C}
.xh-save{display:inline-block;margin-left:10px;vertical-align:middle;background:#6BB85C;
color:#0F172A;font-style:normal;font-weight:800;font-size:9.5px;letter-spacing:1px;
border-radius:5px;padding:3px 7px}

/* Expanded content sits in an inset card, two columns, green section labels. */
.xh-acc>div{display:none}
.xh-acc[data-open="true"]>div{display:block;margin:12px 0 16px;
background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.12);
border-radius:14px;padding:16px 16px 14px}
.xh-mini{font-weight:800;font-size:9.5px;letter-spacing:1.6px;color:#8FD481;margin:0 0 8px}
.xh-mini + .xh-grid + .xh-mini{margin-top:14px}
.xh-grid{display:grid;grid-template-columns:1fr 1fr;gap:2px 12px;margin-bottom:12px}
.xh-grid a{display:flex;align-items:center;min-height:40px;padding:4px 2px;
font-weight:600;font-size:13px;color:rgba(255,255,255,.92);text-decoration:none;
border-bottom:0}
.xh-grid a:active{color:#8FD481}
.xh-all{display:inline-block;font-weight:800;font-size:13px;color:#8FD481;
text-decoration:none;padding:6px 2px;min-height:32px}

/* Pinned actions at the foot of the panel. */
.xh-pinned{flex:none;background:rgba(15,23,42,.25);border-top:1px solid rgba(255,255,255,.12);
padding:14px 20px calc(14px + env(safe-area-inset-bottom));display:grid;gap:10px}
.xh-pinned .cta{width:100%;min-height:48px;border:0;border-radius:12px;cursor:pointer;
background:#6BB85C;color:#0F172A;font-weight:800;font-size:15.5px;font-family:inherit}
.xh-pinned .call{width:100%;min-height:48px;display:flex;align-items:center;
justify-content:center;border:1.5px solid rgba(255,255,255,.45);border-radius:12px;
color:#fff;font-weight:800;font-size:15px;text-decoration:none}
.xh-pinned .trust{display:flex;align-items:center;justify-content:center;gap:8px;
font-weight:700;font-size:12px;color:rgba(255,255,255,.82)}
.xh-pinned .trust .s{color:#F6A723;letter-spacing:1px}

/* --------------------------- chat widget theme ---------------------------
   The widget renders in a shadow root, so these are the only styles of ours that
   reach it: custom properties pierce the boundary, and every one below is a
   documented token with a default, so setting them is configuration rather than
   override. We used to append a whole stylesheet into the shadow root instead.
   That is gone as of 2026-08-13 — FollowUp Pro shipped the fixes it was patching
   around, including the .card p / .fine specificity bug that kept the consent
   disclosure from ever rendering as fine print, and the missing safe-area insets.
   Do not reintroduce it. If the widget looks wrong, report it upstream; a patch
   here is invisible to them and breaks silently when they rename a class.

   BOTH TAG NAMES ON PURPOSE. The element was <extreme-chat>; the build shipped on
   2026-08-13 renamed it to <extreme-chat-v3>, which silently killed every rule below
   — the tokens stopped applying and the menu-open hide stopped matching, with no
   error anywhere. Nothing in their docs mentions the rename; it was found by reading
   the live DOM. Keep old names here when they add v4, and do not assume a selector
   that worked last week still resolves. */
extreme-chat,
extreme-chat-v3{
  --exc-purple:#5F2980; --exc-green:#6BB85C; --exc-border:#E7E7EA;
  --exc-ink:#0F172A; --exc-slate:#64748B;
  --exc-radius-input:12px; --exc-radius-btn:12px; --exc-radius-card:16px;
  --exc-weight-heading:900; --exc-weight-btn:800; --exc-size-fine:12.5px}


@media (max-width:1023px){
  .xh-bar{padding:12px 24px;gap:14px}
  .xh-nav{gap:16px;font-size:13.5px}
  .xh-phone{display:none}
  .xm-grid{grid-template-columns:1fr 1fr;gap:28px;padding:24px 24px 28px}
  .xm-aside{grid-column:1 / -1;flex-direction:row}
  .xm-promo{flex:1}
}
@media (max-width:809px){
  .xh-bar{padding:10px 16px}
  .xh-nav,.xh-actions{display:none}
  .xh-burger{display:flex}
  .xh-logo img{height:38px}

  /* The widget sits wherever it puts itself. We used to lift it clear of a sticky
     dock of our own; the dock went on 2026-08-13 because the widget now carries Call
     and Chat itself, so there is nothing left to clear and no offset to set.

     What stays is getting it out of the way when a modal of ours owns the screen.
     This hides the HOST element rather than ::part(launcher): the widget renders two
     buttons now, and a rule aimed at one named part would leave the other one sitting
     over the menu. The host is an ordinary light-DOM element and hiding it takes the
     whole widget, whatever it grows next.

     Safe on mobile specifically, which is all this block covers: the chat panel is
     full screen there, so neither the menu nor the wizard can be opened behind it,
     and this can never hide the only control that closes an open chat.
     :has() is the live-updating half — the wizard mounts .xw-root when it opens and
     unmounts it on close. Browsers without :has() keep today's behavior. */
  .xh-menu-open extreme-chat, .xh-menu-open extreme-chat-v3,
  html:has(.xw-root) extreme-chat, html:has(.xw-root) extreme-chat-v3{display:none}
}
@media (prefers-reduced-motion:reduce){.xh-hd *{transition:none!important}}

/* ========================= Text Us consent sheet =========================
   Every Text Us button on the site is still an <a href="sms:...">, and this only
   intercepts the click. With JS off, or if this script fails, the anchor works
   exactly as it always did and opens the composer — the consent capture is an
   enhancement on top, never a gate in front.

   The checkbox does NOT gate the button. Telnyx rejected the chat widget on
   2026-08-13 for making the number mandatory with no optional checkbox beside the
   opt-in language, and a sheet that refuses to open Messages until someone ticks a
   box is the same defect wearing our brand. Name and number are required because
   the reviewer explicitly allows a mandatory field when the checkbox is optional;
   consent itself never is. */
.xt-back{position:fixed;inset:0;z-index:9998;display:none;align-items:center;
justify-content:center;padding:20px;background:rgba(15,23,42,.55);
-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.xt-back[data-open="true"]{display:flex}
.xt-card{width:100%;max-width:430px;max-height:calc(100vh - 40px);overflow-y:auto;
background:#fff;border-radius:18px;padding:26px 24px 22px;position:relative;
font-family:"Montserrat",ui-sans-serif,system-ui,sans-serif;color:#0F172A;
box-shadow:0 24px 60px rgba(15,23,42,.3)}
.xt-card h2{margin:0 0 6px;font-size:21px;font-weight:900;letter-spacing:-.028em}
.xt-card .sub{margin:0 0 18px;font-size:13.5px;line-height:1.55;color:#475569}
.xt-x{position:absolute;top:12px;right:12px;width:36px;height:36px;border:0;border-radius:10px;
background:#F4F1F8;color:#5F2980;font-size:17px;cursor:pointer;line-height:1}
.xt-x:hover{background:#EAE2F0}
.xt-check{display:flex;gap:10px;align-items:flex-start;margin:4px 0 16px;cursor:pointer}
.xt-check input{flex:none;width:20px;height:20px;margin:1px 0 0;accent-color:#5F2980;cursor:pointer}
.xt-check input:focus-visible{outline:2px solid #5F2980;outline-offset:2px}
.xt-copy{font-size:12px;line-height:1.5;color:#64748B}
.xt-copy a{color:#5F2980;font-weight:700;text-decoration:underline;text-underline-offset:2px}
.xt-go{width:100%;min-height:48px;border:0;border-radius:12px;background:#6BB85C;color:#0F172A;
font-family:inherit;font-weight:800;font-size:15.5px;cursor:pointer}
.xt-go:hover{background:#8FD481}
.xt-go[disabled]{opacity:.5;cursor:default}
.xt-note{margin:11px 0 0;font-size:11.5px;line-height:1.45;color:#94A3B8;text-align:center}
@media (max-width:359px){.xt-card{padding:22px 18px 18px}}

/* ============================== footer ============================== */
.xf{position:relative;background:#3A1A4E;color:#fff;overflow:hidden;
font-family:"Montserrat",ui-sans-serif,system-ui,sans-serif}
.xf *{box-sizing:border-box}
.xf a{color:inherit;text-decoration:none}
.xf-accent{height:4px;background:linear-gradient(90deg,#6BB85C,#5F2980)}
.xf-mark{position:absolute;right:-60px;top:20px;width:340px;opacity:.05;
transform:rotate(-8deg);filter:brightness(0) invert(1);pointer-events:none}
.xf-wrap{position:relative;max-width:1280px;margin:0 auto;padding:0 40px}
.xf-cta{display:flex;align-items:center;justify-content:space-between;gap:24px;
padding:40px 0 34px;border-bottom:1px solid rgba(255,255,255,.14)}
.xf-cta h2{margin:0;font-style:italic;font-weight:900;font-size:26px;letter-spacing:-.5px}
.xf-cta p{margin:8px 0 0;font-size:14px;font-weight:500;color:rgba(255,255,255,.72)}
.xf-cta-btns{display:flex;gap:10px;flex:none}
.xf-btn-green,.xf-btn-outline{display:inline-flex;align-items:center;justify-content:center;
min-height:46px;padding:12px 22px;border-radius:12px;font-weight:800;font-size:14.5px;
border:0;cursor:pointer;font-family:inherit;white-space:nowrap}
.xf-btn-green{background:#6BB85C;color:#0F172A}
.xf-btn-green:hover{background:#8FD481}
.xf-btn-outline{background:transparent;color:#fff;border:1.5px solid rgba(255,255,255,.4)}
.xf-btn-outline:hover{border-color:#6BB85C;color:#8FD481}
.xf-grid{display:grid;grid-template-columns:1.7fr 1fr 1fr 1fr 1fr;gap:32px;padding:34px 0 30px}
/* The tight file, not logo-white.png: that one is 55% transparent padding, so a
   76px box only ever drew a 34px logo. Same box, nearly twice the mark. */
.xf-logo{height:64px;width:auto;display:block}
.xf-blurb{margin:14px 0 0;font-size:13px;line-height:1.6;font-weight:500;color:rgba(255,255,255,.72)}
.xf-247{display:flex;align-items:center;gap:8px;margin-top:14px;font-size:12.5px;font-weight:700}
.xf-247 .dot{width:8px;height:8px;border-radius:50%;background:#6BB85C}
.xf-social{display:flex;flex-wrap:wrap;gap:12px;margin-top:16px}
.xf-social a{font-size:12.5px;font-weight:600;color:rgba(255,255,255,.72);min-height:32px;
display:inline-flex;align-items:center}
.xf-social a:hover{color:#8FD481}
.xf-h{font-size:10.5px;font-weight:800;letter-spacing:1.6px;color:#8FD481;margin-bottom:12px}
.xf-col a{display:block;padding:6px 0;font-size:13.5px;font-weight:600;
color:rgba(255,255,255,.78);min-height:32px}
.xf-col a:hover{color:#fff}
.xf-phone{font-weight:800!important;font-size:16px!important;color:#fff!important}
/* The sitewide NAP. `address` because that is what it is; font-style reset because
   the element italicises by default and the rest of the column does not. */
.xf-nap{font-style:normal;font-size:13.5px;font-weight:600;line-height:1.6;
color:rgba(255,255,255,.78);margin:0 0 8px}
.xf-nap b{display:block;color:#fff;font-weight:800;margin-bottom:2px}
.xf-meta{font-size:12.5px;color:rgba(255,255,255,.55);margin-top:8px;line-height:1.6}
.xf-areas{padding:22px 0;border-top:1px solid rgba(255,255,255,.12);
font-size:12px;line-height:1.7;color:rgba(255,255,255,.55);display:grid;gap:8px}
.xf-areas b{color:rgba(255,255,255,.8);font-weight:800;letter-spacing:.4px;margin-right:6px}
.xf-areas a{color:rgba(255,255,255,.62);text-decoration:none}
.xf-areas a:hover{color:#8FD481;text-decoration:underline}
/* The office row is the one line in this band that points at premises rather than at
   service areas, so it reads a step brighter than the towns beneath it. */
.xf-offices a{color:rgba(255,255,255,.85);font-weight:700}
.xf-bottom{display:flex;align-items:center;justify-content:space-between;gap:12px;
padding:18px 0 30px;border-top:1px solid rgba(255,255,255,.12);
font-size:12px;color:rgba(255,255,255,.55)}
.xf-bottom .links{display:flex;gap:18px}
.xf-bottom a{min-height:32px;display:inline-flex;align-items:center}
.xf-bottom a:hover{color:#8FD481}

@media (max-width:1023px){
  .xf-wrap{padding:0 24px}
  .xf-grid{grid-template-columns:1.4fr 1fr 1fr;gap:28px}
  .xf-logo{height:56px}
  .xf-mark{width:240px}
}
@media (max-width:809px){
  .xf-wrap{padding:0 20px}
  .xf-cta{flex-direction:column;align-items:stretch;text-align:left;padding:32px 0 28px}
  .xf-cta h2{font-size:21px}
  .xf-cta-btns{flex-direction:column}
  .xf-btn-green,.xf-btn-outline{width:100%;min-height:48px}
  .xf-grid{grid-template-columns:1fr 1fr;gap:24px 20px;padding:30px 0 26px}
  .xf-logo{height:50px}
  .xf-brand{grid-column:1 / -1}
  .xf-bottom{flex-direction:column;align-items:flex-start;gap:10px}
  .xf-mark{width:150px;top:12px;right:-24px}
}
@media (max-width:479px){ .xf-grid{grid-template-columns:1fr} }
