/* Preview engine base CSS. Mobile first, single classes, colours and fonts only through :root tokens.
   Adapted from the approved Ask 4 Harry home, service and suburb designs, with the lawn-only parts removed.
   Per-client tokens are written into a second :root block by the build (from client.json "theme"). */
:root{
  --dark:#24292a;--dark-2:#2f3536;--dark-3:#1b1f20;--accent:#8DC63F;--accent-ink:#006838;
  --ink:#172019;--muted:#56615a;--paper:#fff;--mist:#f3f1ec;--line:#e0dcd3;--star:#f2b318;--on-dark:#d4d6d2;
  --head:Arial,sans-serif;--body:Arial,sans-serif;
  --s1:.25rem;--s2:.5rem;--s3:.75rem;--s4:1rem;--s5:1.5rem;--s6:2rem;--s7:3rem;--s8:4rem;
  --sec:3.5rem;--gut:max(1rem,env(safe-area-inset-left,0px));--r:.875rem;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scroll-padding-bottom:calc(5rem + env(safe-area-inset-bottom,0px))}
body{font:1.0625rem/1.55 var(--body);color:var(--ink);background:var(--paper);-webkit-font-smoothing:antialiased}
img{display:block;max-width:100%;height:auto}
/* crop point from photo.focus, with photo.focus_phone on phones */
img[style*="--pos"]{object-position:var(--pos)}
@media (max-width:879px){img[style*="--pos"]{object-position:var(--pos-m,var(--pos))}}
svg{display:block}
a{color:inherit}
button,input,select,textarea{font:inherit;color:inherit}
ul,ol{list-style:none}
.in{max-width:72.5rem;margin:0 auto;padding-inline:var(--gut)}
h1,h2,h3{font-family:var(--head);letter-spacing:-.02em;text-wrap:balance}
/* card and list titles are bold spans, not headings: balance them too so none ends on one word ("...to prove / it") */
.why b,.steps b,.jcard b,.rv .job,.faq summary,.tile span,.ilist b,.tour-t{text-wrap:balance}
/* body copy: no one-word last lines ("insured." alone). Browsers without it just wrap as before */
p,blockquote,li{text-wrap:pretty}
::selection{background:var(--accent);color:var(--dark)}
:focus-visible{outline:3px solid var(--dark);outline-offset:2px;box-shadow:0 0 0 7px var(--accent);border-radius:4px}
svg.g{width:1.125rem;height:1.125rem;flex:none}
.tlink{display:inline-flex;align-items:center;gap:var(--s2);min-height:2.75rem;font-weight:700;color:var(--accent-ink)}
.dark .tlink{color:var(--accent)}

/* guided tour for the prospect (site.js): a card plus a spotlight ring that dims the rest of the page */
.tour{position:fixed;left:.75rem;right:.75rem;bottom:calc(.75rem + env(safe-area-inset-bottom,0px));z-index:80;background:#fff;color:var(--ink);border-radius:1rem;padding:1.125rem 1.25rem 1rem;box-shadow:0 18px 50px rgba(0,0,0,.4);transform:translateY(1.5rem);opacity:0;transition:transform .3s ease,opacity .3s ease}
.tour.show{transform:none;opacity:1}
.tour-n{font:700 .8125rem var(--body);letter-spacing:.08em;text-transform:uppercase;color:var(--accent-ink);min-height:1em}
.tour-t{font:800 1.375rem/1.1 var(--head);color:var(--dark);margin-top:var(--s1);padding-right:2rem}
.tour-b p{line-height:1.45;margin-top:var(--s2);max-width:42ch}
.tour-b .tour-sig{font:italic 700 1.0625rem var(--head);color:var(--ink)}
.tour-nav{display:grid;grid-template-columns:auto 1fr;gap:var(--s2);margin-top:var(--s4)}
.tour-nav .b-ghost{width:auto;padding:0 var(--s4);color:var(--ink);box-shadow:inset 0 0 0 2px var(--line)}
.tour-x{position:absolute;top:.375rem;right:.375rem;width:2.75rem;height:2.75rem;border:0;background:none;font-size:1.75rem;line-height:1;color:var(--muted);cursor:pointer}
.tour-ring{position:fixed;z-index:75;pointer-events:none;border-radius:.75rem;box-shadow:0 0 0 3px var(--accent),0 0 0 9999px rgba(0,0,0,.55);transition:width .25s ease,height .25s ease}
.touring .bar{display:none}
.tour.first .tour-x,.tour.first [data-tour="back"]{display:none}
.tour.first .tour-nav{grid-template-columns:1fr}
.tour{max-height:calc(100dvh - 1.5rem);overflow:auto}
.tour-text{margin-top:var(--s4)}
.tour.last:has(.tour-text) [data-tour="next"]{background:none;color:var(--ink);box-shadow:inset 0 0 0 2px var(--line)}
.tour-num{font-size:.9375rem;color:var(--muted);text-align:center;margin-top:var(--s2)!important;max-width:none!important}
.tour.last.hello .tour-nav{grid-template-columns:auto 1fr}
.tour-again{position:fixed;z-index:29;left:max(.75rem,env(safe-area-inset-left,0px));bottom:calc(4.75rem + env(safe-area-inset-bottom,0px));min-height:2.75rem;padding:0 1rem;border:0;border-radius:99px;background:#fff;color:var(--dark);font:800 .9375rem var(--head);box-shadow:0 6px 20px rgba(0,0,0,.28);cursor:pointer}
.tour.hello{box-shadow:0 18px 50px rgba(0,0,0,.4),0 0 0 9999px rgba(0,0,0,.45)}

/* buttons: Call is always the primary */
.btn{display:flex;align-items:center;justify-content:center;gap:var(--s2);min-height:3.25rem;padding:0 1rem;font:800 1.0625rem/1.1 var(--head);text-decoration:none;text-align:center;border-radius:var(--btn-r,.625rem);border:0;cursor:pointer;width:100%}
.btn svg{width:1.125rem;height:1.125rem;flex:none}
.b-acc{background:var(--accent);color:var(--dark)}
/* Secondary buttons are filled, not outline-only (Evan, 10 Nov 2026, D3): weak-looking buttons took people 22% longer
   to find (NN/g eye-tracking; principles CD-09). A quieter fill than Call keeps Call first. */
.b-ghost{background:rgba(255,255,255,.14);box-shadow:inset 0 0 0 2px rgba(255,255,255,.45);color:#fff}
/* secondary button for light sections: a light tint of the dark colour plus its edge */
.b-line{background:color-mix(in srgb,var(--dark) 9%,#fff);box-shadow:inset 0 0 0 2px var(--dark);color:var(--dark)}
/* hover text a shade darker than accent-ink: accent-ink is set to pass on white, and this button's 9% tint took
   Hemmens' teal to 4.4:1 (hover contrast check, 11 Nov 2026) */
.b-line:hover{box-shadow:inset 0 0 0 2px var(--accent-ink);color:color-mix(in srgb,var(--accent-ink) 80%,#000)}
/* the first step band on Home (a consultation or feasibility page; Evan, 10 Nov 2026) */
.fstep{display:grid;gap:var(--s5)}
.fstep .cta2{margin-top:var(--s5)}
.fstep .ilist{align-self:center}
/* project showcase on Home: the first project large, the next two beside it. Not ".show": the tour uses that class
   for its card, and a project rule on it once pushed the tour card off screen (10 Nov 2026) */
.showcase{display:grid;gap:var(--s3)}
.sc-item{position:relative;margin:0;overflow:hidden;border-radius:var(--r);background:var(--dark-2)}
.sc-item img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;transition:scale .6s ease}
.sc-item figcaption{position:absolute;inset:auto 0 0;padding:var(--s6) var(--s4) var(--s4);background:linear-gradient(180deg,transparent,color-mix(in srgb,var(--dark) 88%,transparent));color:#fff}
.sc-item b{display:block;font:600 1.25rem/1.15 var(--head)}
.sc-item b a{color:#fff;text-decoration:none}
.sc-item b a::before{content:"";position:absolute;inset:0;z-index:1}
.sc-item b a::after{content:"\2192";margin-left:.35em;color:var(--accent)}
.sc-item span{display:block;margin-top:var(--s1);color:var(--on-dark);font-size:.9375rem}
.sc-item:hover img{scale:1.04}
#work .tlink{margin-top:var(--s4)}
.b-dark{background:var(--dark);color:#fff}
.btn[disabled]{opacity:.55;cursor:not-allowed}

/* header */
.top{background:var(--dark);color:#fff;position:relative;z-index:40}
.top .in{display:flex;align-items:center;gap:var(--s3);min-height:3.75rem}
.logo{margin-right:auto;display:flex;align-items:center;min-height:2.75rem;gap:var(--s2);text-decoration:none;font:800 1.125rem/1 var(--head);letter-spacing:-.01em}
.logo img{width:2.5rem;height:2.5rem;border-radius:50%;background:#fff}
.logo.wide img{width:auto;max-width:11rem;height:2.5rem;border-radius:0;background:none;object-fit:contain}
.logo.full img{width:auto;max-width:12.5rem;height:2.625rem;border-radius:0;background:none;object-fit:contain}
.logo.full.round img{width:3.5rem;height:3.5rem}
.legal a{text-decoration:underline}
.tel{display:flex;align-items:center;justify-content:center;gap:var(--s2);min-height:2.75rem;min-width:2.75rem;font:800 1rem var(--head);text-decoration:none;white-space:nowrap}
.tel svg{width:1.125rem;height:1.125rem;color:var(--accent);flex:none}
.tog{display:flex;align-items:center;gap:var(--s2);min-height:2.75rem;padding:0 0 0 .25rem;background:none;border:0;font:800 1rem var(--head);color:#fff;cursor:pointer}
.tog svg{width:1.125rem;height:1.125rem}
.nav{display:none;background:var(--dark);position:absolute;left:0;right:0;top:100%;max-height:calc(100dvh - 3.75rem);overflow:auto;padding:var(--s4) var(--gut) var(--s6);border-top:1px solid rgba(255,255,255,.14)}
.nav.open{display:block}
.nav .top-q{margin-bottom:var(--s3)}
.nav a:not(.btn),.nav summary{display:flex;align-items:center;justify-content:space-between;min-height:3rem;padding:0 var(--s2);font-weight:700;text-decoration:none;cursor:pointer;color:#fff;border-radius:6px}
.nav summary{list-style:none}
.nav summary::-webkit-details-marker{display:none}
.nav summary::after{content:"";width:.5rem;height:.5rem;border-right:2px solid var(--accent);border-bottom:2px solid var(--accent);transform:rotate(45deg);margin-right:.25rem}
.nav details[open]>summary::after{transform:rotate(-135deg)}
.nav details ul{padding-left:var(--s4);border-left:2px solid rgba(255,255,255,.14);margin-left:var(--s2)}
.nav a:not(.btn):hover,.nav summary:hover{color:var(--accent)}

/* swoosh at the foot of a dark panel */
.swoosh{width:100%;height:2.25rem;color:var(--to,#fff)}
.swoosh .fill{fill:currentColor}
.swoosh .stripe{fill:none;stroke:var(--accent);stroke-width:6}

/* sections */
.sec{padding-block:var(--sec)}
.sec h2{font-size:clamp(1.875rem,8vw,3.25rem);font-weight:800;line-height:1.02;color:var(--dark)}
/* The accent word in section headings keeps its colour but isn't italic by default (Evan, 10 Nov 2026, D4): on every
   site it was a big part of the sameness, and critics now call it an AI tell (principles TR). A motif can opt back in
   with its own `.sec h2 em{font-style:italic}`. Hero headlines and slogans keep it. */
.sec h2 em{font-style:normal;color:var(--accent-ink)}
.hero h1 em{font-style:italic;color:var(--accent-ink)}
.dark{background:var(--dark);color:#fff}
.dark h2,.sec.dark h2{color:#fff}
.dark h2 em,.sec.dark h2 em,.hero h1 em{color:var(--accent)}
.mist{background:var(--mist)}
.lede{max-width:58ch;margin-top:var(--s3)}
.dark .lede{color:var(--on-dark)}
.shead{margin-bottom:var(--s5)}
.prose p{max-width:62ch;margin-top:var(--s3)}
.prose p:first-child{margin-top:0}
.prose .ilist{margin-top:var(--s5)}

/* hero. Default layout: the job photo fills the panel, text sits on a scrim at the foot.
   Motif files can switch to a split layout (photo framed in the brand shape beside the text). */
.hero{position:relative;overflow:hidden}
.hero.home,.hero.svc:not(.noimg){display:grid;grid-template-rows:1fr auto;min-height:min(calc(100svh - 3.75rem - 4.25rem),48rem)}
.hero.svc:not(.noimg){min-height:min(calc(100svh - 3.75rem - 4.25rem),40rem)}
.hero-media{position:absolute;inset:0}
.hero-media img{width:100%;height:100%;object-fit:cover}
.hero-media::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,color-mix(in srgb,var(--dark) 10%,transparent) 0%,color-mix(in srgb,var(--dark) 25%,transparent) 28%,color-mix(in srgb,var(--dark) 86%,transparent) 58%,var(--dark) 100%)}
.hero>.in{position:relative;z-index:2;align-self:end;width:100%}
.hero .edge,.hero .swoosh{position:relative;z-index:3}
.hero-text{padding-block:var(--s4) var(--s5)}
.hero.home .hero-text,.hero.svc:not(.noimg) .hero-text{padding-top:10rem}
.hero.plain .hero-text,.hero.noimg .hero-text{padding-bottom:var(--s7)}
.hero.plain h1{font:800 clamp(2.125rem,9vw,3.75rem)/1.02 var(--head);letter-spacing:-.02em;margin-top:var(--s4)}
.hero.plain h1.long{font-size:clamp(1.75rem,7vw,3rem)}  /* long carried-over blog titles: five lines on a phone otherwise */
.hero-text .crumb ol{padding-top:0;margin-bottom:var(--s3)}
.crumb ol{display:flex;flex-wrap:wrap;gap:var(--s2);font-size:.9375rem;color:var(--on-dark);padding-top:var(--s3)}
.crumb li+li::before{content:"/";margin-right:var(--s2);opacity:.6}
.crumb a{text-decoration:none;color:#fff;display:inline-block;padding:.25rem 0}
.gbadge{display:inline-flex;align-items:center;gap:var(--s2);background:var(--dark-2);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.22);color:#fff;border-radius:99px;min-height:2.75rem;padding:0 .75rem 0 .5rem;font-weight:700;font-size:.9375rem;text-decoration:none;white-space:nowrap}
.gbadge .st{color:var(--star);letter-spacing:1px}
.gbadge .n{color:var(--on-dark);font-weight:400}
.slogan{font:800 clamp(2.375rem,12.5vw,4.75rem)/1 var(--head);letter-spacing:-.02em;margin-top:var(--s4)}
.slogan em{display:block;font-style:italic;color:var(--accent);padding-left:.04em}
.hero h1{font:700 1.0625rem/1.3 var(--body);letter-spacing:0;margin-top:var(--s3);color:#fff}
.hero.svc h1{font:800 clamp(2rem,9vw,3.5rem)/1.02 var(--head);letter-spacing:-.02em;margin-top:var(--s4)}
.hero .sub{color:#e6e7e4;margin-top:var(--s2);max-width:44ch;line-height:1.45}
.btns{display:grid;grid-template-columns:1.35fr 1fr;gap:var(--s2);margin-top:var(--s5)}
.btns .call{min-height:3.5rem}
.btns .call span{display:none}
.btns .b-ghost{min-height:3.5rem}
.prom{margin-top:var(--s3);font-size:.9375rem;line-height:1.4;color:var(--on-dark)}
/* phones: Call and Quote come straight after the headline, so they sit on the first screen above the call bar */
@media (max-width:879px){
  .hero.home .hero-text,.hero.svc .hero-text{display:flex;flex-direction:column}
  .hero-text>.gbadge{align-self:flex-start}
  .hero-text>.btns{order:5}
  .hero-text>.sub{order:6;margin-top:var(--s4)}
  .hero-text>.prom{order:7}
}

/* reviews */
.score{display:inline-grid;grid-template-columns:auto minmax(0,1fr);column-gap:var(--s4);align-items:center}
.score .big{grid-row:1/3;font:800 4.5rem/.85 var(--head);color:var(--dark);letter-spacing:-.04em}
.score .st{color:#b57f00;font-size:1.375rem;letter-spacing:2px;line-height:1.1}
.score .src{display:flex;align-items:center;gap:var(--s2);font-weight:700;min-height:1.75rem}
.score-h{margin:var(--s4) 0 var(--s5)}
.rail{display:grid;grid-auto-flow:column;grid-auto-columns:86%;gap:var(--s3);align-items:stretch;overflow-x:auto;scroll-snap-type:x mandatory;scroll-padding-inline:var(--gut);padding-inline:var(--gut);margin-inline:calc(-1 * var(--gut));padding-block:2px 6px;scrollbar-width:none}
.rail::-webkit-scrollbar{display:none}
/* cards in a rail are one height at every width (Evan, 10 Nov 2026: "The boxes don't line up, so longer reviews have
   bigger boxes"; this replaces the phone-only align-items:start). The quote grows and the name and date sit at the foot,
   so a short review's spare room reads as layout, not a gap. Opening one long review doesn't stretch the others. */
.rail:has(.rv.open){align-items:start}
.rv{scroll-snap-align:start;background:#fff;border:1.5px solid var(--line);border-radius:var(--r);padding:var(--s4);display:flex;flex-direction:column;gap:var(--s3)}
.rv .stars{color:#b57f00;letter-spacing:1px;line-height:1}
.rv .job{display:block;margin-top:var(--s2);font:800 1.125rem/1.15 var(--head);color:var(--accent-ink)}
.rv blockquote{line-height:1.45;flex:1}
.rv blockquote p+p{margin-top:var(--s2)}
.rv figcaption{font-size:.9375rem;color:var(--muted);display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap}
.rv figcaption b{color:var(--ink)}
/* long reviews in a rail fold with "Read more" (site.js); the fade shows there's more */
.rv.long blockquote{flex:none;max-height:calc(1.45em * 9);overflow:hidden;-webkit-mask-image:linear-gradient(180deg,#000 62%,transparent);mask-image:linear-gradient(180deg,#000 62%,transparent)}
.rv.long.open blockquote{max-height:none;-webkit-mask-image:none;mask-image:none}
/* phones fold a little earlier (site.js: over 9 lines, shown as 7), so one long review doesn't make every card tall */
@media (max-width:879px){.rv.long blockquote{max-height:calc(1.45em * 7)}}
.rv .more{align-self:flex-start;margin:calc(-1 * var(--s2)) 0 auto;min-height:2.75rem;padding:0;background:none;border:0;font:700 1rem var(--body);color:var(--accent-ink);text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.rlist{display:grid;gap:var(--s4)}
.rlist .rv{max-width:48rem}
/* few reviews (under 4 in total, Hemmens 9 Nov 2026): no rail and no folding; every review in full, the first as a
   large lead quote, the others beside it on desktop */
.rail.few{grid-auto-flow:row;grid-auto-columns:auto;grid-template-columns:minmax(0,1fr);overflow:visible;margin-inline:0;padding-inline:0;scroll-snap-type:none;align-items:start}
.rail.few .rv:first-child blockquote{font:500 clamp(1.1875rem,4.8vw,1.5rem)/1.4 var(--head);color:var(--dark)}
@media (min-width:880px){
  .rail.few{align-items:stretch}
  .rail.few.n2,.rail.few.n3{grid-template-columns:1.3fr 1fr}
  .rail.few.n3 .rv:first-child{grid-row:1/3}
  .rail.few .rv:first-child{padding:var(--s5)}
}

/* service doors */
.doors{display:grid;gap:var(--s4)}
.door{position:relative;background:#fff;border-radius:var(--r);overflow:hidden;display:flex;flex-direction:column;border:1.5px solid var(--line)}
.door h3 a::before{content:"";position:absolute;inset:0;z-index:1}
.door:hover{border-color:var(--accent-ink)}
.also{margin-top:var(--s5)}
.door img{width:100%;aspect-ratio:16/10;object-fit:cover}
.door .dh{padding:var(--s4);flex:1}
.door h3{font-size:1.375rem;font-weight:800;line-height:1.1}
.door h3 a{color:var(--dark);text-decoration:none}
.door h3 a::after{color:var(--accent-ink)}
.door p{margin-top:var(--s2);line-height:1.45}

/* photo rail and job cards */
.prail{display:grid;grid-auto-flow:column;grid-auto-columns:78%;gap:var(--s3);overflow-x:auto;scroll-snap-type:x mandatory;padding-inline:var(--gut);margin-inline:calc(-1 * var(--gut));scrollbar-width:none;margin-top:var(--s5)}
.prail::-webkit-scrollbar{display:none}
.prail figure{scroll-snap-align:start;position:relative}
.prail img{border-radius:var(--r);aspect-ratio:1/1;object-fit:cover;width:100%}
.prail figcaption{font-size:.9375rem;color:var(--muted);margin-top:var(--s2);line-height:1.35}
.tag{position:absolute;top:var(--s2);left:var(--s2);background:var(--dark-3);color:#fff;font:italic 800 .9375rem var(--head);padding:.2rem .6rem;border-radius:.375rem}
.tag.after{background:var(--accent);color:var(--dark)}
.prail .tag{color:#fff;margin-top:0}
.prail .tag.after{color:var(--dark)}
.jcards{display:grid;gap:var(--s4)}
.jcard{display:block;background:#fff;border-radius:var(--r);overflow:hidden;border:1.5px solid var(--line)}
.jcard img{aspect-ratio:4/3;object-fit:cover;width:100%}
.jcard figcaption{padding:var(--s4)}
.jcard b{display:block;font:800 1.25rem/1.15 var(--head);color:var(--dark)}
.jcard span{display:block;margin-top:var(--s1);color:var(--muted);font-size:.9375rem}
/* call-to-action card in the spare space of the last row: message and buttons centred in the card, the rating pinned
   to the foot. A short accent rule opens it, so it reads as a designed panel rather than an empty card. */
.door.dcta{background:var(--dark);border-color:var(--dark);color:var(--on-dark)}
.door.dcta .dh{display:flex;flex-direction:column;padding:var(--s5)}
.door.dcta h3{color:#fff;font-size:clamp(1.375rem,5.5vw,1.625rem);margin-top:auto}
.door.dcta h3::before{content:"";display:block;width:2.5rem;height:.25rem;border-radius:99px;background:var(--accent);margin-bottom:var(--s3)}
.door.dcta p{color:var(--on-dark);max-width:40ch}
.door.dcta .cta2{margin-top:var(--s5);display:grid;grid-template-columns:repeat(auto-fit,minmax(8.5rem,1fr));gap:var(--s2);justify-content:stretch}
.door.dcta .cta2 .btn{width:100%;min-height:3.25rem;padding:0 var(--s3);white-space:nowrap}
.door.dcta .dproof{display:flex;align-items:center;gap:var(--s2);flex-wrap:wrap;margin-top:auto;padding-top:var(--s5);font-size:.9375rem;line-height:1.3;color:var(--on-dark);max-width:none}
.door.dcta .dproof .st{color:var(--star);letter-spacing:1px}
.door.dcta .dproof::before{content:"";flex-basis:100%;height:1px;background:rgba(255,255,255,.16);margin-bottom:var(--s3)}
.door.dcta:hover{transform:none;box-shadow:none;border-color:var(--dark)}
.jcard.proj{position:relative}
.jcard.proj b a{color:var(--dark);text-decoration:none;display:inline-block;padding:.5rem 0}
.jcard.proj b{margin-top:-.5rem}
.jcard.proj b a::before{content:"";position:absolute;inset:0;z-index:1}
.jcard.proj b a::after{content:"\2192";margin-left:.3em;color:var(--accent-ink)}
.jcard.proj span{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.machines{margin-top:var(--s5)}
.door.mach h2{font-size:1.5rem;line-height:1.1}
.door.mach .specs{margin-top:var(--s3);font-size:.9375rem}
.door.mach .specs li{padding-top:var(--s1);padding-bottom:var(--s1)}
.morelist{margin-top:var(--s5);display:flex;flex-wrap:wrap;gap:var(--s2) var(--s4);align-items:baseline}
.morelist b{flex-basis:100%}
/* the services after the first six: tidy pill links (loose underlined links wrapped unevenly on phones) */
.morelist{gap:var(--s2)}
.morelist b{margin-bottom:var(--s1)}
.morelist a{display:inline-flex;align-items:center;gap:.4em;min-height:2.75rem;padding:0 1rem;font-weight:700;color:var(--dark);text-decoration:none;background:#fff;border:1.5px solid var(--line);border-radius:99px;transition:border-color .18s ease}
.morelist a::after{content:"\2192";color:var(--accent-ink)}
.morelist a:hover{border-color:var(--accent-ink)}

/* includes list */
.incl{display:grid;gap:var(--s5)}
.incl img{border-radius:var(--r);aspect-ratio:4/3;object-fit:cover;width:100%}
.ilist{display:grid;gap:var(--s3);margin-top:var(--s4)}
.ilist li{padding-left:1.75rem;position:relative;line-height:1.45}
.ilist li::before{content:"";position:absolute;left:0;top:.45rem;width:.75rem;height:.75rem;border-radius:2px;background:var(--accent);transform:rotate(45deg)}
.ilist b{font-weight:700}

/* how it works */
.steps{display:grid;gap:var(--s5);margin-top:var(--s6);counter-reset:s}
.steps li{position:relative;padding-left:4rem;min-height:3rem;counter-increment:s}
.steps li::before{content:counter(s);position:absolute;left:0;top:0;width:3rem;height:3rem;border-radius:50%;background:var(--accent);color:var(--dark);display:grid;place-items:center;font:800 1.25rem var(--head)}
.steps b{font:800 1.25rem/1.15 var(--head);display:block;margin-bottom:var(--s2)}
.steps span{line-height:1.45;display:block;color:var(--on-dark)}
.cta2{display:grid;gap:var(--s2);margin-top:var(--s6)}

/* meet the owner */
.meet{display:grid;gap:var(--s5)}
.meet .pics img{border:.3125rem solid #fff;border-radius:.5rem;object-fit:cover;box-shadow:0 10px 24px rgba(0,0,0,.35);aspect-ratio:4/3;width:100%;transform:rotate(1deg)}
.meet h3{margin-top:var(--s2);font-size:clamp(1.375rem,5.8vw,1.75rem);font-weight:800;line-height:1.15;color:#fff}
.meet .lede{color:#e6e7e4}
.meet .btn{margin-top:var(--s5);max-width:16rem}
.creds span{display:inline-block}  /* each credential stays on one line where it fits ("$20 / million" split it) */
.creds{margin-top:var(--s5);padding-top:var(--s4);border-top:1px solid rgba(255,255,255,.2);font-weight:700;color:var(--accent);line-height:1.6}

/* FAQ */
.faqwrap{display:grid;gap:var(--s5)}
.faq{display:grid;gap:var(--s2)}
/* open item: white with a full accent border, not a one-side stripe (a common template tell) */
.faq details{background:var(--mist);border-radius:var(--r);border:2px solid transparent}
.faq details[open]{background:#fff;border-color:var(--accent-ink)}
.faq summary{display:flex;align-items:center;justify-content:space-between;gap:var(--s3);min-height:4rem;padding:var(--s3) var(--s4);font:800 1.125rem/1.2 var(--head);color:var(--dark);cursor:pointer;list-style:none}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";flex:none;width:2rem;height:2rem;border-radius:50%;background:var(--dark);color:#fff;display:grid;place-items:center;font:800 1.25rem/1 var(--body)}
.faq details[open] summary::after{content:"\2212";background:var(--accent-ink)}
.faq details p{padding:0 var(--s4) var(--s4);max-width:58ch}
.faq details a{color:var(--accent-ink);font-weight:700}

/* areas */
.chips{display:flex;flex-wrap:wrap;gap:var(--s2);margin-top:var(--s4)}
.chips li{display:inline-flex;align-items:center;min-height:2.5rem;padding:0 var(--s4);border-radius:99px;background:#fff;border:1.5px solid var(--line);font-weight:700;color:var(--dark)}

/* why choose us: cards with the motif bullet as an icon (motif files restyle .why li::before) */
.why{display:grid;gap:var(--s4);counter-reset:w}
.why li{position:relative;background:var(--mist);border-radius:var(--r);padding:var(--s5) var(--s5) var(--s5) 4.25rem;counter-increment:w}
.why li::before{content:"";position:absolute;left:var(--s5);top:1.55rem;width:1.5rem;height:1.5rem;border-radius:3px;background:var(--accent);transform:rotate(45deg)}
.why b{display:block;font:800 1.25rem/1.15 var(--head);color:var(--dark)}
.why span{display:block;margin-top:var(--s2);line-height:1.5}

/* where we work: copy plus one map of the whole area */
.areas{display:grid;gap:var(--s5)}
.areas .tlink{margin-top:var(--s3)}
.map{position:relative;border-radius:var(--r);overflow:hidden;aspect-ratio:4/3;background:var(--line);box-shadow:0 10px 30px rgba(0,0,0,.12)}
/* Google's "Open in Maps" place card sits at the top of every embed and gets cut off by shaped map frames
   (Evan, 8 Nov 2026), so the iframe starts above the frame and that card stays out of view. Attribution stays at the foot. */
.map iframe{position:absolute;left:0;right:0;bottom:0;top:-6.5rem;width:100%;height:calc(100% + 6.5rem);border:0;filter:saturate(.85)}

/* owner photo stand-in */
.ownph{display:grid;place-items:center;align-content:center;gap:var(--s3);aspect-ratio:4/3;width:100%;background:linear-gradient(160deg,var(--dark-2),var(--dark-3));color:var(--on-dark);border-radius:.5rem;font-weight:700;text-align:center;padding:var(--s4)}
.ownph svg{width:4.5rem;height:4.5rem;fill:var(--accent);opacity:.85}
.meet .pics .ownph{border:.3125rem solid #fff;box-shadow:0 10px 24px rgba(0,0,0,.35);transform:rotate(1deg)}

/* service photos when there are only 1 to 3 */
.pgrid{display:grid;gap:var(--s3);margin-top:var(--s5)}
.pgrid figure{position:relative}
.pgrid img{width:100%;border-radius:var(--r);aspect-ratio:4/3;object-fit:cover}
.pgrid.n3{grid-template-columns:1fr 1fr}
.pgrid.n3 figure:first-child{grid-column:1/-1}
.pgrid.n3 figure:first-child img{aspect-ratio:16/9}
.pgrid.n1 img{aspect-ratio:16/9}

/* multi-step quote form */
.qprog{display:flex;align-items:center;gap:var(--s3)}
.qbar{flex:1;height:.375rem;border-radius:99px;background:rgba(255,255,255,.16);overflow:hidden}
.qbar i{display:block;height:100%;background:var(--accent);transform:scaleX(.334);transform-origin:left;transition:transform .25s ease}
.qcount{font-size:.875rem;color:var(--on-dark);white-space:nowrap}
.qs{display:grid;gap:var(--s4)}
.qs legend{padding:0;margin-bottom:var(--s4)}
.ms.js .qs{display:none}
.ms.js .qs.on{display:grid}
.ms:not(.js) .qprog,.ms:not(.js) [data-next],.ms:not(.js) [data-back]{display:none}
.qnav{display:grid;grid-template-columns:auto 1fr;gap:var(--s2)}
.qnav .btn:only-child{grid-column:1/-1}
.qnav .b-ghost{width:auto;padding:0 var(--s5)}
.q3 textarea::placeholder{color:#6b716b}

/* contact page */
.cgrid{display:grid;gap:var(--s4)}
.cbox{background:var(--mist);border-radius:var(--r);padding:var(--s5)}
.cbox p{margin-top:var(--s1)}
.cbox .chips li{background:#fff}
.ct{font:800 .9375rem var(--head);color:var(--accent-ink);text-transform:uppercase;letter-spacing:.06em;margin:0 0 var(--s2)!important}
.cbig{display:inline-block;font:800 clamp(2rem,9vw,3rem)/1.05 var(--head);color:var(--dark);text-decoration:none;white-space:nowrap}
.cmail{font-weight:700;color:var(--dark);overflow-wrap:anywhere;display:inline-block;padding:.25rem 0}

/* quote form (inactive in previews) */
.qwrap{display:grid;gap:var(--s6)}
.door-no{margin-top:var(--s5)}
.door-no small{display:block;font:700 1rem var(--body);color:var(--on-dark);margin-bottom:var(--s2)}
.door-no a{display:inline-block;font:800 clamp(2.25rem,11vw,4rem)/1 var(--head);color:#fff;text-decoration:none;padding-bottom:var(--s2);border-bottom:6px solid var(--accent);white-space:nowrap}
.qproof{display:flex;align-items:center;gap:var(--s2);margin-top:var(--s5);font-size:.9375rem;color:var(--on-dark)}
.q3{background:var(--dark-2);border:1.5px solid rgba(255,255,255,.14);border-radius:var(--r);padding:var(--s5) var(--s4);display:grid;gap:var(--s4)}
.q3 h3{font-size:1.375rem;font-weight:800;line-height:1.1}
.q3 fieldset{border:0;min-width:0}
.q3 .lab{font:600 1rem/1.3 var(--body);color:#fff;display:block;margin-bottom:var(--s2)}
.q3 input[type=text],.q3 input[type=tel],.q3 textarea{width:100%;min-height:3.25rem;font:1.0625rem var(--body);padding:.5rem .875rem;border:0;border-radius:.625rem;background:#fff;color:var(--ink)}
.q3 textarea{min-height:5.5rem;resize:vertical}
.tiles{display:grid;grid-template-columns:1fr 1fr;gap:var(--s2)}
.tile{position:relative;display:block;cursor:pointer}
.tile input{position:absolute;opacity:0;inset:0;width:100%;height:100%;cursor:pointer;margin:0}
.tile span{display:flex;align-items:center;min-height:3.5rem;padding:.5rem .75rem;background:var(--dark);border:2px solid rgba(255,255,255,.26);border-radius:.75rem;font:800 1rem/1.15 var(--head);color:#fff}
.tile input:checked+span{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.tile input:focus-visible+span{outline:3px solid #fff;outline-offset:2px}
.fine{font-size:.9375rem;color:var(--on-dark);line-height:1.4}
.pvnote{background:#fff4c7;color:#3a2f00;border-radius:.5rem;padding:var(--s3);font-size:.9375rem;line-height:1.35}

/* footer */
/* phones: the room for the sticky call bar is part of the footer, so the page ends in footer colour, not a white strip */
footer{background:var(--dark-3);color:#d9dbd7;padding-block:var(--s6) calc(var(--s6) + 4.5rem + env(safe-area-inset-bottom,0px));font-size:1rem}
footer .grid{display:grid;gap:var(--s5)}
footer a{color:#d9dbd7;text-decoration:none}
footer a:hover{color:#fff;text-decoration:underline}
.ft{font:800 1.0625rem var(--head);color:var(--accent);margin-bottom:var(--s2)}
.flist a{display:flex;align-items:center;min-height:2.5rem;padding-block:.3rem;line-height:1.3}  /* a name on two lines keeps clear of the next */
.fcols{display:grid;grid-template-columns:1fr 1fr;gap:var(--s5) var(--s4)}
.fbrand b{display:block;font:800 1.25rem var(--head);color:#fff;margin-bottom:var(--s2)}
.flogo{height:3.25rem;width:auto;margin-bottom:var(--s4)}
.flogo.round{height:6rem}
.fbrand p{line-height:1.6}
.fbrand p a{display:inline-flex;align-items:center;min-height:2.75rem}
.legal{border-top:1px solid rgba(255,255,255,.12);margin-top:var(--s5);padding-top:var(--s3);font-size:.875rem;color:#b9bdb8;line-height:1.5}

/* sticky call bar on phones */
.bar{position:fixed;left:0;right:0;bottom:0;z-index:30;background:var(--dark);border-top:3px solid var(--accent);padding:.5rem max(.5rem,env(safe-area-inset-right,0px)) calc(.5rem + env(safe-area-inset-bottom,0px)) max(.5rem,env(safe-area-inset-left,0px));display:grid;grid-template-columns:1fr 1fr;gap:.5rem}
.bar .btn{min-height:3rem;padding:0 .25rem}
.bar.t3{grid-template-columns:1fr auto 1fr}
.bar.t3 .btn[href^="sms:"]{padding:0 1rem}
/* "Prefer to text?" under the hero buttons (D5): only when business.text_ok and a mobile number */
.hero .txt{margin-top:var(--s3);font-size:1rem;color:var(--on-dark)}
.hero .txt a{color:#fff;font-weight:700;white-space:nowrap}
/* out of the way while the hero's own Call and Quote buttons show, or while someone types in a form (site.js) */
.bar{transition:transform .25s ease,visibility .25s}
.bar.hide{transform:translateY(100%);visibility:hidden}
.bar.hide~.tour-again{bottom:calc(1rem + env(safe-area-inset-bottom,0px))}
@media (prefers-reduced-motion:reduce){.bar{transition:none}}

/* narrow phones: the business name keeps its room; the number stays on the hero button and the sticky bar */
@media (max-width:429px){.tel span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}.logo{font-size:1rem;line-height:1.1;min-width:0}}
@media (min-width:560px){
  .rail{grid-auto-columns:46%}
  .prail{grid-auto-columns:40%}
  .btns,.cta2{grid-template-columns:auto auto;justify-content:start}
  .btns .btn,.cta2 .btn{width:auto;min-height:3.5rem;padding:0 var(--s5)}
  .jcards,.doors{grid-template-columns:1fr 1fr}
  /* two across: a CTA card that would start a row on its own spans the row instead of leaving a hole */
  .doors>.dcta:nth-child(odd){grid-column:1/-1}
  /* an odd machine card left over at the end becomes a wide card (photo beside text). Project and blog cards are
     articles and stay one column wide, with any spare space left empty (Evan, 10 Nov 2026) */
  .machines>.door:last-child:nth-child(odd):not(:first-child){grid-column:1/-1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center}
  .machines>.door:last-child:nth-child(odd):not(:first-child) img{height:100%}
}
@media (min-width:880px){
  :root{--sec:5.5rem}
  footer{padding-bottom:var(--s6)}
  .bar{display:none}
  .top{position:sticky;top:0}
  .top .in{min-height:5rem}
  /* a jump to #quote or an FAQ lands below the sticky header, not under it (design-skill dig, 11 Nov 2026) */
  main [id]{scroll-margin-top:6rem}
  .logo{font-size:1.375rem}
  .logo img{width:3.25rem;height:3.25rem}
  .tel{font-size:1.1875rem;order:3}
  .tog{order:4}
}
/* The full menu only from 1180 px. Between 880 and 1180 the menu, the header button and the phone number don't fit
   on one line, and wrapped labels ("Book a / consultation", "Our / projects") looked "super ugly" (Evan, 10 Nov 2026),
   so tablets and small laptops keep the menu button. Labels never wrap; render audit FAILs nav-wrap. */
@media (min-width:1180px){
  .tog{display:none}
  .nav{order:2;display:block;position:static;max-height:none;overflow:visible;background:none;border:0;padding:0}
  .nav>ul{display:flex;align-items:center;gap:var(--s1)}
  .nav>ul>li{position:relative}
  .nav a:not(.btn),.nav summary{font:700 1rem var(--body);padding:0 var(--s2);min-height:2.75rem;gap:var(--s2)}
  .nav>ul>li>a,.nav summary,.nav .top-q .btn{white-space:nowrap}
  .nav .top-q{order:9;margin:0 0 0 var(--s2)}
  .nav .top-q .btn{min-height:2.75rem;width:auto;font-size:1rem}
  .nav details ul{position:absolute;top:100%;left:0;min-width:17rem;background:var(--dark);border:1px solid rgba(255,255,255,.18);border-radius:.625rem;padding:var(--s2);margin:0;box-shadow:0 14px 30px rgba(0,0,0,.3)}
}
@media (min-width:880px){
  .swoosh{height:4rem}
  .logo.full img{height:3.25rem;max-width:16rem}
  .logo.full.round img{width:4.25rem;height:4.25rem}
  .hero.home,.hero.svc:not(.noimg){min-height:40rem}
  .hero.svc:not(.noimg){min-height:34rem}
  .hero-media::after{background:linear-gradient(90deg,var(--dark) 0%,color-mix(in srgb,var(--dark) 82%,transparent) 34%,color-mix(in srgb,var(--dark) 20%,transparent) 66%,transparent 100%)}
  .hero>.in{align-self:center}
  .hero-text{max-width:38rem}
  .hero.home .hero-text,.hero.svc:not(.noimg) .hero-text{padding:var(--s7) 0 var(--s8)}
  .hero.plain .hero-text,.hero.noimg .hero-text{padding:var(--s6) 0 var(--s7);max-width:48rem}
  .hero h1{font-size:1.375rem;margin-top:var(--s4)}
  .hero .sub{font-size:1.1875rem}
  .btns{grid-template-columns:auto auto}
  .btns .call span{display:inline}
  .tour{left:auto;right:1.5rem;bottom:1.5rem;width:24rem}
  .tour.hello{right:50%;bottom:50%;transform:translate(50%,50%)}
  .tour.hello:not(.show){transform:translate(50%,calc(50% + 1.5rem))}
  .cgrid{grid-template-columns:1fr 1fr}
  /* three contact boxes: the phone box runs down the left beside email and hours, so no box sits alone on a row */
  .cgrid:has(>.cbox:nth-child(3))>.cbox:first-child{grid-row:span 2;display:flex;flex-direction:column;justify-content:center}
  .faqwrap h2{font-size:clamp(1.875rem,3.4vw,2.75rem);hyphens:auto}
  .why{grid-template-columns:repeat(2,1fr);gap:var(--s5)}
  .areas{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:var(--s8);align-items:center}
  .pgrid.n2,.pgrid.n3{grid-template-columns:repeat(var(--cols,2),1fr)}
  .pgrid.n3{--cols:3}
  .pgrid.n3 figure:first-child{grid-column:auto}
  .pgrid.n3 figure:first-child img{aspect-ratio:4/3}
  .pgrid.n1{max-width:48rem}
  .flogo{height:4rem}
  .flogo.round{height:7.5rem}
  .rail{grid-auto-columns:calc((100% - 2 * var(--s3)) / 3);margin-inline:0;padding-inline:0}
  .prail{grid-auto-columns:calc((100% - 3 * var(--s3)) / 4);margin-inline:0;padding-inline:0}
  /* 3 across, left-aligned. A short last row of service cards gets a call-to-action card in the spare space
     (Evan, 8 Nov 2026: no centred rows); with one card left over, the CTA takes both spare columns */
  .doors{grid-template-columns:repeat(3,1fr);gap:var(--s5)}
  .doors>.dcta:nth-child(odd){grid-column:auto}
  .door.dcta.r1{grid-column:span 2}
  /* two or four services: two across, bigger photos (Evan, 10 Nov 2026: a layout made for the count) */
  .doors.n2,.doors.n4{grid-template-columns:repeat(2,1fr)}
  .doors.n2 .door img,.doors.n4 .door img{aspect-ratio:16/9}
  .doors.n2 .door .dh,.doors.n4 .door .dh{padding:var(--s5)}
  .fstep{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--s8);align-items:center}
  .showcase.n3{grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);grid-template-rows:1fr 1fr}
  .showcase.n3 .lead{grid-row:1/3}
  .showcase .lead img{height:100%;aspect-ratio:auto;min-height:30rem}
  .showcase.n2{grid-template-columns:1fr 1fr}
  .sc-item figcaption{padding:var(--s7) var(--s5) var(--s5)}
  .sc-item.lead b{font-size:1.75rem}
  .door.dcta .dh{padding:var(--s6)}
  .tour-again{bottom:1.5rem;left:1.5rem}
  .jcards{grid-template-columns:repeat(3,1fr)}
  .machines>.door:last-child:nth-child(odd):not(:first-child){grid-column:auto;display:flex}
  .machines>.door:last-child:nth-child(odd):not(:first-child) img{height:auto}
  /* three across: one machine alone on the last row becomes a wide card, photo the width of one column */
  .machines>.door:last-child:nth-child(3n+1):not(:first-child){grid-column:1/-1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);align-items:center}
  .machines>.door:last-child:nth-child(3n+1):not(:first-child) img{height:100%}
  .incl{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:var(--s8);align-items:center}
  /* steps are a sequence, read left to right: one row when they fit (Evan, 8 Nov 2026: a centred second row zig-zagged
     the numbers on Treeworx), wrapping left-aligned on narrower screens. Not the doors' centring trick. */
  .steps{grid-template-columns:repeat(3,1fr);gap:var(--s6) var(--s7)}  /* always three steps (model) */
  /* the owner stand-in stays a framed card, not a big empty panel (review, 8 Nov 2026) */
  .meet .pics .ownph{aspect-ratio:16/9}
  .steps li{padding:4.25rem 0 0}
  .faqwrap{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:var(--s8);align-items:start}
  .meet{grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:var(--s4) var(--s8);align-items:center}
  .qwrap{grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:var(--s8);align-items:start}
  .q3{padding:var(--s6)}
  footer .grid{grid-template-columns:minmax(0,.9fr) minmax(0,2fr);gap:var(--s7)}
  .fcols{grid-template-columns:repeat(3,1fr)}
}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* Feedback and motion. Hover and press feedback everywhere. Entrance and scroll motion only under html.motion, which
   <head> sets unless the visitor prefers reduced motion or the URL has ?nopop/?shots (screenshots and checks measure
   the settled page). Uses the separate translate/scale properties so motif transforms (rotated bullets) survive. */
.btn{transition:background-color .18s ease,box-shadow .18s ease,color .18s ease,transform .12s ease}
.btn:active{transform:translateY(1px) scale(.985)}
.btn:focus-visible,.door a:focus-visible,.gbadge:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
.gbadge{transition:box-shadow .18s ease}
.door,.jcard{transition:transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.door img,.jcard img{transition:scale .6s ease}
.door h3 a::after{content:"\2192";display:inline-block;margin-left:.3em;transition:translate .2s ease}
@media (hover:hover){
  .b-acc:hover{background:color-mix(in srgb,var(--accent) 80%,#fff)}
  .b-ghost:hover{background:rgba(255,255,255,.08);box-shadow:inset 0 0 0 2px var(--accent)}
  .b-dark:hover{background:color-mix(in srgb,var(--dark) 78%,#fff)}
  .gbadge:hover{box-shadow:inset 0 0 0 1.5px var(--accent)}
  .door:hover,.jcard:hover{transform:translateY(-4px);box-shadow:0 14px 30px rgba(0,0,0,.14)}
  .door:hover img,.jcard:hover img{scale:1.04}
  .door:hover h3 a::after{translate:5px 0}
}
/* reduced motion: no card lift, photo zoom or arrow nudge on hover (principles VD-26/27, 10 Nov 2026) */
@media (prefers-reduced-motion:reduce){
  .door:hover,.jcard:hover{transform:none}
  .door:hover img,.jcard:hover img{scale:none}
  .door:hover h3 a::after{translate:none}
}
/* review and photo rails on desktop: previous and next buttons (site.js), so cards past the third aren't hidden
   behind a scrollbar that isn't shown (principles CD-55, 10 Nov 2026). Phones keep the swipe, with the next card
   peeking in. */
.railnav{display:none}
@media (min-width:880px){
  .railnav{display:flex;justify-content:flex-end;gap:.5rem;margin-top:var(--s3)}
  .railnav[hidden]{display:none}
}
.railnav button{width:2.75rem;height:2.75rem;border-radius:50%;border:1px solid var(--line);background:#fff;color:var(--ink);font:600 1.5rem/1 var(--body);cursor:pointer;display:grid;place-items:center;padding:0}
.railnav button:disabled{opacity:.35;cursor:default}
@media (hover:hover){.railnav button:hover:not(:disabled){border-color:var(--ink)}}
/* Accent buttons on light sections take the dark colour (Evan, 10 Nov 2026, D10): most accents are only 1.4 to 3.6:1
   on white (principles VD-11/12). Dark panels inside a light section (the services call-to-action card) keep the accent. */
.sec .b-acc:not(:is(.dark,.dcta,.hero,.bar) .b-acc){background:var(--dark);color:#fff}
@media (hover:hover){
  .sec .b-acc:not(:is(.dark,.dcta,.hero,.bar) .b-acc):hover{background:color-mix(in srgb,var(--dark) 78%,#fff)}
}
/* review dates (D6; principles CD-19): month and year, only when reliable (build.review_date) */
.rv figcaption time{flex-basis:100%;font-size:.875rem}
@keyframes rise{from{opacity:0;translate:0 14px}}
@keyframes settle{from{scale:1.06}}
/* The hero's text and buttons are simply there when the page appears (Evan, 10 Nov 2026, D2): animating the headline
   and Call slows people down (NN/g; principles VD-26). The photo still settles; cards still fade up on scroll. */
.motion .hero-media img{animation:settle 1.4s cubic-bezier(.2,.7,.2,1) both}
/* scroll reveal: site.js adds .rv-in (so nothing hides without JS) and .seen once it's on screen */
.motion .rv-in{opacity:0;translate:0 18px;transition:opacity .6s ease var(--d,0s),translate .6s cubic-bezier(.2,.7,.2,1) var(--d,0s),transform .2s ease,box-shadow .2s ease,border-color .2s ease}
.motion .rv-in.seen{opacity:1;translate:none}
/* keyboard: a card that takes focus before it has faded in shows at once, so focus is never on something invisible (WCAG 2.4.7) */
.motion .rv-in:focus-within{opacity:1;translate:none;transition:none}
/* why-us bullets pop in after their card; process steps light up one by one as you scroll, like Harry's mower */
.motion .why li::before{transition:scale .45s cubic-bezier(.3,1.6,.5,1) calc(var(--d,0s) + .25s)}
.motion .why li.rv-in:not(.seen)::before{scale:0}
.motion .steps li::before{transition:filter .4s ease,opacity .4s ease,scale .45s cubic-bezier(.3,1.6,.5,1);transition-delay:calc(var(--d,0s) + .15s)}
.motion .steps li.rv-in:not(.on)::before{filter:grayscale(1);opacity:.45;scale:.85}

/* Motif: COVE (Coast to Coast Concreting). Two things of theirs:
   - the hand-drawn ring of their round logo (Facebook, Instagram), open at the foot where "CONCRETING" sits. It was traced
     from the logo itself (cove.html #cvring), with a heavier cut of the same ring for small icons (--cvring below);
   - the overlapping trowel arcs of a colour-coved finish, the one they show most (Finishes page, "Colour Coved" highlight).
   Edge: every dark panel ends in a band of coved arcs pressed into the charcoal, then a straight, clean join.
   Mark: the round logo on the hero photo, like a stamp. Bullets, why points and step numbers sit in the ring.
   Owner: the photo cut to a circle inside the logo's ring, the name spaced along the open foot like "CONCRETING".
   Type: Josefin Sans carries the logo's wide, spaced capitals; the script stays in the logo only. */
:root{
  --r:.25rem;--btn-r:.25rem;
  --cvring:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M13.6 76.4L12.4 75.3L11.2 74.2L9.9 73.1L9 71.8L8.2 70.4L7.3 69L6.7 67.5L6 66L5.4 64.5L5 62.9L4.7 61.3L4.4 59.7L4.1 58.1L3.9 56.5L3.6 54.9L3.4 53.3L3.3 51.6L3.2 50L3.2 48.4L3.3 46.7L3.2 45.1L3.3 43.4L3.4 41.8L3.5 40.1L3.7 38.5L4.2 36.9L4.8 35.3L5.4 33.8L6.1 32.3L7 30.9L7.8 29.4L8.6 28L9.3 26.5L10.2 25.1L11 23.7L11.9 22.3L13 21.1L14.1 19.9L15 18.5L16.1 17.2L17.1 16L18.2 14.7L19.4 13.5L20.7 12.5L22 11.5L23.4 10.6L24.9 9.8L26.4 9L27.8 8.3L29.4 7.7L30.9 7.2L32.5 6.6L34 6.1L35.6 5.7L37.1 5.2L38.7 4.8L40.3 4.4L41.9 4.1L43.5 3.8L45.1 3.7L46.8 3.6L48.4 3.6L50 3.6L51.6 3.7L53.2 3.8L54.8 4L56.5 4.1L58.1 4.3L59.6 4.6L61.2 5L62.8 5.4L64.4 5.8L65.9 6.2L67.5 6.7L69 7.2L70.5 7.9L72 8.7L73.4 9.4L74.9 10.2L76.3 10.9L77.8 11.7L79.3 12.5L80.6 13.5L81.8 14.7L82.9 16L84 17.2L84.9 18.5L85.9 19.9L87 21.1L87.9 22.4L88.8 23.8L89.7 25.2L90.4 26.7L91.1 28.1L91.9 29.6L92.5 31.1L93.2 32.6L93.8 34.1L94.2 35.6L94.6 37.2L94.8 38.8L95.2 40.4L95.5 42L95.8 43.6L96.1 45.2L96.3 46.8L96.3 48.4L96.2 50L96.2 51.6L96.2 53.2L96.1 54.8L95.9 56.5L95.7 58.1L95.3 59.6L94.9 61.2L94.4 62.7L93.9 64.3L93.4 65.8L92.9 67.3L92.2 68.8L91.5 70.3L90.9 71.7L90.1 73.2L89.4 74.6L88.5 76L87.2 77L86 78.1L84.7 79.1L84.1 78.6L84.8 77.2L85.5 75.8L86 74.3L86.9 73.1L87.8 71.8L88.6 70.5L89.3 69.2L89.9 67.7L90.3 66.3L90.8 64.8L91.2 63.4L91.5 61.9L91.6 60.4L91.7 58.9L91.8 57.4L91.9 55.9L91.9 54.4L92 52.9L92.1 51.5L91.9 50L91.7 48.5L91.5 47.1L91.4 45.7L91.2 44.2L91 42.8L90.8 41.3L90.5 39.9L90 38.5L89.4 37.2L89 35.8L88.5 34.4L87.9 33.1L87.3 31.8L86.7 30.5L85.9 29.2L85.2 28L84.5 26.7L83.7 25.5L82.9 24.3L82.2 23L81.2 21.9L80 21L78.9 20.1L77.7 19.2L76.5 18.4L75.4 17.5L74.4 16.4L73.3 15.4L72.2 14.4L71 13.7L69.7 13L68.4 12.3L67.1 11.7L65.8 11L64.4 10.3L63.1 9.7L61.7 9.2L60.3 8.8L58.8 8.5L57.4 8.3L55.9 8.1L54.4 8L52.9 8L51.5 8L50 8.1L48.5 8.2L47.1 8.4L45.6 8.5L44.2 8.7L42.8 9L41.3 9.3L39.9 9.5L38.5 9.9L37.1 10.2L35.7 10.7L34.3 11.2L33 11.8L31.7 12.4L30.4 13.1L29.1 13.9L28 14.8L26.8 15.7L25.8 16.6L24.7 17.6L23.6 18.5L22.5 19.5L21.4 20.4L20.3 21.3L19.2 22.2L18 23.1L17 24.2L16.2 25.5L15.3 26.6L14.5 27.8L13.9 29.1L13 30.3L12.2 31.6L11.7 32.9L11.3 34.4L10.9 35.8L10.6 37.2L10.4 38.6L10.2 40.1L9.7 41.4L9.3 42.8L9 44.2L8.7 45.7L8.4 47.1L8.5 48.6L8.5 50L8.6 51.4L8.7 52.9L8.8 54.3L8.9 55.8L9.1 57.2L9.3 58.6L9.6 60.1L9.8 61.5L10.1 63L10.2 64.5L10.5 66L10.9 67.4L11.5 68.8L12.1 70.2L12.8 71.5L13.2 73L13.7 74.5L14.2 76Z'/%3E%3C/svg%3E");
  /* coved arcs: two sets of trowel fans, half a fan apart, so they cross the way a coved finish does */
  --cvarcs:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 32' preserveAspectRatio='none'%3E%3Cg fill='none' stroke='%23fff' stroke-opacity='.13' stroke-width='1.4' stroke-linecap='round'%3E%3Cpath d='M3 33A29 29 0 0 1 61 33M11 33A21 21 0 0 1 53 33M19 33A13 13 0 0 1 45 33'/%3E%3Cpath d='M-29 33A29 29 0 0 1 29 33M35 33A29 29 0 0 1 93 33M-21 33A21 21 0 0 1 21 33M43 33A21 21 0 0 1 85 33' stroke-opacity='.08'/%3E%3C/g%3E%3C/svg%3E");
}
#cvring path{fill:currentColor}

/* type: wide spaced capitals for the slogan, like "CONCRETING" in the logo */
.slogan{text-transform:uppercase;letter-spacing:.04em;font-weight:700}
.sec h2,.hero.svc h1,.hero.plain h1{font-weight:700;letter-spacing:-.005em}
.sec h2{text-wrap:balance}
.door h3,.why b,.steps b,.faq summary{font-weight:700}
.btn{font-weight:700;letter-spacing:.01em}

/* edge: a band of coved arcs in the charcoal, then a straight join. The band is the panel's own colour and the next
   section tucks 2 px up over its foot, so no fractional row can show as a seam at 125% scaling */
.e-cove{display:block;position:relative;height:2.25rem;background:var(--cvarcs) 50% 100%/4.5rem 100% repeat-x,var(--dark)}
.hero .e-cove{z-index:3}
section:has(> .e-cove) + section{position:relative;z-index:4;margin-top:-2px}
section:has(> .e-cove) + section:not(.mist):not(.dark){background:#fff}

/* mark: their round logo on the hero photo, like a stamp */
.cvmark{position:absolute;right:var(--gut);top:.85rem;width:4.5rem;aspect-ratio:1;z-index:2;border-radius:50%;padding:.3rem;
  background:color-mix(in srgb,var(--dark) 80%,transparent);box-shadow:0 8px 20px rgba(0,0,0,.4);pointer-events:none}
.cvmark img{display:block;width:100%;height:100%;object-fit:contain}

/* bullets and why points: the ring */
.ilist li::before{top:.3rem;width:.95rem;height:.95rem;border-radius:0;transform:none;background:var(--accent-ink);
  -webkit-mask:var(--cvring) center/100% 100% no-repeat;mask:var(--cvring) center/100% 100% no-repeat}
.dark .ilist li::before{background:var(--accent)}
.why li::before{top:1.35rem;width:1.9rem;height:1.9rem;border-radius:0;transform:none;background:var(--accent-ink);
  -webkit-mask:var(--cvring) center/100% 100% no-repeat;mask:var(--cvring) center/100% 100% no-repeat}

/* steps: the number inside the ring */
.steps li::before{background:none;color:var(--accent);font:700 1.375rem/1 var(--head);padding-top:.15rem;z-index:1}
.steps li::after{content:"";position:absolute;left:0;top:0;width:3rem;height:3rem;background:var(--accent);
  -webkit-mask:var(--cvring) center/100% 100% no-repeat;mask:var(--cvring) center/100% 100% no-repeat}
section:not(.dark) .steps li::before{color:var(--accent-ink)}
section:not(.dark) .steps li::after{background:var(--accent-ink)}

/* owner: the photo in a circle inside the logo's ring, the name along the open foot */
.cvown{position:relative;width:100%;max-width:21rem;aspect-ratio:1;margin:0 auto var(--s4);color:#fff}
.cvpic{position:absolute;inset:11%;border-radius:50%;overflow:hidden;background:var(--dark-2)}
.cvpic img,.cvpic .ownph{display:grid;width:100%;height:100%;aspect-ratio:1;object-fit:cover;border:0;border-radius:0;transform:none;box-shadow:none}
.cvpic .ownph{padding:0 18%;font-size:.9375rem;background:radial-gradient(circle at 50% 40%,var(--dark-2),var(--dark-3) 75%)}
.cvpic .ownph svg{width:3.5rem;height:3.5rem}
.cvframe{position:absolute;inset:0;width:100%;height:100%;overflow:visible;fill:currentColor}
.cvframe text{font:700 7px var(--head);letter-spacing:.42em;fill:currentColor}
section:not(.dark) .cvown{color:var(--dark)}

/* phones: photo first, so the driveway shows instead of sky above a text scrim; desktop keeps it full bleed */
@media (max-width:879px){
  .hero.home,.hero.svc:not(.noimg){display:block;min-height:0}
  .hero-media{position:relative;inset:auto}
  .hero-media::after{background:linear-gradient(180deg,transparent 70%,color-mix(in srgb,var(--dark) 55%,transparent) 100%)}
  .hero-media img{display:block;aspect-ratio:16/10;height:auto;max-height:34svh}
  .hero.home .hero-text,.hero.svc:not(.noimg) .hero-text{padding-top:var(--s4)}
  .hero.home .slogan{font-size:clamp(1.875rem,8.6vw,2.75rem);letter-spacing:.02em}
}

/* their email address is long: keep it on one line in the contact box on phones */
.cmail{font-size:min(1rem,3.75vw)}

.chips li,.gbadge,.faq details{border-radius:.25rem}
.door img,.jcard img,.prail img,.incl img,.pics img,.map{border-radius:.25rem}

@media (min-width:880px){
  .slogan{font-size:clamp(2.25rem,min(4.4vw,7.5vh),4.125rem)}
  .e-cove{height:3rem;background-size:6rem 100%,auto}
  .cvmark{top:auto;bottom:3.75rem;right:max(var(--gut),calc((100vw - 72.5rem)/2));width:7.5rem}
  .steps li::after{left:0;top:0}
  .cvown{max-width:24rem;margin:0}
}

:root{--dark:#24282b;--dark-2:#30353a;--dark-3:#1a1d1f;--accent:#ec7aa6;--accent-ink:#9b2456;--mist:#f2f1ee;--line:#dfddd8;--head:"Josefin Sans","Century Gothic",Arial,sans-serif;--body:"Mulish",system-ui,sans-serif}
