/* ==========================================================================
   22 ELECTRICAL WORKS — Concept 1 "VOLTAGE"
   Dark flagship. Brand palette pulled from the live site CSS + logo artwork.
   ========================================================================== */

:root{
  --blue:#00A2E2;
  --blue-lt:#6AB9E2;
  --ice:#CFF9FE;
  --navy:#212F6E;
  --ink:#0B0E14;
  --ink2:#11151E;
  --ink3:#171C27;
  --line:rgba(255,255,255,.10);
  --line2:rgba(255,255,255,.16);
  --txt:#E8EBF0;
  --mut:#939AA8;
  --paper:#F6F5F6;
  --hd:'Manrope',system-ui,sans-serif;
  --bd:'Poppins',system-ui,sans-serif;
  --wrap:1240px;
  --r:16px;
  --ease:cubic-bezier(.22,1,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--ink);color:var(--txt);
  font-family:var(--bd);font-size:16px;line-height:1.65;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{max-width:100%;display:block}
figure{margin:0}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{font-family:var(--hd);font-weight:800;line-height:1.05;letter-spacing:-.025em;margin:0}
p{margin:0}
button{font:inherit}
::selection{background:var(--blue);color:#001018}
section{scroll-margin-top:84px}

.wrap{width:100%;max-width:var(--wrap);margin:0 auto;padding:0 24px}

/* ---------- scroll progress ---------- */
.progress{position:fixed;inset:0 auto auto 0;height:3px;width:0;z-index:120;
  background:linear-gradient(90deg,var(--blue),var(--ice));box-shadow:0 0 14px rgba(0,162,226,.7)}

/* ---------- concept ribbon ---------- */
.cnote{position:relative;z-index:90;background:#1b2230;color:#c2cad8;
  font-size:12.5px;letter-spacing:.01em;display:flex;align-items:center;justify-content:center;
  gap:14px;padding:9px 46px 9px 18px;text-align:center;border-bottom:1px solid var(--line)}
.cnote strong{color:var(--ice);font-weight:600}
.cnote button{position:absolute;right:10px;top:50%;transform:translateY(-50%);
  background:none;border:0;color:#8e97a6;font-size:19px;line-height:1;cursor:pointer;padding:6px 9px;border-radius:8px}
.cnote button:hover{background:rgba(255,255,255,.08);color:#fff}

/* ---------- header ---------- */
.hd{position:sticky;top:0;z-index:100;background:rgba(11,14,20,.72);
  backdrop-filter:saturate(160%) blur(14px);-webkit-backdrop-filter:saturate(160%) blur(14px);
  border-bottom:1px solid var(--line);transition:background .3s,border-color .3s}
.hd.scrolled{background:rgba(11,14,20,.94);border-bottom-color:var(--line2)}
.hd-in{display:flex;align-items:center;gap:26px;height:72px}
.brand{display:flex;align-items:center;gap:11px;flex-shrink:0}
.brand img{height:38px;width:auto}
.nav{display:flex;gap:26px;margin-left:auto;font-size:14.5px;font-weight:500;color:#b9c1cd}
.nav a{position:relative;padding:6px 0;transition:color .2s}
.nav a::after{content:'';position:absolute;left:0;right:100%;bottom:0;height:2px;
  background:var(--blue);transition:right .35s var(--ease)}
.nav a:hover{color:#fff}
.nav a:hover::after{right:0}
.hd-cta{display:flex;align-items:center;gap:12px;flex-shrink:0}

.tel{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:14.5px;color:var(--ice);
  padding:9px 14px;border:1px solid var(--line2);border-radius:999px;transition:.25s}
.tel:hover{border-color:var(--blue);background:rgba(0,162,226,.12)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-family:var(--hd);font-weight:700;font-size:15px;letter-spacing:-.01em;
  padding:14px 26px;border-radius:999px;border:1px solid transparent;cursor:pointer;
  transition:transform .25s var(--ease),box-shadow .25s,background .25s,color .25s;white-space:nowrap}
.btn-p{background:var(--blue);color:#04121c;box-shadow:0 8px 26px rgba(0,162,226,.32)}
.btn-p:hover{transform:translateY(-2px);box-shadow:0 14px 36px rgba(0,162,226,.5);background:#19b2ee}
.btn-g{background:rgba(255,255,255,.05);color:#fff;border-color:var(--line2)}
.btn-g:hover{border-color:var(--blue);background:rgba(0,162,226,.14);transform:translateY(-2px)}
.btn-sm{padding:11px 20px;font-size:14px}

.burger{display:none;background:none;border:1px solid var(--line2);border-radius:11px;
  width:44px;height:44px;padding:0;cursor:pointer;position:relative}
.burger span{position:absolute;left:12px;right:12px;height:2px;background:#fff;border-radius:2px;transition:.3s var(--ease)}
.burger span:nth-child(1){top:15px}
.burger span:nth-child(2){top:21px}
.burger span:nth-child(3){top:27px}
.burger.on span:nth-child(1){top:21px;transform:rotate(45deg)}
.burger.on span:nth-child(2){opacity:0}
.burger.on span:nth-child(3){top:21px;transform:rotate(-45deg)}

.mmenu{display:none;flex-direction:column;background:#0e1219;border-bottom:1px solid var(--line)}
.mmenu.open{display:flex}
.mmenu a{padding:16px 24px;border-top:1px solid var(--line);font-weight:500;font-size:16px}
.mmenu .mm-cta{display:flex;gap:10px;padding:16px 24px;border-top:1px solid var(--line)}
.mmenu .mm-cta .btn{flex:1}

/* ---------- hero ---------- */
.hero{position:relative;min-height:min(92vh,860px);display:flex;align-items:flex-end;
  overflow:hidden;padding:120px 0 56px}
.hero-bg{position:absolute;inset:-8% 0 -8%;z-index:0;will-change:transform}
/* five stacked slides. Each one slow zooms out over its 8s turn then
   crossfades into the next, so the hero is never a static photo.
   40s loop = 5 x 8s. The -1.6s delay on the first slide starts it already
   faded in, otherwise the hero opens on a black frame. */
.hero-slide{position:absolute;inset:0;opacity:0;
  animation:heroFade 40s var(--ease) infinite both}
.hero-slide:nth-child(1){animation-delay:-1.6s}
.hero-slide:nth-child(2){animation-delay:6.4s}
.hero-slide:nth-child(3){animation-delay:14.4s}
.hero-slide:nth-child(4){animation-delay:22.4s}
.hero-slide:nth-child(5){animation-delay:30.4s}
/* the picture wrapper has to be a block, otherwise the img's height:100%
   resolves against an inline box and the background collapses. */
.hero-slide picture{display:block;width:100%;height:100%}
/* the zoom lives on the img, not the slide: the slide owns opacity and the
   JS parallax owns the wrapper's transform, so all three stay out of each
   other's way. --py anchors each photo's faces (set per slide in the HTML)
   so a wide, heavily letterboxed hero still never crops a head off. */
/* --z is that photo's face zoom. The frames are wide two-up shots, so at 1:1 the
   faces end up small AND land behind the headline / qualifier card. Scaling each
   slide in around its own face anchor makes the team read at a glance and gives
   object-position real room to move (at scale 1 the photo covers the box almost
   exactly, so --px/--py barely bite). */
.hero-slide img{width:100%;height:100%;object-fit:cover;
  object-position:var(--px,50%) var(--py,30%);
  transform-origin:var(--px,50%) var(--py,30%);
  transform:scale(var(--z,1));
  animation:heroZoomOut 40s linear infinite both}
.hero-slide:nth-child(1) img{animation-delay:-1.6s}
.hero-slide:nth-child(2) img{animation-delay:6.4s}
.hero-slide:nth-child(3) img{animation-delay:14.4s}
.hero-slide:nth-child(4) img{animation-delay:22.4s}
.hero-slide:nth-child(5) img{animation-delay:30.4s}
@keyframes heroFade{0%{opacity:0}4%{opacity:1}20%{opacity:1}24%{opacity:0}100%{opacity:0}}
@keyframes heroZoomOut{
  0%{transform:scale(calc(var(--z,1) * 1.05))}
  24%{transform:scale(var(--z,1))}
  100%{transform:scale(var(--z,1))}}
@media(prefers-reduced-motion:reduce){
  .hero-slide,.hero-slide img{animation:none;transform:none}
  .hero-slide{opacity:0}.hero-slide:first-child{opacity:1}}
/* Once the hero stacks (1080px, where the qualifier drops under the copy) the
   photo stops being a full height backdrop. Filling a 2000px tall column with a
   3:2 frame means "cover" zooms right in and slices whoever is standing near an
   edge, so instead the photo runs as a wide band at its OWN aspect ratio —
   nothing is cropped, nobody loses a face or an arm — and fades into the ink so
   the copy underneath still sits on dark. */
@media(max-width:1080px){
  .hero-bg{inset:0 0 auto;height:auto;aspect-ratio:3/2;
    -webkit-mask-image:linear-gradient(180deg,#000 56%,rgba(0,0,0,.35) 84%,transparent 100%);
    mask-image:linear-gradient(180deg,#000 56%,rgba(0,0,0,.35) 84%,transparent 100%)}
  /* the band shows the whole 3:2 frame, so the desktop face zoom would slice
     people off the edges. A gentle 1.12 anchored low still keeps everyone in
     frame while lifting the faces clear of the headline. */
  .hero-slide img{object-position:50% 24%;transform-origin:8% 62%;--z:1.14}
}
/* phones keep the single tall portrait crop: a landscape frame at 390px wide is
   a sliver, and four extra photos is a lot of data on a phone. Cuts off at 600px
   rather than 700px: above that the portrait scales up so far that Josh's face
   fills the fold and the headline lands back on top of it, while the 3:2 band
   already reads fine at that width. */
@media(max-width:600px){
  /* On a phone the copy stack fills the whole band, so wherever Josh's face
     landed a button or a paragraph sat across it. The band is now trimmed at the
     TOP (2389 -> 2000, all sky and treetops) and bottom anchored, which lifts his
     head into the clear strip between the header and the headline — the copy runs
     over his chest instead of his eyes. The hero's top padding below opens that
     strip up. transform-origin sits on his face so the slow zoom holds it there. */
  .hero-bg{aspect-ratio:620/1920;
    -webkit-mask-image:linear-gradient(180deg,#000 74%,rgba(0,0,0,.35) 92%,transparent 100%);
    mask-image:linear-gradient(180deg,#000 74%,rgba(0,0,0,.35) 92%,transparent 100%)}
  .hero-slide:not(:first-child){display:none}
  .hero-slide{opacity:1;animation:none}
  .hero-slide img{object-position:50% 100%;transform-origin:50% 12%;--z:1;
    animation:heroZoomOnce 24s var(--ease) both;animation-delay:0s}
  .hero{min-height:auto;padding:175px 0 44px}}
@keyframes heroZoomOnce{from{transform:scale(1.06)}to{transform:scale(1)}}
/* The veil used to be a blanket dark wash top to bottom, which buried the team's
   faces in the upper third. It is now weighted to where the TEXT is instead: a
   soft top, a strong pool bottom left under the copy, and only a light tint
   across the middle band where the faces sit. */
.hero-veil{position:absolute;inset:0;z-index:1;
  background:
    linear-gradient(180deg,rgba(11,14,20,.58) 0%,rgba(11,14,20,.16) 26%,rgba(11,14,20,.20) 52%,rgba(11,14,20,.80) 82%,var(--ink) 100%),
    linear-gradient(90deg,rgba(11,14,20,.72) 0%,rgba(11,14,20,.40) 30%,rgba(11,14,20,0) 58%),
    radial-gradient(90% 70% at 12% 78%,rgba(0,162,226,.22),transparent 62%)}
.hero-grid{position:absolute;inset:0;z-index:1;opacity:.5;
  background-image:linear-gradient(rgba(255,255,255,.045) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.045) 1px,transparent 1px);
  background-size:74px 74px;
  mask-image:radial-gradient(75% 65% at 50% 45%,#000,transparent 78%);
  -webkit-mask-image:radial-gradient(75% 65% at 50% 45%,#000,transparent 78%)}
.hero .wrap{position:relative;z-index:2;width:100%}

.h1{font-size:clamp(30px,4.6vw,58px);max-width:none;margin-bottom:22px;
  text-transform:uppercase;letter-spacing:-.015em;line-height:1.04;
  /* liquid glass: the glyphs sit at ~78% white so the photo behind reads through
     them, with a soft dark drop and a faint light rim doing the legibility work
     the solid fill used to do (Tim, 19 Aug 2026) */
  color:rgba(255,255,255,.78);-webkit-text-stroke:.022em rgba(255,255,255,.58);
  text-shadow:0 4px 30px rgba(0,0,0,.62),0 1px 2px rgba(0,0,0,.35),
              0 0 1px rgba(255,255,255,.28)}
.h1 .hl{display:block}
/* Google review stars, sized off the headline so they scale with it */
.gstars{display:inline-flex;align-items:center;gap:.06em;vertical-align:baseline;
  color:#FBBC04;-webkit-text-stroke:0}
.gstars svg{width:.78em;height:.78em;display:block}
.h1 .w{display:inline-block;overflow:hidden;vertical-align:bottom}
.h1 .w i{display:inline-block;font-style:normal;transform:translateY(105%);
  animation:rise .95s var(--ease) forwards;animation-delay:calc(var(--i)*.075s + .15s)}
@keyframes rise{to{transform:translateY(0)}}
.h1 em{font-style:normal;color:var(--blue);position:relative}
.hero-sub{font-size:clamp(16px,1.9vw,19px);color:#c3cad6;max-width:56ch;margin-bottom:14px;
  line-height:1.65;opacity:0;animation:fadeUp .9s var(--ease) .75s forwards}
.hero-sub2{max-width:50ch;margin-bottom:32px;animation-delay:.85s}

/* the suburb cycles one at a time, big and in the brand blue. all four stay in
   the markup so the copy still reads and still indexes, only one is visible. */
.rot{display:inline-grid;vertical-align:baseline;line-height:1.1}
.rot i{grid-area:1/1;font-style:normal;font-family:var(--hd);font-weight:800;
  font-size:1.5em;letter-spacing:-.02em;color:var(--blue);white-space:nowrap;
  text-shadow:0 0 30px rgba(0,162,226,.5);
  opacity:0;transform:translateY(.32em);
  animation:rotsub 13.2s var(--ease) infinite;animation-delay:calc(var(--r) * 3.3s)}
@keyframes rotsub{
  0%{opacity:0;transform:translateY(.32em)}
  3%{opacity:1;transform:none}
  22%{opacity:1;transform:none}
  25%,100%{opacity:0;transform:translateY(-.32em)}
}
@keyframes fadeUp{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.hero-cta{display:flex;flex-wrap:wrap;gap:14px;
  opacity:0;animation:fadeUp .9s var(--ease) .9s forwards}

/* hero splits into copy on the left, qualifier card on the right */
.hero-in{display:grid;grid-template-columns:minmax(0,1fr) 460px;gap:56px;
  align-items:center;margin-bottom:44px}
.hero-copy{min-width:0}

.trust{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  opacity:0;animation:fadeUp .9s var(--ease) 1.05s forwards;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.trust div{background:rgba(11,14,20,.62);padding:17px 18px 18px;
  display:flex;align-items:flex-start;gap:11px}
.trust .tr-ic{display:flex;align-items:center;justify-content:center;flex-shrink:0;
  width:34px;height:34px;border-radius:10px;color:var(--blue);
  border:1px solid rgba(0,162,226,.32);background:rgba(0,162,226,.10);
  animation:icpulse 6s var(--ease) infinite;animation-delay:calc(var(--g,0) * .5s)}
.trust .tr-t{min-width:0}
.trust b{display:block;font-family:var(--hd);font-size:15px;color:#fff;font-weight:700;
  line-height:1.35;margin-bottom:2px;padding-bottom:1px}
.trust span{font-size:12.5px;color:var(--mut);line-height:1.5;display:block}

/* ---------- qualifier card (hero, right) ---------- */
/* blue liquid glass: transparent, NOT blurred (Tim, 16 Aug 2026) — the photo
   behind it still reads, so you can see a bit of Josh through the card. */
.qz{position:relative;
  background:linear-gradient(158deg,rgba(0,162,226,.20) 0%,rgba(8,32,58,.44) 42%,rgba(6,12,22,.66) 100%);
  border:1px solid rgba(0,162,226,.34);border-radius:22px;
  padding:28px 26px 26px;
  box-shadow:0 30px 80px rgba(0,0,0,.5),
             inset 0 1px 0 rgba(255,255,255,.16),
             inset 0 -1px 0 rgba(0,162,226,.12);
  opacity:0;animation:fadeUp .9s var(--ease) 1s forwards}
/* the specular sheen that sells the glass, kept off the pointer */
.qz::before{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(158deg,rgba(255,255,255,.14),transparent 38%)}
.qz>*{position:relative;z-index:1}
.qz-logo{margin-bottom:22px;padding-bottom:20px;border-bottom:1px solid var(--line)}
.qz-logo img{width:100%;height:auto}
.qz-h{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:6px}
.qz-h h2,.qz-h h3{font-size:21px;color:#fff}
.qz-h span{font-size:12px;color:var(--mut);font-family:var(--hd);font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;white-space:nowrap}
.qz-p{font-size:13.5px;color:var(--mut);margin-bottom:20px}
/* the card is deliberately see through, so the quiet copy on it carries its own
   shadow rather than relying on a panel behind it */
.qz-p,.qz-h span,.qz .qlabel,.qz .qnote,.qz .consent{text-shadow:0 1px 10px rgba(4,8,14,.85)}
/* the progress bar reads like a charger filling: the blue keeps flowing and a
   bright pulse runs along whatever is already charged */
.qz-bar{height:5px;border-radius:99px;background:rgba(255,255,255,.1);overflow:hidden;margin-bottom:24px}
.qz-bar i{display:block;position:relative;height:100%;width:33.33%;border-radius:99px;overflow:hidden;
  background:linear-gradient(90deg,var(--blue),var(--ice));
  box-shadow:0 0 14px rgba(0,162,226,.55);transition:width .5s var(--ease)}
.qz-bar i::before{content:'';position:absolute;inset:0;border-radius:99px;
  background:linear-gradient(90deg,transparent 0,rgba(255,255,255,.85) 48%,transparent 92%);
  transform:translateX(-100%);animation:chargeflow 1.9s linear infinite}
.qz-bar i::after{content:'';position:absolute;top:50%;right:1px;width:5px;height:5px;
  margin-top:-2.5px;border-radius:50%;background:#fff;
  box-shadow:0 0 9px 2px rgba(207,249,254,.9);animation:chargetip 1.9s ease-in-out infinite}
@keyframes chargeflow{0%{transform:translateX(-100%)}100%{transform:translateX(100%)}}
@keyframes chargetip{0%,100%{opacity:.45}50%{opacity:1}}

.qstep{display:none}
.qstep.on{display:block;animation:qin .45s var(--ease)}
@keyframes qin{from{opacity:0;transform:translateX(14px)}to{opacity:1;transform:none}}
.qlabel{display:block;font-family:var(--hd);font-size:12.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mut);margin-bottom:11px}

/* every chip is the same pill: equal rows, and the label fills its row so a two
   line option is exactly as tall as a one line option */
.chips{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:22px;grid-auto-rows:1fr}
.chip{position:relative;display:flex}
.chip input{position:absolute;opacity:0;width:0;height:0}
.chip span{display:flex;align-items:center;gap:10px;flex:1;width:100%;min-height:62px;padding:12px 14px;
  border:1.5px solid var(--line2);border-radius:13px;background:rgba(255,255,255,.03);
  font-size:14px;font-weight:500;color:#dfe5f0;cursor:pointer;line-height:1.3;
  transition:border-color .22s,background .22s,transform .22s var(--ease)}
.chip span svg{color:var(--blue);flex-shrink:0;
  animation:icpulse 6s var(--ease) infinite;animation-delay:calc(var(--g,0) * .5s)}

/* icons come alive every few seconds, like something on the circuit firing */
@keyframes icpulse{
  0%,68%,100%{filter:none;transform:scale(1)}
  76%{filter:drop-shadow(0 0 9px rgba(0,162,226,.95)) brightness(1.35);transform:scale(1.08)}
  84%{filter:drop-shadow(0 0 4px rgba(0,162,226,.55)) brightness(1.1);transform:scale(1)}
}
.chip span:hover{border-color:rgba(0,162,226,.55);background:rgba(0,162,226,.08)}
.chip input:checked + span{border-color:var(--blue);background:rgba(0,162,226,.18);color:#fff;
  box-shadow:0 0 0 3px rgba(0,162,226,.15)}
.chip input:focus-visible + span{outline:2px solid var(--ice);outline-offset:2px}
.chips.one{grid-template-columns:1fr}
.chips.one span{min-height:52px}

.qf{margin-bottom:16px}
.qf label{display:block;font-family:var(--hd);font-size:12.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mut);margin-bottom:8px}
.qf input,.qf textarea{width:100%;background:rgba(6,9,16,.72);border:1.5px solid var(--line2);
  border-radius:12px;padding:15px 16px;color:#fff;font-family:var(--bd);font-size:16px;
  transition:border-color .25s,box-shadow .25s;-webkit-appearance:none;appearance:none}
.qf textarea{resize:vertical;min-height:92px}
.qf input:focus,.qf textarea:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(0,162,226,.16)}
.qf input::placeholder,.qf textarea::placeholder{color:#69707e}
.qrow{display:grid;grid-template-columns:1fr 1fr;gap:14px}

.qz .consent{display:flex;gap:11px;align-items:flex-start;font-size:12.5px;color:var(--mut);
  margin:4px 0 18px;line-height:1.55;cursor:pointer}
.qz .consent input{width:19px;height:19px;flex-shrink:0;margin-top:2px;accent-color:var(--blue)}

.qnav{display:flex;gap:11px}
.qnav .btn{flex:1}
.qnav .back{flex:0 0 auto;padding-left:20px;padding-right:20px}
.qnav .btn:disabled{opacity:.45;cursor:not-allowed;transform:none;box-shadow:none}
.qnote{font-size:11.5px;color:#69707e;text-align:center;margin-top:13px;line-height:1.5}

.qok{display:none;text-align:center;padding:22px 4px 10px}
.qok.on{display:block}
.qok .tick{width:64px;height:64px;border-radius:50%;background:rgba(0,162,226,.18);
  border:1px solid rgba(0,162,226,.45);display:grid;place-items:center;margin:0 auto 18px;color:var(--blue)}
.qok h3,.qok h4{font-family:var(--hd);font-size:21px;color:#fff;margin-bottom:9px}
.qok p{font-size:14.5px;color:var(--mut);margin-bottom:20px}

/* ---------- marquee ---------- */
.mq{border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  background:var(--ink2);overflow:hidden;padding:16px 0}
.mq-in{display:flex;gap:0;width:max-content;animation:slide 38s linear infinite}
.mq:hover .mq-in{animation-play-state:paused}
@keyframes slide{to{transform:translateX(-50%)}}
.mq-in span{display:inline-flex;align-items:center;gap:22px;padding:0 22px;
  font-family:var(--hd);font-weight:700;font-size:15px;letter-spacing:.08em;
  text-transform:uppercase;color:#5e6878;white-space:nowrap}
.mq-in span svg{color:var(--blue);flex-shrink:0}

/* ---------- section furniture ---------- */
.sec{padding:104px 0;position:relative}
.sec-tight{padding:78px 0}
/* Photo backed section — a full bleed image sitting behind the content, scrimmed
   hard so it reads as atmosphere and never fights the copy. Same treatment
   language as .phero, just darker because content sits over the middle of it. */
.sec-photo{overflow:hidden;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.sec-photo>.sec-bg{position:absolute;inset:0;z-index:0}
.sec-photo>.sec-bg img{width:100%;height:100%;object-fit:cover;object-position:50% 34%;
  filter:saturate(.78) brightness(.36)}
.sec-photo::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(180deg,var(--ink) 0%,rgba(11,14,20,.7) 22%,rgba(11,14,20,.7) 78%,var(--ink) 100%),
    radial-gradient(66% 62% at 50% 52%,rgba(11,14,20,.66),transparent 72%),
    radial-gradient(70% 70% at 6% 4%,rgba(0,162,226,.16),transparent 60%)}
.sec-photo>.wrap{position:relative;z-index:2}
/* On phones the cards run edge to edge, so the centre scrim would bury the photo
   entirely. Lift it and let the crop breathe instead. */
@media(max-width:700px){
  .sec-photo>.sec-bg img{filter:saturate(.78) brightness(.46);object-position:50% 42%}
  .sec-photo::after{background:
    linear-gradient(180deg,var(--ink) 0%,rgba(11,14,20,.66) 18%,rgba(11,14,20,.66) 82%,var(--ink) 100%),
    radial-gradient(70% 70% at 6% 4%,rgba(0,162,226,.14),transparent 60%)}
}
#recent-jobs{padding-bottom:40px}
#recent-jobs+.sec{padding-top:40px}
.shead{margin-bottom:52px;max-width:70ch}
/* No leading dash rule on the eyebrow (Tim, 4 Aug 2026) — the label stands on
   its own. */
/* the eyebrow sits in a blue outlined pill so every section opens on the same
   piece of brand furniture (Tim, 16 Aug 2026) */
.klabel{display:inline-flex;align-items:center;font-family:var(--hd);font-weight:700;
  font-size:11.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--blue);margin-bottom:16px;
  padding:7px 15px 6px;border:1px solid rgba(0,162,226,.42);border-radius:99px;
  background:rgba(0,162,226,.08);box-shadow:0 0 22px rgba(0,162,226,.10) inset}
.h2{font-size:clamp(29px,4.4vw,50px);margin-bottom:16px}
.h2 em{font-style:normal;color:var(--blue)}
/* power flicker on the contact CTA's "home or business" — a slow voltage-style
   glow breathing behind the text, on brand for an electrician's call to action */
.h2 em.pwr{display:inline-block;animation:pwrGlow 2.6s ease-in-out infinite}
@keyframes pwrGlow{
  0%,100%{text-shadow:0 0 18px rgba(0,162,226,.55)}
  50%{text-shadow:0 0 6px rgba(0,162,226,.15)}
}
@media(prefers-reduced-motion:reduce){.h2 em.pwr{animation:none}}
.lead{color:var(--mut);font-size:17px;max-width:62ch}

/* reveal — scoped to .js so that with scripting off, or if site.js fails to
   load, every section is simply visible rather than blank. */
.js .rv{opacity:0;transform:translateY(26px);filter:blur(6px);
  transition:opacity .8s var(--ease),transform .8s var(--ease),filter .8s var(--ease)}
.js .rv.in{opacity:1;transform:none;filter:none}
@media(prefers-reduced-motion:reduce){.js .rv{opacity:1;transform:none;filter:none;transition:none}
  .h1 .w i{transform:none;animation:none}.hero-sub,.hero-cta,.trust{opacity:1;animation:none}
  .mq-in{animation:none}
  .rot i{animation:none;opacity:0}
  .rot i:first-child{opacity:1;transform:none}
  .chip span svg,.trust .tr-ic,.local .tr-ic{animation:none}
  .qz-bar i::before,.qz-bar i::after{animation:none;opacity:0}
  .btn-p.btn-ev::before{animation:none}}

/* ---------- services ---------- */
.svc{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.card{position:relative;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  background:var(--ink2);transition:transform .45s var(--ease),border-color .35s,box-shadow .45s}
.card:hover{transform:translateY(-6px);border-color:rgba(0,162,226,.5);
  box-shadow:0 22px 50px rgba(0,0,0,.5)}
.card-img{position:relative;aspect-ratio:16/11;overflow:hidden;background:#0d1119}
.card-img img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease);filter:saturate(1.02)}
.card:hover .card-img img{transform:scale(1.07)}
.card-img::after{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 30%,rgba(11,14,20,.9))}
.card-num{position:absolute;top:14px;left:16px;z-index:2;font-family:var(--hd);font-weight:800;
  font-size:12px;letter-spacing:.14em;color:var(--ice);background:rgba(0,162,226,.2);
  border:1px solid rgba(0,162,226,.4);border-radius:999px;padding:5px 11px}
.card-body{padding:22px 24px 26px;position:relative;z-index:2;margin-top:-46px}
.card h3{font-size:20px;margin-bottom:9px;color:#fff}
.card p{font-size:14.5px;color:var(--mut);line-height:1.6}
.card-more{display:inline-flex;align-items:center;gap:7px;margin-top:16px;font-size:13.5px;
  font-weight:600;color:var(--blue);transition:gap .3s var(--ease)}
.card:hover .card-more{gap:13px}

/* ---------- stats / why ---------- */
.why{display:grid;grid-template-columns:1.05fr .95fr;gap:60px;align-items:center}
.why-media{position:relative;border-radius:22px;overflow:hidden;border:1px solid var(--line2)}
/* height:auto is load bearing. The markup carries width/height attributes and
   that presentational hint wins over aspect-ratio, so without it the image was
   locked to a 900px tall box, "cover" zoomed miles in and sliced the left hand
   bloke clean out of the photo on a phone (Tim, 16 Aug 2026). */
.why-media img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover}
.why-media::after{content:'';position:absolute;inset:0;
  background:linear-gradient(200deg,transparent 40%,rgba(0,162,226,.18))}
.why-badge{position:absolute;left:20px;bottom:20px;z-index:3;display:flex;align-items:center;gap:13px;
  background:rgba(11,14,20,.82);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line2);border-radius:15px;padding:14px 18px}
.why-badge img{width:42px;height:auto;aspect-ratio:auto}
.why-badge b{display:block;font-family:var(--hd);font-size:14px;color:#fff}
.why-badge span{font-size:12px;color:var(--mut)}

.bars{margin:28px 0 6px;display:grid;gap:20px}
.bar b{display:flex;justify-content:space-between;font-family:var(--hd);font-size:14px;
  font-weight:700;color:#dfe4ec;margin-bottom:9px}
.bar b i{font-style:normal;color:var(--blue)}
.bar-t{height:6px;border-radius:99px;background:rgba(255,255,255,.09);overflow:hidden}
.bar-f{height:100%;width:0;border-radius:99px;
  background:linear-gradient(90deg,var(--blue),var(--ice));
  transition:width 1.5s var(--ease);box-shadow:0 0 12px rgba(0,162,226,.6)}

.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:70px}
.stat{border:1px solid var(--line);border-radius:var(--r);padding:28px 24px;background:var(--ink2);
  transition:border-color .35s,transform .4s var(--ease)}
.stat:hover{border-color:rgba(0,162,226,.45);transform:translateY(-4px)}
.stat b{display:block;font-family:var(--hd);font-weight:800;font-size:clamp(32px,4vw,46px);
  color:#fff;line-height:1;letter-spacing:-.03em;margin-bottom:8px}
.stat b i{font-style:normal;color:var(--blue)}
.stat span{font-size:13.5px;color:var(--mut)}

/* ---------- gallery ---------- */
.gal{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:200px;gap:14px}
.gi{position:relative;overflow:hidden;border-radius:14px;border:1px solid var(--line);background:#0d1119}
.gi img{width:100%;height:100%;object-fit:cover;transition:transform .85s var(--ease),filter .5s;
  filter:saturate(.92) brightness(.9)}
.gi:hover img{transform:scale(1.06);filter:saturate(1.06) brightness(1)}
.gi::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,transparent 45%,rgba(11,14,20,.86));
  opacity:0;transition:opacity .4s}
.gi:hover::after{opacity:1}
.gi span{position:absolute;left:16px;bottom:14px;z-index:2;font-family:var(--hd);font-weight:700;
  font-size:13.5px;color:#fff;opacity:0;transform:translateY(10px);transition:.45s var(--ease)}
.gi:hover span{opacity:1;transform:none}
.gi.w2{grid-column:span 2}
/* Named "tall", never "h2": .h2 is the heading class and the word cascade in
   site.js rewrites the innerHTML of everything it matches. A tile called h2
   had its <img> shredded into a word span and rendered 0x0. */
.gi.tall{grid-row:span 2}

/* ---------- reviews (moving strip, same technique as the jobs ticker) ---------- */
.revs{position:relative;overflow:hidden;
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.revs-track{display:flex;gap:20px;width:max-content;animation:revslide 70s linear infinite}
.revs:hover .revs-track{animation-play-state:paused}
@keyframes revslide{to{transform:translateX(-50%)}}
.rev{width:340px;flex:0 0 340px;border:1px solid var(--line);border-radius:var(--r);padding:30px 28px;background:var(--ink2);
  display:flex;flex-direction:column;align-items:center;text-align:center;transition:border-color .35s,transform .4s var(--ease)}
.rev:hover{border-color:rgba(0,162,226,.4);transform:translateY(-5px)}
.stars{display:flex;justify-content:center;gap:3px;color:#FFC93C;margin-bottom:16px}
.rev p{font-size:15px;color:#cfd5df;line-height:1.7;flex:1}
.rev-w{display:flex;flex-direction:column;align-items:center;gap:8px;margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
.av{width:40px;height:40px;border-radius:50%;background:linear-gradient(140deg,var(--blue),var(--navy));
  display:grid;place-items:center;font-family:var(--hd);font-weight:800;font-size:14px;color:#02131d;flex-shrink:0}
.rev-w b{display:block;font-family:var(--hd);font-size:14.5px;color:#fff}
.rev-w span{font-size:12.5px;color:var(--mut)}

/* ---------- team ---------- */
.team{display:grid;grid-template-columns:repeat(2,1fr);gap:22px;max-width:760px}
.mem{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--ink2);
  transition:border-color .35s,transform .4s var(--ease)}
.mem:hover{border-color:rgba(0,162,226,.45);transform:translateY(-5px)}
.mem-img{aspect-ratio:4/5;overflow:hidden;background:#0d1119}
.mem-img img{width:100%;height:100%;object-fit:cover;object-position:50% 22%;transition:transform .8s var(--ease)}
.mem:hover .mem-img img{transform:scale(1.05)}
.mem-b{padding:20px 22px}
.mem-b b{display:block;font-family:var(--hd);font-size:19px;color:#fff;margin-bottom:3px}
.mem-b span{font-size:13px;color:var(--blue);font-weight:600;letter-spacing:.06em;text-transform:uppercase}

/* ---------- founder ---------- */
/* Josh's only photo is a soft 640x801 crop. Keep the frame small enough that it
   is always scaled DOWN, even on a 2x screen, or it turns to mush. 300px wide
   at 4/5 is 600x750 device pixels, just inside the source. */
.founder{display:grid;grid-template-columns:300px 1fr;gap:52px;align-items:center}
.f-media{position:relative;border-radius:20px;overflow:hidden;border:1px solid var(--line2);
  background:#0d1119}
/* height:auto is load bearing. The height attribute on the img is a
   presentational hint that otherwise beats aspect-ratio and stretched the
   frame to the full 801px. */
.f-media img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;object-position:50% 18%}
.f-media::after{content:'';position:absolute;inset:0;
  background:linear-gradient(190deg,transparent 46%,rgba(0,162,226,.22))}
.f-stamp{position:absolute;left:18px;bottom:18px;z-index:3;display:flex;align-items:center;gap:11px;
  background:rgba(11,14,20,.84);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line2);border-radius:13px;padding:11px 15px}
.f-stamp img{width:34px;height:auto;aspect-ratio:auto}
.f-stamp b{display:block;font-family:var(--hd);font-size:13.5px;color:#fff;line-height:1.2}
.f-stamp span{font-size:11.5px;color:var(--mut)}

.f-quote{position:relative}
.f-mark{font-family:var(--hd);font-weight:800;font-size:92px;line-height:.7;color:var(--blue);
  opacity:.28;margin-bottom:6px;display:block}
.f-quote blockquote{margin:0;font-family:var(--hd);font-weight:600;letter-spacing:-.015em;
  font-size:clamp(19px,2.25vw,27px);line-height:1.42;color:#fff}
.f-quote blockquote span{color:var(--blue)}
.f-sign{display:flex;align-items:center;gap:16px;margin-top:28px;padding-top:24px;
  border-top:1px solid var(--line)}
.f-sign .nm{font-family:var(--hd);font-weight:800;font-size:19px;color:#fff;line-height:1.2}
.f-sign .rl{font-size:13px;color:var(--blue);font-weight:600;letter-spacing:.08em;text-transform:uppercase}
.f-creds{display:flex;flex-wrap:wrap;gap:10px;margin-top:26px}
.f-creds span{display:inline-flex;align-items:center;gap:8px;font-size:13px;color:#c3cad6;
  border:1px solid var(--line2);border-radius:999px;padding:8px 15px;background:rgba(255,255,255,.03)}
.f-creds svg{color:var(--blue);flex-shrink:0}

/* ---------- coverage ---------- */
.cov{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.cv{position:relative;border-radius:var(--r);overflow:hidden;border:1px solid var(--line);
  aspect-ratio:4/3;transition:transform .45s var(--ease),border-color .35s}
.cv:hover{transform:translateY(-6px);border-color:rgba(0,162,226,.5)}
.cv img{width:100%;height:100%;object-fit:cover;transition:transform .9s var(--ease);filter:saturate(.8) brightness(.58)}
.cv:hover img{transform:scale(1.07)}
.cv-b{position:absolute;inset:auto 0 0;padding:26px 24px 24px;z-index:2;
  background:linear-gradient(180deg,rgba(11,14,20,0) 0%,rgba(11,14,20,.72) 34%,rgba(11,14,20,.96) 100%)}
.cv-b b{display:block;font-family:var(--hd);font-size:20px;color:#fff;margin-bottom:6px;
  text-shadow:0 1px 12px rgba(0,0,0,.6)}
.cv-b span{font-size:13.5px;color:#d6dce5;text-shadow:0 1px 10px rgba(0,0,0,.7)}

/* ---------- CTA band ---------- */
/* the gradient itself drifts, so the CTA is quietly alive rather than a flat
   slab (Tim, 16 Aug 2026). Oversized background-size gives the shift room. */
.band{position:relative;overflow:hidden;border-radius:26px;padding:60px 56px;
  background:linear-gradient(125deg,var(--navy) 0%,#12224e 26%,#0a3a63 50%,#132048 74%,#071528 100%);
  background-size:280% 280%;
  animation:bandshift 17s ease-in-out infinite;
  border:1px solid rgba(0,162,226,.3)}
@keyframes bandshift{0%,100%{background-position:0% 50%}50%{background-position:100% 50%}}
.band::before{content:'';position:absolute;right:-8%;top:-40%;width:520px;height:520px;border-radius:50%;
  background:radial-gradient(circle,rgba(0,162,226,.38),transparent 66%)}
.band-in{position:relative;z-index:2;display:flex;align-items:center;gap:40px;justify-content:space-between;flex-wrap:wrap}
.band h3{font-size:clamp(26px,3.4vw,38px);color:#fff;max-width:20ch;margin-bottom:10px}
.band p{color:#bcc8dd;font-size:16px;max-width:46ch}
.band-cta{display:flex;gap:13px;flex-wrap:wrap}

/* ---------- contact ---------- */
.cont{display:grid;grid-template-columns:.9fr 1.1fr;gap:56px;align-items:start}
.cinfo{display:grid;gap:14px;margin-top:30px}
.ci{display:flex;gap:15px;align-items:flex-start;border:1px solid var(--line);border-radius:14px;
  padding:18px 20px;background:var(--ink2);transition:border-color .3s}
.ci:hover{border-color:rgba(0,162,226,.45)}
.ci .ic{width:40px;height:40px;border-radius:11px;flex-shrink:0;display:grid;place-items:center;
  background:rgba(0,162,226,.14);color:var(--blue);border:1px solid rgba(0,162,226,.3)}
.ci b{display:block;font-family:var(--hd);font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--mut);margin-bottom:4px;font-weight:700}
.ci span{font-size:16px;color:#fff;font-weight:500;word-break:break-word}

.form{border:1px solid var(--line);border-radius:22px;padding:34px;background:var(--ink2)}
.frow{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.f{margin-bottom:16px}
.f label{display:block;font-family:var(--hd);font-size:12.5px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mut);margin-bottom:8px}
.f input,.f select,.f textarea{width:100%;background:#0c1017;border:1px solid var(--line2);
  border-radius:12px;padding:14px 16px;color:#fff;font-family:var(--bd);font-size:15px;
  transition:border-color .25s,box-shadow .25s;-webkit-appearance:none;appearance:none}
.f select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%23939AA8' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center;background-size:12px;padding-right:42px}
.f textarea{resize:vertical;min-height:112px}
.f input:focus,.f select:focus,.f textarea:focus{outline:none;border-color:var(--blue);
  box-shadow:0 0 0 3px rgba(0,162,226,.16)}
.f input::placeholder,.f textarea::placeholder{color:#5c6572}
.consent{display:flex;gap:11px;align-items:flex-start;font-size:13px;color:var(--mut);margin:6px 0 20px;line-height:1.55}
.consent input{width:19px;height:19px;flex-shrink:0;margin-top:2px;accent-color:var(--blue)}
.form .btn-p{width:100%}
.fnote{font-size:12px;color:#6b7484;margin-top:14px;text-align:center}
.fok{display:none;text-align:center;padding:36px 10px}
.fok.on{display:block}
.fok .tick{width:62px;height:62px;border-radius:50%;background:rgba(0,162,226,.16);
  border:1px solid rgba(0,162,226,.45);display:grid;place-items:center;margin:0 auto 18px;color:var(--blue)}
.fok h3,.fok h4{font-family:var(--hd);font-size:22px;color:#fff;margin-bottom:8px}
.fok p{color:var(--mut);font-size:14.5px}

/* ---------- footer ---------- */
.ft{border-top:1px solid var(--line);background:#080B10;padding:64px 0 34px;margin-top:20px}
.ft-top{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:40px;margin-bottom:46px}
.ft-brand img{height:44px;width:auto;max-width:100%;object-fit:contain;margin-bottom:18px}
/* A fixed height with no width lets max-width:100% squash the wordmark out of
   proportion on any container narrower than its intrinsic 900px, which is what
   distorted it in the footer on mobile. Only the two images sized by HEIGHT need
   width:auto. .why-badge img and .f-stamp img are sized by WIDTH with height:auto
   and must NOT be caught by this, or they render at full natural size. */
.brand img{width:auto;object-fit:contain}
.ft-brand p{font-size:14.5px;color:var(--mut);max-width:34ch}
.ft h2,.ft h5{font-family:var(--hd);font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;
  color:#fff;margin:0 0 16px;font-weight:700}
.ft ul{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.ft ul a,.ft ul li{font-size:14.5px;color:var(--mut);transition:color .25s}
.ft ul a:hover{color:var(--blue)}
.ft-bot{border-top:1px solid var(--line);padding-top:24px;display:flex;justify-content:space-between;
  align-items:center;gap:20px;flex-wrap:wrap;font-size:13px;color:#606a79}
.scalus-badge{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:#7d8797;
  border:1px solid var(--line);border-radius:999px;padding:7px 15px;transition:.25s}
.scalus-badge b{color:var(--ice);font-weight:600}
.scalus-badge:hover{border-color:rgba(0,162,226,.5);color:#cfd6e0}

/* ---------- mobile sticky call bar ---------- */
.mbar{display:none}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media(max-width:1180px){
  .hero-in{grid-template-columns:minmax(0,1fr) 400px;gap:38px}
}
@media(max-width:1080px){
  /* card drops below the copy and centres, so nothing gets squeezed */
  .hero-in{grid-template-columns:1fr;gap:40px;justify-items:stretch}
  .qz{max-width:560px;width:100%}
  .h1{max-width:20ch}
  .founder{grid-template-columns:1fr;gap:34px}
  /* stacked, the portrait centres rather than hugging the left rail (Tim, 16 Aug 2026) */
  .f-media{max-width:280px;margin-left:auto;margin-right:auto}
  .svc{grid-template-columns:repeat(2,1fr)}
  .why{grid-template-columns:1fr;gap:40px}
  .cont{grid-template-columns:1fr;gap:38px}
  .ft-top{grid-template-columns:1fr 1fr;gap:34px}
  .gal{grid-template-columns:repeat(2,1fr);grid-auto-rows:180px}
}
@media(max-width:900px){
  .nav{display:none}
  .tel span{display:none}
  .tel{padding:11px}
  .burger{display:block}
  .hd-cta .btn{display:none}
  .cov{grid-template-columns:1fr}
  .stats{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:640px){
  .wrap{padding:0 18px}
  section{scroll-margin-top:70px}
  .hd-in{height:64px}
  .brand img{height:32px}
  /* top padding opens the strip the hero photo's face sits in — see the
     max-width:700px hero block above */
  .hero{min-height:auto;padding:175px 0 44px}
  /* sized so each of the three uppercase lines holds on one line on a phone */
  .h1{font-size:clamp(20px,7.8vw,34px);max-width:100%;margin-bottom:16px}
  .hero-sub{font-size:15.5px;margin-bottom:10px}
  .hero-sub2{margin-bottom:26px}
  .rot i{font-size:1.42em}
  .hero-cta{gap:10px}
  .hero-cta .btn{width:100%;padding:16px 22px}
  .hero-in{gap:30px;margin-bottom:32px}
  .qz{padding:22px 18px 20px;border-radius:18px}
  .qz-h{flex-direction:column;align-items:flex-start;gap:4px}
  .qz-h h2,.qz-h h3{font-size:19px}
  .chips{grid-template-columns:1fr;gap:9px}
  .chip span{min-height:58px;font-size:14.5px}
  .qrow{grid-template-columns:1fr;gap:0}
  .qnav{flex-direction:column-reverse;gap:9px}
  .qnav .btn,.qnav .back{width:100%}
  .trust{grid-template-columns:1fr 1fr}
  .trust div{padding:14px 15px}
  .trust b{font-size:13.5px}
  .trust span{font-size:11.5px}
  .sec{padding:64px 0}
  .sec-tight{padding:52px 0}
  #recent-jobs{padding-bottom:28px}
  #recent-jobs+.sec{padding-top:28px}
  .shead{margin-bottom:34px}
  .h2{font-size:clamp(26px,7.4vw,34px)}
  .lead{font-size:15.5px}
  .svc{grid-template-columns:1fr;gap:16px}
  /* the team photo runs at its native 3:2 on a phone — shorter and wider, and
     not a pixel of either bloke gets trimmed off the sides */
  .why-media img{aspect-ratio:3/2}
  .card-body{padding:20px 20px 24px}
  /* gallery becomes clean 2 up cards with the caption BELOW the photo,
     so nothing overlaps and every label stays readable on a phone */
  .gal{grid-template-columns:1fr 1fr;grid-auto-rows:auto;gap:12px}
  .gi{display:flex;flex-direction:column;background:var(--ink2)}
  .gi.w2,.gi.tall{grid-column:auto;grid-row:auto}
  .gi img{aspect-ratio:4/3;height:auto;filter:none}
  .gi::after{display:none}
  .gi span{position:static;opacity:1;transform:none;padding:10px 12px 13px;
    font-size:12px;line-height:1.4;color:#cbd2dd;font-weight:600}
  .cv-b{padding:22px 20px 20px}
  .cv-b b{font-size:18px}
  .cv-b span{font-size:13px}
  .stats{gap:12px;margin-top:44px}
  .stat{padding:20px 16px}
  .stat b{font-size:30px}
  .stat span{font-size:12px}
  .founder{gap:26px}
  .f-mark{font-size:64px}
  .f-quote blockquote{font-size:18.5px;line-height:1.5}
  .f-sign{gap:13px;margin-top:22px;padding-top:20px}
  .f-sign .nm{font-size:17px}
  .f-creds{gap:8px;margin-top:20px}
  .f-creds span{font-size:12.5px;padding:7px 13px}
  .team{grid-template-columns:1fr 1fr;gap:14px}
  .mem-b{padding:15px 14px}
  .mem-b b{font-size:16px}
  .mem-b span{font-size:11px}
  .band{padding:38px 24px;border-radius:20px}
  .band-in{gap:26px}
  .band h3{font-size:26px}
  .band p{font-size:15px}
  .band-cta{width:100%;flex-direction:column}
  .band-cta .btn{width:100%}
  .form{padding:24px 20px;border-radius:18px}
  .frow{grid-template-columns:1fr;gap:0}
  .ft{padding:48px 0 96px}
  .ft-top{grid-template-columns:1fr;gap:30px;margin-bottom:32px}
  .ft-bot{flex-direction:column;align-items:flex-start;gap:14px}
  .mq-in span{font-size:13px;gap:16px;padding:0 16px}

  /* sticky call bar */
  .mbar{display:grid;grid-template-columns:1fr 1fr;gap:10px;position:fixed;
    left:0;right:0;bottom:0;z-index:110;padding:10px 14px calc(10px + env(safe-area-inset-bottom));
    background:rgba(9,12,17,.94);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    border-top:1px solid var(--line2)}
  .mbar .btn{width:100%;padding:15px 12px;font-size:15px}
}

/* ==========================================================================
   INNER PAGES — added when the single concept page was fanned out into the
   full multi page site. Reuses every token above, adds only new furniture.
   ========================================================================== */

/* ---------- page hero (every page except home) ---------- */
.phero{position:relative;overflow:hidden;padding:56px 0 60px;border-bottom:1px solid var(--line);
  background:var(--ink2)}
.phero-bg{position:absolute;inset:0;z-index:0}
.phero-bg img{width:100%;height:100%;object-fit:cover;filter:saturate(.85) brightness(.42)}
.phero::after{content:'';position:absolute;inset:0;z-index:1;
  background:
    linear-gradient(180deg,rgba(11,14,20,.78) 0%,rgba(11,14,20,.62) 40%,rgba(11,14,20,.94) 100%),
    radial-gradient(80% 80% at 8% 90%,rgba(0,162,226,.22),transparent 62%)}
.phero .wrap{position:relative;z-index:2}
.phero h1{font-family:var(--hd);font-weight:800;font-size:clamp(30px,5vw,54px);
  line-height:1.04;letter-spacing:-.028em;color:#fff;margin:0 0 16px;max-width:20ch}
.phero h1 em{font-style:normal;color:var(--blue)}
.phero .lead{max-width:60ch;font-size:17px}
.phero-cta{display:flex;flex-wrap:wrap;gap:13px;margin-top:30px}

/* ---------- breadcrumbs ---------- */
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:20px;
  font-size:13px;color:var(--mut)}
.crumbs a{color:var(--mut);transition:color .2s}
.crumbs a:hover{color:var(--blue)}
.crumbs span[aria-current]{color:#cfd6e0}
.crumbs i{font-style:normal;color:#4e5766}

/* ---------- prose ---------- */
.prose{max-width:74ch}
.prose p{color:#c2c9d4;font-size:16.5px;line-height:1.78;margin-bottom:18px}
.prose h2{font-size:clamp(24px,3.2vw,34px);margin:44px 0 16px;color:#fff}
.prose h2:first-child{margin-top:0}
.prose h3{font-family:var(--hd);font-size:20px;color:#fff;margin:32px 0 12px}
.prose strong{color:#fff;font-weight:600}
.prose a{color:var(--blue);text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px;text-decoration-color:rgba(0,162,226,.45)}
.prose a:hover{text-decoration-color:var(--blue)}
.prose ul{list-style:none;margin:0 0 22px;padding:0;display:grid;gap:11px}
.prose ul li{position:relative;padding-left:30px;color:#c2c9d4;font-size:16px;line-height:1.65}
.prose ul li::before{content:'';position:absolute;left:0;top:9px;width:9px;height:9px;border-radius:3px;
  background:var(--blue);box-shadow:0 0 10px rgba(0,162,226,.65)}

/* two column: prose on the left, sticky enquiry rail on the right */
.pcols{display:grid;grid-template-columns:minmax(0,1fr) 380px;gap:56px;align-items:start}
.rail{position:sticky;top:96px;display:grid;gap:16px}
.rail-card{border:1px solid var(--line2);border-radius:20px;padding:26px 24px;background:var(--ink2)}
.rail-card h2,.rail-card h3{font-size:20px;color:#fff;margin-bottom:8px}
.rail-card p{font-size:14.5px;color:var(--mut);margin-bottom:18px;line-height:1.6}
.rail-card .btn{width:100%;margin-bottom:10px}
.rail-card .btn:last-child{margin-bottom:0}
.rail-list{display:grid;gap:2px}
.rail-list a{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:13px 2px;border-bottom:1px solid var(--line);font-size:14.5px;color:#c2c9d4;transition:.22s}
.rail-list a:last-child{border-bottom:0}
.rail-list a:hover{color:var(--blue);padding-left:6px}
.rail-list a svg{color:var(--blue);flex-shrink:0;opacity:.6}

/* ---------- checklist blocks ---------- */
.checks{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:26px 0 4px}
.check{display:flex;gap:13px;align-items:flex-start;border:1px solid var(--line);border-radius:14px;
  padding:17px 18px;background:var(--ink2);transition:border-color .3s}
.check:hover{border-color:rgba(0,162,226,.42)}
.check .tk{width:26px;height:26px;border-radius:8px;flex-shrink:0;display:grid;place-items:center;
  background:rgba(0,162,226,.15);border:1px solid rgba(0,162,226,.35);color:var(--blue)}
.check b{display:block;font-family:var(--hd);font-size:15px;color:#fff;margin-bottom:3px}
.check span{font-size:13.5px;color:var(--mut);line-height:1.55}

/* ---------- link tiles (services index, areas index) ---------- */
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.tile{position:relative;border:1px solid var(--line);border-radius:var(--r);padding:26px 24px;
  background:var(--ink2);display:flex;flex-direction:column;
  transition:transform .4s var(--ease),border-color .3s,box-shadow .4s}
.tile:hover{transform:translateY(-5px);border-color:rgba(0,162,226,.5);box-shadow:0 18px 44px rgba(0,0,0,.45)}
.tile b{display:block;font-family:var(--hd);font-weight:800;font-size:19px;color:#fff;margin-bottom:8px}
.tile p{font-size:14px;color:var(--mut);line-height:1.6;flex:1}
.tile .go{display:inline-flex;align-items:center;gap:7px;margin-top:16px;font-size:13.5px;
  font-weight:600;color:var(--blue);transition:gap .3s var(--ease)}
.tile:hover .go{gap:13px}
.tile-ic{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;margin-bottom:16px;
  background:rgba(0,162,226,.13);border:1px solid rgba(0,162,226,.32);color:var(--blue)}

/* compact suburb chips */
.chips-link{display:flex;flex-wrap:wrap;gap:10px}
.chips-link a{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line2);
  border-radius:999px;padding:10px 17px;font-size:14px;color:#c8ced9;background:rgba(255,255,255,.03);
  transition:.25s}
.chips-link a:hover{border-color:var(--blue);background:rgba(0,162,226,.12);color:#fff}
.chips-link a svg{color:var(--blue);opacity:.75}

/* On a phone fourteen pills wrap into a whole screenful of list, so they rotate
   past instead (Tim, 16 Aug 2026). site.js clones the row once and the track
   travels exactly one set, which is why the gap lives on the pill as a margin
   rather than on the flex container — a container gap would leave a 10px jump
   at the loop point. Every link stays in the DOM either way. */
.chips-rot{overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent)}
.chips-rot .chips-link{flex-wrap:nowrap;width:max-content;gap:0;
  animation:chipsroll 42s linear infinite}
.chips-rot .chips-link a{flex:0 0 auto;margin-right:10px}
.chips-rot:hover .chips-link,.chips-rot:focus-within .chips-link{animation-play-state:paused}
@keyframes chipsroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ---------- FAQ accordion ---------- */
.faqs{display:grid;gap:12px;max-width:900px}
/* Homepage FAQ teaser only (the dedicated /faq page sits beside a rail and
   does not need this) — the list caps at 900px, so on wide screens it sat
   flush left in the 1240px wrap with a dead gap to its right. Center the
   whole heading+list+button cluster as a unit instead. */
.faq-teaser{display:flex;flex-direction:column;align-items:center;text-align:center}
.faq-teaser .faqs{margin:0 auto}
.faq{border:1px solid var(--line);border-radius:14px;background:var(--ink2);overflow:hidden;
  transition:border-color .3s}
.faq[open]{border-color:rgba(0,162,226,.42)}
.faq summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;
  gap:18px;padding:20px 22px;font-family:var(--hd);font-weight:700;font-size:16.5px;color:#fff}
.faq summary::-webkit-details-marker{display:none}
.faq summary .pm{width:26px;height:26px;flex-shrink:0;border-radius:8px;display:grid;place-items:center;
  background:rgba(0,162,226,.14);border:1px solid rgba(0,162,226,.34);color:var(--blue);
  transition:transform .3s var(--ease)}
.faq[open] summary .pm{transform:rotate(45deg)}
.faq .fa{padding:0 22px 22px;color:#b8c0cc;font-size:15.5px;line-height:1.75}
.faq .fa p+p{margin-top:14px}

/* ---------- local proof strip ---------- */
.local{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:34px}
.local div{border:1px solid var(--line);border-radius:14px;padding:20px;background:rgba(255,255,255,.02);
  display:flex;align-items:flex-start;gap:12px}
.local .tr-ic{display:flex;align-items:center;justify-content:center;flex-shrink:0;
  width:36px;height:36px;border-radius:11px;color:var(--blue);
  border:1px solid rgba(0,162,226,.32);background:rgba(0,162,226,.10);
  animation:icpulse 6s var(--ease) infinite;animation-delay:calc(var(--g,0) * .5s)}
.local .tr-t{min-width:0}
.local b{display:block;font-family:var(--hd);font-size:15px;color:#fff;line-height:1.35;
  margin-bottom:3px;padding-bottom:1px}
.local span{font-size:13px;color:var(--mut);line-height:1.55;display:block}

/* ---------- next/prev suburb nav ---------- */
.nearby{border-top:1px solid var(--line);margin-top:56px;padding-top:34px}
.nearby h3,.nearby h4{font-family:var(--hd);font-size:13px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--mut);margin:0 0 16px;font-weight:700}

/* ---------- gallery page filter row ---------- */
.filters{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:32px}
.filters button{border:1px solid var(--line2);background:rgba(255,255,255,.03);color:#c8ced9;
  border-radius:999px;padding:10px 18px;font-size:14px;cursor:pointer;transition:.25s;font-family:var(--bd)}
.filters button:hover{border-color:rgba(0,162,226,.55);color:#fff}
.filters button.on{background:var(--blue);border-color:var(--blue);color:#04121c;font-weight:600}
.gi.hide{display:none}

/* ---------- responsive for the new furniture ---------- */
@media(max-width:1080px){
  .pcols{grid-template-columns:1fr;gap:44px}
  .rail{position:static}
  .tiles{grid-template-columns:repeat(2,1fr)}
  .local{grid-template-columns:1fr 1fr}
}
@media(max-width:640px){
  .phero{padding:38px 0 42px}
  .phero h1{font-size:clamp(26px,7.6vw,34px);max-width:100%}
  .phero .lead{font-size:15.5px}
  .phero-cta{gap:10px}
  .phero-cta .btn{width:100%}
  .crumbs{font-size:12px;gap:6px}
  .prose p{font-size:15.5px}
  .prose ul li{font-size:15px}
  .checks{grid-template-columns:1fr}
  .tiles{grid-template-columns:1fr}
  .rail-card{padding:22px 20px}
  .faq summary{font-size:15.5px;padding:17px 18px;gap:12px}
  .faq .fa{padding:0 18px 19px;font-size:14.8px}
  .local{grid-template-columns:1fr}
  .filters{gap:8px}
  .filters button{padding:9px 14px;font-size:13px}
}

/* ==========================================================================
   RECENT JOBS TICKER
   Live from ServiceM8. The section removes itself when the feed is empty, so
   an unwired or down API shows nothing rather than an empty shell.
   ========================================================================== */
.jobs{position:relative;overflow:hidden;
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent)}
.jobs-track{display:flex;gap:16px;width:max-content;animation:jobslide 64s linear infinite}
.jobs:hover .jobs-track{animation-play-state:paused}
@keyframes jobslide{to{transform:translateX(-50%)}}
.job{width:290px;flex:0 0 290px;border:1px solid var(--line);border-radius:16px;
  background:var(--ink2);overflow:hidden;transition:border-color .3s,transform .4s var(--ease)}
.job:hover{border-color:rgba(0,162,226,.5);transform:translateY(-4px)}
.job-img{aspect-ratio:4/3;background:#0d1119;position:relative;overflow:hidden}
/* The bolt sits behind every tile so a photo that has not decoded yet reads
   as a deliberate placeholder rather than the browser's broken image icon. */
.job-ph{position:absolute;inset:0;display:grid;place-items:center;
  color:rgba(0,162,226,.28)}
.job-img img{position:relative;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .45s var(--ease),transform .8s var(--ease)}
.job-img img.on{opacity:1}
.job:hover .job-img img{transform:scale(1.06)}
.job-img.none{display:grid;place-items:center;color:rgba(0,162,226,.4)}
.job-b{padding:16px 18px 18px}
.job-b b{display:block;font-family:var(--hd);font-size:15.5px;color:#fff;margin-bottom:7px;
  line-height:1.25}
.job-meta{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--mut);flex-wrap:wrap}
.job-meta .pin{display:inline-flex;align-items:center;gap:5px;color:var(--blue);font-weight:600}
.job-meta .dot{width:3px;height:3px;border-radius:50%;background:#4c5563}
.jobs-live{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;color:var(--mut);
  margin-top:22px}
.jobs-live i{width:8px;height:8px;border-radius:50%;background:#38d39f;
  box-shadow:0 0 0 0 rgba(56,211,159,.65);animation:pulse 2.4s infinite}
@keyframes pulse{70%{box-shadow:0 0 0 9px rgba(56,211,159,0)}100%{box-shadow:0 0 0 0 rgba(56,211,159,0)}}

/* ==========================================================================
   MOTION LAYER
   Everything here is additive and every piece is switched off by
   prefers-reduced-motion at the bottom of this block.
   ========================================================================== */

/* directional + scale reveals, same observer as .rv */
.js .rv-l{opacity:0;transform:translateX(-38px);transition:opacity .85s var(--ease),transform .85s var(--ease)}
.js .rv-r{opacity:0;transform:translateX(38px);transition:opacity .85s var(--ease),transform .85s var(--ease)}
.js .rv-s{opacity:0;transform:scale(.94);transition:opacity .8s var(--ease),transform .8s var(--ease)}
.js .rv-l.in,.js .rv-r.in,.js .rv-s.in{opacity:1;transform:none}

/* heading word cascade, same mechanism as the hero h1 */
.h2 .w{display:inline-block;overflow:hidden;vertical-align:bottom}
.h2 .w i{display:inline-block;font-style:normal;transform:translateY(110%);
  transition:transform .78s var(--ease);transition-delay:calc(var(--i)*.045s)}
.h2.in .w i,.in .h2 .w i{transform:translateY(0)}

/* hero CTA: a charge runs around the outline, the way the ring on an EV charger
   travels while it is delivering. the shine sweep is dropped on this one so the
   two effects do not fight. */
@property --evq{syntax:'<angle>';initial-value:0deg;inherits:false}
.btn-p.btn-ev{position:relative;overflow:visible;isolation:isolate}
.btn-p.btn-ev::after{display:none}
.btn-p.btn-ev::before{content:'';position:absolute;inset:-2px;border-radius:999px;padding:2px;
  background:conic-gradient(from var(--evq),
    rgba(207,249,254,0) 0deg,rgba(207,249,254,0) 226deg,
    rgba(207,249,254,.22) 284deg,rgba(207,249,254,.8) 332deg,
    #ffffff 350deg,rgba(207,249,254,.8) 356deg,rgba(207,249,254,0) 360deg);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
  filter:drop-shadow(0 0 6px rgba(0,162,226,.85));
  animation:evrun 2.8s linear infinite;pointer-events:none;z-index:2}
@keyframes evrun{to{--evq:360deg}}

/* primary button shine sweep */
.btn-p{position:relative;overflow:hidden}
.btn-p::after{content:'';position:absolute;top:0;bottom:0;left:-70%;width:45%;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.42),transparent);
  transform:skewX(-18deg);opacity:0;pointer-events:none}
.btn-p:hover::after{animation:shine .78s var(--ease) forwards}
@keyframes shine{from{left:-70%;opacity:1}to{left:120%;opacity:1}}

/* tick items pop in with a stagger once their block reveals */
.js .check{opacity:0;transform:translateY(16px) scale(.97);
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.js .checks.in .check,.js .in .check{opacity:1;transform:none}
.js .checks.in .check:nth-child(1),.js .in .check:nth-child(1){transition-delay:.05s}
.js .checks.in .check:nth-child(2),.js .in .check:nth-child(2){transition-delay:.14s}
.js .checks.in .check:nth-child(3),.js .in .check:nth-child(3){transition-delay:.23s}
.js .checks.in .check:nth-child(4),.js .in .check:nth-child(4){transition-delay:.32s}
.js .checks.in .check:nth-child(5),.js .in .check:nth-child(5){transition-delay:.41s}
.js .checks.in .check:nth-child(6),.js .in .check:nth-child(6){transition-delay:.5s}
.check .tk{transition:transform .45s var(--ease),background .3s}
.check:hover .tk{transform:rotate(-8deg) scale(1.12);background:rgba(0,162,226,.28)}

/* the kicker rule that used to draw itself in is gone, see .klabel above */

/* CTA band gets a slow moving glow */
.band::before{animation:drift 14s ease-in-out infinite alternate}
@keyframes drift{from{transform:translate(0,0) scale(1)}to{transform:translate(-70px,40px) scale(1.16)}}

/* hero grid drifts very slightly so the hero is never completely static */
.hero-grid{animation:gridDrift 30s linear infinite}
@keyframes gridDrift{to{background-position:74px 74px}}

/* suburb chips stagger in */
.js .chips-link a{opacity:0;transform:translateY(12px);
  transition:opacity .5s var(--ease),transform .5s var(--ease),border-color .25s,background .25s,color .25s}
.js .in .chips-link a,.js .chips-link.in a{opacity:1;transform:none}
.js .in .chips-link a:nth-child(n+1){transition-delay:calc((var(--n,0)) * .035s)}

/* service and link tiles lift their icon on hover */
.tile-ic{transition:transform .45s var(--ease),background .3s,border-color .3s}
.tile:hover .tile-ic{transform:translateY(-4px) rotate(-6deg);background:rgba(0,162,226,.22)}

/* stat cards breathe on hover */
.stat b{transition:transform .4s var(--ease)}
.stat:hover b{transform:translateY(-3px)}

/* gallery figures drift up slightly as they enter */
.js .gi{transition:transform .5s var(--ease),border-color .3s}

@media(prefers-reduced-motion:reduce){
  .js .rv-l,.js .rv-r,.js .rv-s{opacity:1;transform:none;transition:none}
  .h2 .w i{transform:none;transition:none}
  .btn-p::after{display:none}
  .js .check{opacity:1;transform:none;transition:none}
  .band,.band::before,.hero-grid{animation:none}
  .chips-rot .chips-link{animation:none}
  .jobs-track{animation:none;width:auto;flex-wrap:wrap}
  .js .chips-link a{opacity:1;transform:none;transition:none}
  .jobs-live i{animation:none}
  .revs-track{animation:none;width:auto;flex-wrap:wrap}
  .revs-track .rev[aria-hidden="true"]{display:none}
}

@media(max-width:640px){
  .job{width:238px;flex-basis:238px}
  .job-b{padding:13px 15px 15px}
  .job-b b{font-size:14.5px}
  .jobs-track{gap:12px}
  .rev{width:270px;flex-basis:270px;padding:24px 20px}
  .revs-track{gap:14px}
}
