/* =========================================================================
   LEAD GROUP — DESIGN SYSTEM  (V1 "Cinematic Duotone": gold on near-black)
   ========================================================================= */
:root{
  --bg:#fafaf8;            /* paper */
  --bg2:#f2f1ec;           /* alternating section */
  --surface:#ffffff;       /* cards / panels */
  --surface2:#f4f3ee;      /* raised */
  --ink:#14161a;           /* headings */
  --text:#3c4148;          /* body */
  --muted:#5f656d;         /* secondary */
  --line:rgba(20,22,26,.13);
  --line-strong:rgba(20,22,26,.22);
  --accent:#2f6f6a;        /* teal */
  --accent-light:#3d8a83;
  --accent-ink:#ffffff;    /* text on teal */

  /* One family throughout. Playfair Display is banned (Solar Surveys' identity)
     and Anton was the display face that read as cheap. */
  --font-display:'Montserrat',system-ui,sans-serif;
  --font-serif:'Montserrat',system-ui,sans-serif;
  --font-head:'Montserrat',system-ui,sans-serif;
  --font-body:'Montserrat',system-ui,sans-serif;
  --font-mono:'DM Mono',ui-monospace,monospace;
  --glow:rgba(47,111,106,.16);

  /* The hero stays dark whatever the page does. */
  --hero:#0f1413;

  --maxw:1240px;
  --radius:0;              /* square, per the agreed button style */
  --ease:cubic-bezier(.165,.84,.44,1);
  --t:.4s var(--ease);
}

*{margin:0;padding:0;box-sizing:border-box}
a{text-decoration:none;color:inherit}
html{scroll-behavior:smooth;scroll-padding-top:90px;-webkit-text-size-adjust:100%}
body{font-family:var(--font-body);background:var(--bg);color:var(--text);line-height:1.7;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{display:block;max-width:100%}
::selection{background:var(--accent);color:var(--accent-ink)}
.mono{font-family:var(--font-mono)}

/* ---------- TYPE ---------- */
h1,h3,h4{color:var(--ink);line-height:1.08;letter-spacing:-.02em;font-weight:800}
h2{font-family:var(--font-display);color:var(--ink);font-weight:800;font-size:clamp(2.1rem,3.8vw,3.4rem);line-height:1.08;letter-spacing:-.01em;margin-bottom:1rem}
h2 .gi{font-weight:800;color:var(--accent)}
/* numbered drafting kicker */
.kick{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;color:var(--accent);display:inline-flex;align-items:center;gap:.7rem;margin-bottom:1.2rem}
.kick .no{color:var(--ink);font-weight:500}
.kick::after{content:"";flex:1;min-width:2.5rem;height:1px;background:var(--line)}
/* dimension divider between sections */
.dimdiv{display:flex;align-items:center;gap:1rem;color:var(--muted);font-family:var(--font-mono);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;padding:0 3vw;max-width:var(--maxw);margin:0 auto}
.dimdiv::before,.dimdiv::after{content:"";height:1px;background:var(--line);flex:1}
.dimdiv .t{color:var(--accent)}
h3{font-family:var(--font-body);font-weight:600;font-size:1.22rem;letter-spacing:-.01em}
/* Card and step sub-headings. These were h4 under an h2, which skips a level for anyone navigating by heading; the tag is now h3 and this rule keeps the original weight and size so nothing moves visually. */
.sh{font-family:var(--font-body);font-weight:800;font-size:1rem;line-height:1.08;letter-spacing:-.02em}
p{color:var(--text);font-size:1.02rem;line-height:1.75;margin-bottom:1rem;max-width:68ch}
strong{color:var(--ink);font-weight:600}
.lede{font-size:1.12rem;line-height:1.7;color:var(--text);max-width:62ch}
.text-muted{color:var(--muted)}
.eyebrow{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--accent);display:inline-flex;align-items:center;gap:.7rem;margin-bottom:1.1rem}
.eyebrow::before{content:"";width:2rem;height:1px;background:var(--accent)}
.eyebrow.center{justify-content:center}

/* ---------- LAYOUT ---------- */
.container{max-width:var(--maxw);margin:0 auto;padding:0 3vw}
.narrow{max-width:860px;margin:0 auto;padding:0 3vw}
.sec{padding:6.5rem 0;position:relative}
.sec.alt{background:var(--bg2)}
.sec-head{max-width:740px;margin-bottom:3rem}
.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}
.grid{display:grid;gap:1.2rem}
.two{display:grid;grid-template-columns:1.05fr .95fr;gap:3rem;align-items:start}

/* ---------- BUTTONS ---------- */
.btn{display:inline-flex;align-items:center;gap:.55rem;font-family:var(--font-body);font-weight:600;font-size:.92rem;padding:.95rem 1.8rem;border-radius:var(--radius);border:1px solid var(--line-strong);color:var(--ink);transition:var(--t);cursor:pointer;white-space:nowrap}
.btn:hover{border-color:var(--accent);color:var(--accent)}
.btn.s{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
.btn.s:hover{background:var(--accent-light);color:var(--accent-ink);transform:translateY(-2px)}
.btnrow{display:flex;gap:1rem;flex-wrap:wrap}

/* ---------- NAV ---------- */
.navbar{position:fixed;top:0;left:0;right:0;z-index:1000;background:rgba(250,250,248,.82);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-bottom:1px solid transparent;transition:background .3s,border-color .3s}
.navbar.scrolled{background:rgba(250,250,248,.97);border-bottom-color:var(--line)}
.nav-inner{max-width:1320px;margin:0 auto;padding:0 3vw;height:70px;display:flex;align-items:center;justify-content:space-between}
.brand{display:inline-flex;align-items:center;gap:.6rem;text-decoration:none}
.brand-mark{height:30px;width:auto;display:block;transition:transform .45s cubic-bezier(.2,.8,.2,1),filter .45s}
.brand:hover .brand-mark{transform:translateY(-2px)}
.brand-word{font-family:var(--font-head);font-weight:900;font-size:1.22rem;color:#fff;letter-spacing:.01em;line-height:1;text-transform:uppercase}
.brand-word .a{color:var(--accent)}
.nav-links{display:flex;align-items:center;gap:.3rem;list-style:none}
.nav-links>li>a{font-size:.88rem;font-weight:500;color:var(--text);padding:.5rem .8rem;border-radius:var(--radius);display:inline-flex;align-items:center;gap:.35rem;transition:color .2s}
.nav-links>li>a:hover{color:var(--accent)}
.nav-cta{margin-left:.5rem}
.has-dd{position:relative}
.has-dd>a::after{content:"";width:5px;height:5px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg) translateY(-1px);opacity:.6}
.dd{position:absolute;top:calc(100% + 8px);left:0;min-width:300px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 24px 60px rgba(0,0,0,.5);padding:.5rem;opacity:0;visibility:hidden;transform:translateY(8px);transition:.25s;list-style:none}
.has-dd:hover .dd,.has-dd.open .dd{opacity:1;visibility:visible;transform:translateY(0)}
.dd a{display:block;padding:.55rem .8rem;font-size:.88rem;font-weight:500;color:var(--ink);border-radius:var(--radius);transition:.18s}
.dd a:hover{background:var(--surface2);color:var(--accent)}
.dd a span{display:block;font-size:.74rem;font-weight:400;color:var(--muted);margin-top:1px}
.nav-mob{display:none}
.burger{display:none;background:none;border:none;color:#fff;font-size:1.5rem;line-height:1;cursor:pointer;padding:.3rem .55rem;border-radius:var(--radius);transition:color .2s,background .2s}
.burger:hover,.burger.is-open{color:var(--accent)}
body.nav-locked{overflow:hidden}

/* ---------- HOME HERO (video + duotone + giant type) ---------- */
.hero{position:relative;min-height:100vh;min-height:100svh;overflow:hidden;display:flex;flex-direction:column;justify-content:flex-end}
.herovid,.heroposter{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.herovid{filter:grayscale(.35) contrast(1.08) brightness(.62)}
.duo{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(15,20,19,.78),rgba(15,20,19,.34) 30%,rgba(15,20,19,.5) 62%,var(--bg))}
.duo2{position:absolute;inset:0;z-index:1;background:radial-gradient(120% 90% at 70% 18%,rgba(47,111,106,.22),transparent 58%)}
.hero-inner{position:relative;z-index:4;width:100%;max-width:1320px;margin:0 auto;padding:8rem 3vw 2.6rem}
.hero-eyebrow2{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;color:var(--accent);display:inline-flex;align-items:center;gap:.7rem;margin-bottom:1.3rem}
.hero-eyebrow2::before{content:"";width:2rem;height:1px;background:var(--accent)}
.hero-giant{font-family:var(--font-display);text-transform:uppercase;line-height:.88;font-size:clamp(2.5rem,8.5vw,7.4rem);color:#fff;letter-spacing:.005em;margin-bottom:1.5rem}
.hero-giant .o{color:transparent;-webkit-text-stroke:1.4px rgba(255,255,255,.78)}
.hero-sub{max-width:54ch;color:rgba(255,255,255,.85);font-size:1.05rem;line-height:1.6;margin-bottom:1.9rem}
.hero-sub strong{color:#fff;font-weight:600;display:block;font-size:1.18rem;margin-bottom:.4rem}
.hero-actions{display:flex;gap:1rem;flex-wrap:wrap;margin-bottom:2.2rem}
.hero-strip{display:flex;justify-content:space-between;gap:.8rem 2rem;flex-wrap:wrap;border-top:1px solid rgba(255,255,255,.16);padding-top:1.3rem;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.62)}

/* ---------- PAGE HERO (inner pages) ---------- */
.phero{position:relative;padding:9rem 0 4rem;background:var(--bg2);border-bottom:1px solid var(--line);overflow:hidden}
.phero::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(201,168,76,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(201,168,76,.04) 1px,transparent 1px);background-size:48px 48px;mask-image:radial-gradient(ellipse 70% 90% at 100% 0%,#000,transparent 70%);-webkit-mask-image:radial-gradient(ellipse 70% 90% at 100% 0%,#000,transparent 70%)}
.phero .container{position:relative}
/* Image-backed page hero. Service and topic pages opened with a text-only band
   on every one of 161 pages, which read as the same dark strip repeated before
   the content started. Where a relevant project photograph exists the hero
   carries it, darkened enough to hold white text at AA contrast. */
.phero.has-img{background:#0e1014;border-bottom:0}
.phero.has-img .pbg{position:absolute;inset:0;z-index:0}
.phero.has-img .pbg img{width:100%;height:100%;object-fit:cover;opacity:.42}
.phero.has-img::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(14,16,20,.55) 0%,rgba(14,16,20,.72) 55%,rgba(14,16,20,.92) 100%)}
.phero.has-img .container{z-index:2}
.phero.has-img h1,.phero.has-img .lede,.phero.has-img .crumb,.phero.has-img .crumb a{color:#fff}
.phero.has-img .lede{color:rgba(255,255,255,.86)}
.phero.has-img .crumb a{opacity:.8}
.phero.has-img::before{opacity:.35}
.phero h1{font-family:var(--font-head);font-weight:900;font-size:clamp(2.4rem,4.6vw,4rem);max-width:18ch;margin-bottom:1.2rem}
.crumb{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:1.4rem}
.crumb a:hover{color:var(--accent)}

/* ---------- CARDS ---------- */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:1.2rem}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:1.8rem;transition:transform .3s,border-color .3s,background .3s;position:relative;overflow:hidden;display:block}
.card:hover{transform:translateY(-4px);border-color:var(--line-strong);background:var(--surface2)}
.card .num{font-family:var(--font-mono);font-size:.74rem;color:var(--accent);letter-spacing:.05em}
.card h3{margin:.6rem 0 .5rem;color:var(--ink)}
.card p{color:var(--muted);font-size:.95rem;line-height:1.6;margin:0}
.card .go{display:inline-block;margin-top:1rem;font-size:.85rem;color:var(--ink);font-weight:500}
.card:hover .go{color:var(--accent)}
.card.feat::after{content:"";position:absolute;top:0;left:0;height:3px;width:0;background:var(--accent);transition:width .45s var(--ease)}
.card.feat:hover::after{width:100%}

/* sub-service chips list */
.subs{display:grid;grid-template-columns:repeat(2,1fr);gap:.2rem 2rem;margin-top:1.5rem}
.subs li{list-style:none;border-bottom:1px solid var(--line);padding:.85rem 0;display:flex;justify-content:space-between;gap:1rem;color:var(--text);font-size:.97rem}
.subs li::after{content:"\2197";color:var(--accent);opacity:.7}

/* ---------- PREMIUM: cursor glow + shimmer border (driven by main.js LERP) ---------- */
.premium-glow{position:relative;overflow:hidden}
.premium-glow::before{content:"";position:absolute;top:var(--mouse-y,50%);left:var(--mouse-x,50%);width:420px;height:420px;transform:translate(-50%,-50%);background:radial-gradient(circle,var(--glow),transparent 68%);opacity:0;transition:opacity .45s var(--ease);pointer-events:none;z-index:1}
.premium-glow:hover::before{opacity:1}
.premium-shimmer{position:relative}
.premium-shimmer::after{content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;background:linear-gradient(130deg,transparent 20%,var(--accent),transparent 80%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:0;transition:opacity .45s var(--ease);pointer-events:none}
.premium-shimmer:hover::after{opacity:.7}
.btn-magnetic{transform:translate(var(--mx,0),var(--my,0))}

/* ---------- CAPABILITY TAG STRIP ---------- */
.tagstrip{display:flex;flex-wrap:wrap;gap:.55rem}
.tag{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text);border:1px solid var(--line);border-radius:100px;padding:.5rem 1rem;transition:.25s}
.tag:hover{border-color:var(--accent);color:var(--accent)}

/* ---------- IMAGE-BACKED BENTO ---------- */
.bento{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:230px;gap:1rem;grid-auto-flow:dense}
.bcard{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);display:flex;flex-direction:column;justify-content:flex-end;padding:1.6rem;isolation:isolate;box-shadow:0 10px 34px rgba(0,0,0,.32);transition:transform .35s var(--ease),border-color .35s,box-shadow .35s}
.bcard:hover{transform:translateY(-5px);border-color:var(--line-strong)}
.bcard .bg{position:absolute;inset:0;z-index:-2}
.bcard .bg img{width:100%;height:100%;object-fit:cover;filter:grayscale(.15) contrast(1.1) brightness(.66) saturate(1.05);transition:transform .8s var(--ease),filter .5s}
.bcard:hover{box-shadow:0 30px 70px rgba(0,0,0,.55)}
.bcard:hover .bg img{transform:scale(1.07);filter:grayscale(0) contrast(1.12) brightness(.78) saturate(1.1)}
.bcard::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(0deg,rgba(8,9,12,.95) 0%,rgba(8,9,12,.5) 42%,rgba(8,9,12,.12) 80%,rgba(8,9,12,.3) 100%)}
.bcard .k{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:.5rem}
.bcard h3{color:#fff;font-size:1.3rem;margin-bottom:.45rem}
.bcard p{color:rgba(255,255,255,.78);font-size:.92rem;line-height:1.55;margin:0;max-width:42ch}
.bcard .go{margin-top:1rem;font-size:.84rem;color:#fff;font-weight:500;display:inline-flex;gap:.4rem}
.bcard:hover .go{color:var(--accent)}
.bcard.lg{grid-column:span 2;grid-row:span 2}
.bcard.lg h3{font-size:1.9rem}
.bcard.lg p{font-size:1rem;max-width:48ch}
.bcard.tall{grid-row:span 2}
.bcard .topk{position:absolute;top:1.3rem;left:1.6rem;z-index:1;font-family:var(--font-mono);font-size:.72rem;color:rgba(255,255,255,.6)}
/* drawing-sheet title block on cards (Lead Group signature) */
.bcard .sheet{position:absolute;top:1.1rem;left:1.5rem;right:1.5rem;z-index:1;display:flex;align-items:center;gap:.6rem;font-family:var(--font-mono);font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.7)}
.bcard .sheet .ix{color:var(--accent)}
.bcard .sheet .rule{flex:1;height:1px;background:rgba(255,255,255,.22)}
.bcard .tick{position:absolute;width:10px;height:10px;z-index:1;pointer-events:none}
.bcard .tick.br{bottom:1.1rem;right:1.5rem;border-bottom:1.5px solid var(--accent);border-right:1.5px solid var(--accent)}
.scard .tick{position:absolute;top:1rem;right:1rem;width:9px;height:9px;border-top:1.5px solid var(--accent);border-right:1.5px solid var(--accent);z-index:1}
/* blueprint-grid section texture */
.sec.blueprint::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(201,168,76,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(201,168,76,.04) 1px,transparent 1px);background-size:46px 46px;mask-image:radial-gradient(ellipse 85% 70% at 50% 0%,#000,transparent 78%);-webkit-mask-image:radial-gradient(ellipse 85% 70% at 50% 0%,#000,transparent 78%);pointer-events:none}
.sec.blueprint>*{position:relative}

/* ---------- IMAGE-BACKED SECTOR CARDS ---------- */
.sgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}
.scard{position:relative;aspect-ratio:3/4;overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);display:flex;align-items:flex-end;padding:1.4rem;isolation:isolate;transition:transform .35s var(--ease)}
.scard:hover{transform:translateY(-5px);box-shadow:0 26px 60px rgba(0,0,0,.5)}
.scard img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;filter:grayscale(.2) contrast(1.08) brightness(.62) saturate(1.05);transition:transform .8s var(--ease),filter .5s}
.scard:hover img{transform:scale(1.07);filter:grayscale(0) contrast(1.1) brightness(.74) saturate(1.1)}
.scard::after{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(0deg,rgba(8,9,12,.92),rgba(8,9,12,.2) 60%)}
.scard .k{font-family:var(--font-mono);font-size:.64rem;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:.4rem}
.scard h4{color:#fff;font-size:1.15rem;margin-bottom:.35rem}
.scard p{color:rgba(255,255,255,.72);font-size:.85rem;line-height:1.5;margin:0}

/* ---------- RICH STAT BLOCK ---------- */
.statblock{display:grid;grid-template-columns:repeat(4,1fr);gap:2rem}
.statblock .item{border-top:2px solid var(--line);padding-top:1.3rem;transition:border-color .3s}
.statblock .item:hover{border-color:var(--accent)}
.statblock .n{font-family:var(--font-mono);font-size:clamp(2.2rem,3.4vw,3rem);color:var(--accent);letter-spacing:-.02em;line-height:1}
.statblock .k{color:var(--ink);font-weight:600;font-size:1.02rem;margin:.6rem 0 .35rem}
.statblock .d{color:var(--muted);font-size:.9rem;line-height:1.5}

/* ---------- WORK GRID ---------- */
.work{display:grid;grid-template-columns:repeat(4,1fr);gap:1rem}
.wcard{position:relative;aspect-ratio:3/4;overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);display:block}
.wcard img{width:100%;height:100%;object-fit:cover;filter:grayscale(.06) contrast(1.03) brightness(1) saturate(1.02);transition:transform .8s var(--ease),filter .5s}
.wcard:hover img{transform:scale(1.07);filter:grayscale(0) contrast(1.1) brightness(1) saturate(1.1)}
.wcard:hover{box-shadow:0 26px 60px rgba(0,0,0,.5)}
.wcard::after{content:"";position:absolute;inset:0;background:linear-gradient(0deg,rgba(0,0,0,.85),transparent 50%)}
.wcard .m{position:absolute;left:0;right:0;bottom:0;padding:1rem;z-index:2}
.wcard .m .k{font-family:var(--font-mono);font-size:.64rem;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);display:block;margin-bottom:.3rem}
.wcard .m .t{color:#fff;font-weight:600;font-size:.95rem;line-height:1.25}
.wcard .corner{position:absolute;top:.8rem;right:.8rem;width:8px;height:8px;border-top:1.5px solid var(--accent);border-right:1.5px solid var(--accent);z-index:2}
/* Portfolio sector image. Sources are a mix of 16:9 and 4:3, so a fixed
   aspect-ratio plus object-fit keeps the grid even and holds the space.
   height:auto is required, not optional: the width/height attributes each img
   carries (for CLS) set a specified height, and aspect-ratio is ignored unless
   the other dimension is auto. Without it these render at full natural height. */
.secimg{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;display:block;filter:grayscale(.06) contrast(1.02) brightness(1)}

/* ---------- BRAND LOGO ----------
   Painted with mask-image so one file serves every colour: the element is
   filled with currentColor and the SVG defines the shape. That means the logo
   follows the palette (white on the dark hero, ink on a light surface) with no
   second export, and the 35KB file is fetched once and cached rather than
   inlined into 222 pages.
   Ratios come from the artwork: horizontal 3.40:1, lockup 2.78:1. */
.brand-logo{display:block;width:102px;height:30px;background-color:currentColor;
  -webkit-mask:url(/images/logo/horizontal.svg) left center/contain no-repeat;
  mask:url(/images/logo/horizontal.svg) left center/contain no-repeat}
.foot-logo{display:block;width:170px;height:61px;background-color:currentColor;
  -webkit-mask:url(/images/logo/lockup.svg) left center/contain no-repeat;
  mask:url(/images/logo/lockup.svg) left center/contain no-repeat}
.brand{display:inline-flex;align-items:center;color:var(--ink)}
/* Browsers without mask support would show a solid block, which is worse than
   nothing, so the fill is only applied where mask actually works. */
@supports not ((-webkit-mask: url(#a)) or (mask: url(#a))){
  .brand-logo,.foot-logo{background-color:transparent}
}
@media(max-width:640px){.brand-logo{width:88px;height:26px}}

/* ---------- COOKIE CONSENT ----------
   js/cookie-consent.js injects this and carries no styles of its own, so with
   no rules here it rendered as unstyled text and default buttons on all 221
   pages. The JS appends to <body>, hence position:fixed rather than a flow
   position, and toggles .is-visible, so the hidden state must be the default.
   Removal is on a 200ms timer in the JS; the transition matches it. */
.lg-cookie-banner{position:fixed;right:1.25rem;bottom:1.25rem;z-index:9999;width:min(24rem,calc(100vw - 2.5rem));
  background:var(--bg-elev,#16181c);border:1px solid var(--line);border-radius:var(--radius);
  padding:1.35rem 1.35rem 1.15rem;box-shadow:0 24px 60px rgba(0,0,0,.55);
  opacity:0;transform:translateY(12px);transition:opacity .2s var(--ease,ease),transform .2s var(--ease,ease)}
.lg-cookie-banner.is-visible{opacity:1;transform:none}
.lg-cookie-label{font-family:var(--font-mono);font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin:0 0 .5rem}
.lg-cookie-body{color:var(--muted);font-size:.86rem;line-height:1.55;margin:0 0 1.1rem}
.lg-cookie-actions{display:flex;gap:.6rem}
.lg-cookie-btn{flex:1;cursor:pointer;font:inherit;font-size:.83rem;font-weight:600;
  padding:.6rem .9rem;border-radius:calc(var(--radius) / 1.6);border:1px solid var(--line);
  transition:background .25s,color .25s,border-color .25s}
.lg-cookie-btn-primary{background:var(--accent);border-color:var(--accent);color:#14161a}
.lg-cookie-btn-primary:hover{filter:brightness(1.08)}
.lg-cookie-btn-secondary{background:transparent;color:var(--text)}
.lg-cookie-btn-secondary:hover{border-color:var(--accent);color:var(--ink)}
.lg-cookie-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.lg-cookie-link{display:inline-block;margin-top:.9rem;font-size:.75rem;color:var(--muted);text-decoration:underline}
.lg-cookie-link:hover{color:var(--accent)}
/* Slim full-width strip on small screens, as the script's own notes describe. */
@media (max-width:560px){
  .lg-cookie-banner{right:0;left:0;bottom:0;width:auto;border-radius:0;border-left:0;border-right:0;border-bottom:0;padding:1.1rem 1.15rem}
}
@media (prefers-reduced-motion:reduce){
  .lg-cookie-banner{transition:none;transform:none}
}

/* Hero brand line. Uses the eyebrow slot but drops the uppercase: a tagline in
   letterspaced caps reads as a label, and this is a sentence. */
.hero-tagline{text-transform:none;letter-spacing:.02em;font-size:.95rem;font-family:var(--font-body)}
/* Brand tagline. Sits with the wordmark, which is where a brand line belongs.
   Sentence case on purpose: Title Case reads corporate and dated against the
   light editorial direction. The hero keeps its own proposition line
   ("Designed, calculated, signed off.") - that says what you get, this says
   who we are, and they do different jobs. */
.ftag{margin-top:.55rem;font-size:.9rem;line-height:1.4;color:var(--ink);letter-spacing:.01em}
.tagline-lead{font-family:var(--font-display,inherit);font-size:clamp(1.5rem,3.2vw,2.1rem);line-height:1.25;color:var(--ink);margin-bottom:1.4rem;max-width:20ch}
.tagline-lead::after{content:"";display:block;width:46px;height:2px;background:var(--accent);margin-top:1.1rem}
.ftag::after{content:"";display:block;width:34px;height:1px;background:var(--accent);margin-top:.7rem;opacity:.8}
/* Testimonials. Only rendered when a real, consented quote exists. */
.tgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:1.6rem;margin-top:2.4rem}
.tcard{margin:0;border:1px solid var(--line);border-radius:var(--radius);padding:1.8rem;background:rgba(20,22,26,.03)}
.tcard blockquote{margin:0;border:0;padding:0}
.tcard blockquote p{color:var(--ink);font-size:1.04rem;line-height:1.6}
.tcard blockquote p::before{content:"\201C";color:var(--accent);font-size:1.6em;line-height:0;vertical-align:-.28em;margin-right:.12em}
.tcard blockquote p::after{content:"\201D";color:var(--accent);font-size:1.6em;line-height:0;vertical-align:-.28em;margin-left:.06em}
.tcard figcaption{margin-top:1.2rem;padding-top:1rem;border-top:1px solid var(--line)}
.tcard figcaption .k{display:block;font-family:var(--font-mono);font-size:.64rem;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:.35rem}
.tcard figcaption .t{color:var(--muted);font-size:.9rem}
/* Drawing line work. The SVGs carry stroke="currentColor", so colour comes from
   here and the same files work on the dark theme and on the light restyle. */
.dwggrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.6rem;margin-top:2.4rem}
.dwg{margin:0;border:1px solid var(--line);border-radius:var(--radius);padding:1.4rem 1.4rem 0;background:rgba(20,22,26,.03);overflow:hidden}
.dwg svg{width:100%;height:auto;aspect-ratio:4/3;display:block;color:var(--text);opacity:.9;transition:opacity .4s,color .4s}
.dwg:hover svg{opacity:1;color:var(--accent)}
.dwg figcaption{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding:1rem 0;border-top:1px solid var(--line);margin-top:1.2rem}
/* Case study gallery. height:auto here for the same reason as .secimg above. */
.gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.2rem;margin-top:2.4rem}
.gcell{margin:0;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.gcell img{width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;display:block;filter:grayscale(.06) contrast(1.02) brightness(1);transition:transform .8s var(--ease),filter .5s}
.gcell:hover img{transform:scale(1.04);filter:grayscale(0) contrast(1.08) brightness(1)}

/* ---------- ANSWER / FAQ / DIM ---------- */
.answer{background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--accent);padding:1.6rem 1.8rem;border-radius:0 var(--radius) var(--radius) 0}
.answer .q{color:var(--ink);font-weight:600;margin-bottom:.5rem}
.answer p{color:var(--text);font-size:.97rem;margin:0}
.dim{font-family:var(--font-mono);font-size:.8rem;color:var(--accent);display:flex;align-items:center;gap:.6rem;padding:.15rem 0}
.dim::before{content:"";width:1.5rem;height:1px;background:var(--accent);opacity:.7}
.faq details{border-bottom:1px solid var(--line);padding:1.3rem 0}
.faq summary{font-weight:600;color:var(--ink);cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:1rem;font-size:1.05rem}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--accent);font-size:1.4rem;line-height:1}
.faq details[open] summary::after{content:"\2212"}
.faq details p{margin:.9rem 0 0}

/* process steps */
.steps{counter-reset:s;display:grid;grid-template-columns:repeat(4,1fr);gap:1.2rem}
.step{border-top:2px solid var(--line);padding-top:1.2rem;position:relative}
.step::before{counter-increment:s;content:"0" counter(s);font-family:var(--font-mono);font-size:.8rem;color:var(--accent)}
.step h4{color:var(--ink);font-size:1.05rem;margin:.5rem 0 .4rem}
.step p{font-size:.92rem;color:var(--muted);margin:0}

/* ---------- STATS ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1.5rem;border-top:1px solid var(--line);padding-top:2.2rem}
.stats .n{font-family:var(--font-mono);font-size:clamp(1.8rem,3vw,2.6rem);color:var(--accent);letter-spacing:-.02em}
.stats .k{font-size:.82rem;color:var(--muted);margin-top:.3rem}

/* ---------- CTA BAND ---------- */
.ctaband{background:var(--surface);border:1px solid var(--line);border-top:2px solid var(--accent);border-radius:var(--radius);padding:3.6rem;text-align:center;position:relative;overflow:hidden}
.ctaband::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(201,168,76,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(201,168,76,.04) 1px,transparent 1px);background-size:44px 44px;opacity:.7}
.ctaband>*{position:relative}
.ctaband p{color:var(--muted);max-width:52ch;margin:0 auto 1.8rem}
.ctaband .btnrow{justify-content:center}

/* ---------- CONTACT FORM ---------- */
.form{display:grid;gap:1.1rem}
.field label{display:block;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);margin-bottom:.45rem}
.field input,.field textarea,.field select{width:100%;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:.85rem 1rem;color:var(--ink);font-family:var(--font-body);font-size:.97rem}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:var(--accent)}
.field textarea{min-height:140px;resize:vertical}
.f2{display:grid;grid-template-columns:1fr 1fr;gap:1.1rem}

/* ---------- FOOTER ---------- */
footer{background:#08090c;border-top:1px solid var(--line);padding:4rem 0 2rem;color:var(--muted)}
.fg{display:grid;grid-template-columns:1.7fr repeat(4,1fr);gap:2.4rem}
footer h2{color:var(--ink);font-family:var(--font-display);font-weight:800;font-size:.76rem;text-transform:uppercase;letter-spacing:.14em;line-height:1.2;margin-bottom:1rem}
footer a{color:var(--muted);font-size:.9rem;line-height:2;transition:color .2s}
footer a:hover{color:var(--accent)}
.foot-mark{display:block;height:46px;width:auto;margin-bottom:1rem;opacity:.95}
.fwm{font-family:var(--font-head);font-weight:900;font-size:1.4rem;color:#fff;text-transform:uppercase}.fwm .a{color:var(--accent)}
.floc{border-top:1px solid var(--line);margin-top:2.6rem;padding-top:1.4rem;font-size:.82rem;color:var(--muted)}
.fbot{border-top:1px solid var(--line);margin-top:1.4rem;padding-top:1.4rem;font-size:.8rem;display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem}

/* ---------- REVEAL ---------- */
.reveal{transition:opacity .8s var(--ease),transform .8s var(--ease);will-change:opacity,transform}
.js .reveal{opacity:0;transform:translateY(26px)}
.reveal.visible{opacity:1;transform:none}
.d1{transition-delay:.08s}.d2{transition-delay:.16s}.d3{transition-delay:.24s}.d4{transition-delay:.32s}
@media(prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none}.herovid{display:none}}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Visually hidden, still in the accessibility tree and the document outline. Used for section headings that exist structurally but are not drawn. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.skip{position:absolute;left:-999px}.skip:focus{left:1rem;top:1rem;z-index:2000;background:var(--accent);color:var(--accent-ink);padding:.6rem 1rem;border-radius:var(--radius)}

/* ---------- PREMIUM INTERACTION LAYER ---------- */
.scroll-progress{position:fixed;top:0;left:0;height:2px;width:0;background:linear-gradient(90deg,var(--accent),var(--accent-light));z-index:2000;box-shadow:0 0 10px rgba(201,168,76,.5)}
.back-to-top{position:fixed;right:1.5rem;bottom:1.5rem;width:48px;height:48px;border-radius:50%;background:var(--surface);border:1px solid var(--line-strong);color:var(--ink);font-size:1.15rem;cursor:pointer;opacity:0;visibility:hidden;transform:translateY(12px);transition:var(--t);z-index:900;display:grid;place-items:center;box-shadow:var(--shadow-card)}
.back-to-top.show{opacity:1;visibility:visible;transform:none}
.back-to-top:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-3px)}
/* value-prop trust strip */
.trust-strip{background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.trust-strip .row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1.2rem 2rem;padding:1.5rem 0}
.trust-strip .item{display:flex;align-items:center;gap:.6rem;font-family:var(--font-mono);font-size:.76rem;letter-spacing:.07em;text-transform:uppercase;color:var(--text)}
.trust-strip .item b{color:var(--accent);font-weight:500}
.trust-strip .item .tick{color:var(--accent)}
/* cost table */
.costgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:1rem;margin-top:2rem}
.costcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:1.6rem 1.8rem;transition:var(--t);position:relative;overflow:hidden}
.costcard:hover{border-color:var(--accent);transform:translateY(-3px);box-shadow:var(--shadow-card)}
.costcard .svc{font-weight:600;color:var(--ink);font-size:1.08rem}
.costcard .price{font-family:var(--font-mono);font-size:1.7rem;color:var(--accent);margin:.5rem 0;letter-spacing:-.02em}
.costcard .note{color:var(--muted);font-size:.9rem;line-height:1.55;margin:0}
/* extension cost calculator */
.calc{background:var(--surface);border:1px solid var(--line);border-top:2px solid var(--accent);border-radius:var(--radius);padding:2.2rem;max-width:640px;margin:0 auto}
.calc h3{color:var(--ink);margin-bottom:.4rem}
.calc .field{margin:1.1rem 0}
.calc label{display:block;font-family:var(--font-mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:.55rem}
.calc select,.calc input[type=range]{width:100%}
.calc select{background:var(--bg2);border:1px solid var(--line);border-radius:var(--radius);padding:.85rem 1rem;color:var(--ink);font-family:var(--font-body);font-size:1rem}
.calc input[type=range]{accent-color:var(--accent);height:6px}
.calc .rangeval{font-family:var(--font-mono);color:var(--accent);font-size:.95rem;margin-top:.4rem}
.calc .result{margin-top:1.8rem;border-top:1px solid var(--line);padding-top:1.6rem;text-align:center}
.calc .result .lab{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.calc .result .amt{font-family:var(--font-display);font-size:clamp(2.4rem,6vw,3.6rem);color:#fff;line-height:1;margin:.4rem 0}
.calc .result .amt span{color:var(--accent)}
.calc .result .sub{color:var(--muted);font-size:.88rem;margin:0}
.calc .cta-row{margin-top:1.6rem;text-align:center}
/* article readability */
.article h2{margin-top:2.4rem;font-size:clamp(1.6rem,3vw,2.2rem)}
.article p{font-size:1.08rem;line-height:1.8}
.article .lede{font-size:1.25rem;color:var(--ink)}

/* ---------- RESPONSIVE ---------- */
/* nav collapses to drawer before the horizontal menu gets cramped on tablets */
@media(max-width:1180px){
  /* Above the drawer. The burger spans y58 to y92 and the drawer opens at
     y70, so they overlap by 22px; the drawer comes later in the DOM and was
     capturing the tap, which meant the menu could be opened and not closed. */
  .burger{display:inline-block;position:relative;z-index:3}
  .nav-links{position:fixed;top:70px;left:0;right:0;background:var(--bg2);border-bottom:1px solid var(--line);flex-direction:column;align-items:stretch;gap:0;padding:.6rem 1rem 1.4rem;transform:translateY(-12px);opacity:0;visibility:hidden;transition:transform .28s,opacity .28s,visibility .28s;max-height:calc(100dvh - 70px);overflow-y:auto;-webkit-overflow-scrolling:touch}
  .nav-links.open{transform:none;opacity:1;visibility:visible}

  .nav-links>li{width:100%}
  .nav-links>li>a{padding:.9rem .6rem;border-bottom:1px solid var(--line);font-size:1rem;justify-content:space-between}
  .has-dd>a::after{margin-left:auto;transition:transform .25s}
  .has-dd.open>a::after{transform:rotate(45deg) translateY(2px) scaleY(-1)}
  .nav-cta{margin:1rem 0 0}.nav-cta .btn{width:100%;justify-content:center;padding:.9rem 1rem}
  .dd{position:static;opacity:1;visibility:visible;transform:none;box-shadow:none;border:none;background:transparent;padding:0 0 0 1rem;min-width:0;max-height:0;overflow:hidden;transition:max-height .3s}
  .has-dd.open .dd{max-height:760px;padding-bottom:.4rem}
}
@media(max-width:1024px){.fg{grid-template-columns:1fr 1fr 1fr}.two{grid-template-columns:1fr}.steps{grid-template-columns:1fr 1fr}.bento{grid-template-columns:repeat(2,1fr)}.bcard.lg{grid-column:span 2}.sgrid{grid-template-columns:1fr 1fr}.statblock{grid-template-columns:1fr 1fr;gap:1.5rem}.costgrid{grid-template-columns:1fr}}
@media(max-width:768px){
  .sec{padding:4.5rem 0}
  .cards,.work,.stats,.subs,.statblock{grid-template-columns:1fr}
  .bento{grid-template-columns:1fr;grid-auto-rows:200px}
  .bcard.lg,.bcard.tall{grid-column:auto;grid-row:auto}
  .sgrid{grid-template-columns:1fr 1fr}
  .work{grid-template-columns:1fr 1fr}
  .f2{grid-template-columns:1fr}
  .fg{grid-template-columns:1fr 1fr}
  .hero-inner{padding:7rem 6vw 2rem}
  .hero-giant{font-size:clamp(2.2rem,11vw,4rem)}
  .hero-actions{flex-direction:column;align-items:stretch}
  .hero-actions .btn{width:100%;justify-content:center}
  .hero-strip{font-size:.62rem;gap:.6rem 1.2rem}
}
@media(max-width:420px){.work{grid-template-columns:1fr}.hero-corners{font-size:.58rem}}

/* ---------- MID-PAGE CTA ----------
   Lighter than .ctaband. Sits partway down long service and topic pages so the
   ask is not held back until after 1,000+ words. */
.midcta{padding:0;margin:3.5rem 0}
.midcta-in{display:flex;align-items:center;justify-content:space-between;gap:1.6rem;flex-wrap:wrap;
  background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:var(--radius);padding:1.5rem 1.8rem}
.midcta-in strong{color:var(--ink);display:block;margin-bottom:.3rem;font-family:var(--font-head)}
.midcta-in span{color:var(--muted);font-size:.93rem;line-height:1.6;display:block;max-width:62ch}
.midcta-act{display:flex;gap:.7rem;flex-shrink:0}
@media(max-width:760px){
  .midcta-in{flex-direction:column;align-items:flex-start;padding:1.3rem 1.4rem}
  .midcta-act{width:100%}
  .midcta-act .btn{flex:1;justify-content:center}
}

/* ---------- STICKY MOBILE CONTACT BAR ----------
   Most homeowner traffic arrives on a phone, where the nav CTA scrolls away
   and never comes back. Desktop keeps the nav button instead. */
.stickybar{display:none}
@media(max-width:820px){
  .stickybar{display:grid;grid-template-columns:1fr 1fr;position:fixed;left:0;right:0;bottom:0;z-index:60;
    background:rgba(14,15,18,.97);backdrop-filter:blur(12px);border-top:1px solid var(--line-strong)}
  .stickybar a{padding:.95rem .6rem;text-align:center;font-family:var(--font-head);font-weight:600;
    font-size:.9rem;letter-spacing:.02em;color:var(--ink);text-decoration:none}
  .stickybar a.primary{background:var(--accent);color:var(--accent-ink)}
  .stickybar a:active{opacity:.85}
  body{padding-bottom:3.5rem}
}
@media print{.stickybar{display:none}}

/* Secondary button: outlined, so a two-button CTA has a clear primary.
   Used for the phone action once a real number replaces the placeholder. */
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line-strong)}
.btn.ghost:hover{border-color:var(--accent);color:var(--accent)}

/* Single-action sticky bar while the phone number is a placeholder. */
@media(max-width:820px){.stickybar:has(a:only-child){grid-template-columns:1fr}}

/* ---------- CASE STUDY FACT BAR ---------- */
.csfacts{display:flex;flex-wrap:wrap;gap:.6rem 2rem;margin-top:1.6rem}
.csfacts .dim{font-family:var(--font-mono);font-size:.74rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.csfacts .dim b{color:var(--accent);font-weight:500;margin-right:.5rem}
.card .kick{margin-bottom:.6rem}

/* ---------- MOBILE LEGIBILITY FLOOR ----------
   The mono label styles sit at .62-.66rem, which resolves to 10-11px. That is
   below the readable threshold on a phone and is flagged by mobile usability
   checks. Desktop keeps the tighter sizing; mobile gets a 12px floor. */
@media(max-width:820px){
  .hero-strip,.dimdiv,.bcard .k,.scard .k,.wcard .m .k,.bcard .topk,.bcard .sheet{font-size:.75rem}
  .kick,.eyebrow,.crumb,.hero-eyebrow2,.card .num,.csfacts .dim{font-size:.76rem}
}
/* hero-corners is overridden inside a later 420px breakpoint, so it needs
   restating here to keep the 12px mobile floor. */
@media(max-width:820px){.hero-corners{font-size:.75rem}}
@media(max-width:420px){.hero-corners{font-size:.75rem}}

/* ---------- GRID3 ----------
   Used by /who-we-serve and /case-studies. Auto-fit rather than a fixed 3
   columns, because those hubs hold 9 and 10 cards and need to reflow cleanly
   at every width without a stack of breakpoints. */
.grid3{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:1.2rem}
@media(max-width:640px){.grid3{grid-template-columns:1fr;gap:1rem}}

/* ---------- PAPER RESTYLE, per-component corrections ----------
   Anything that assumed a dark canvas and does not follow the tokens. */
.dwg{background:var(--surface)}
.dwg svg{color:var(--ink);opacity:.85}
.dwg:hover svg{color:var(--accent);opacity:1}
.tcard{background:var(--surface)}
.secimg,.gcell img{filter:none}
/* the hero sits on its own dark stage regardless of the page palette */
.hero,.hero .hero-inner{color:#fff}
.hero h1,.hero .hero-sub strong{color:#fff}
.hero-sub{color:rgba(255,255,255,.86)}
.hero-strip{color:rgba(255,255,255,.62);border-top-color:rgba(255,255,255,.18)}
.hero-eyebrow2{color:#8ecec8}
.hero-eyebrow2::before{background:#8ecec8}
.hero-tagline{color:#fff}
/* square buttons with a contrasting hover, as chosen */
.btn{border-radius:0}
.btn.s{background:var(--accent);color:#fff;border-color:var(--accent)}
.btn.s:hover{background:var(--ink);border-color:var(--ink);color:#fff;transform:none}
.btn:hover{border-color:var(--accent);color:var(--accent)}
/* footer follows the page, not the old dark surface */
footer{background:var(--bg2);border-top:1px solid var(--line)}
.foot-logo{color:var(--ink)}

/* ---------- MONTSERRAT AT READING SIZE ----------
   Montserrat is a geometric display face carrying body text here, which is the
   agreed choice. These compensate for what that costs at 16px: the wide round
   letterforms read loose, so a hair of negative tracking tightens them, and a
   little more leading stops long topic pages (1,200-1,400 words) feeling dense.
   Headings keep their own tracking, which is why this is scoped to text. */
body{letter-spacing:-.004em}
p,.lede,.article p{line-height:1.8}
.lede{letter-spacing:-.006em}
.subs li,li{line-height:1.7}
/* Montserrat's numerals are wide; tabular keeps the stat rows aligned */
.stats .n,.statblock .n,.cell .n{font-variant-numeric:tabular-nums}

/* ---------- PAPER RESTYLE: contrast corrections ----------
   The hero no longer fades into the page colour. It used to end in near-black,
   which the light strip text sat on happily; ending in paper made that text
   disappear. It now holds its dark surface to its own edge and the page starts
   paper below, which is a cleaner transition anyway. */
.duo{background:linear-gradient(180deg,rgba(15,20,19,.80),rgba(15,20,19,.34) 30%,
  rgba(15,20,19,.55) 66%,rgba(15,20,19,.94))}
.hero-strip{color:rgba(255,255,255,.72);border-top-color:rgba(255,255,255,.20)}
.hero-strip span{color:rgba(255,255,255,.72)}

/* Cookie banner never followed the tokens: it had a hardcoded dark fallback,
   so on paper it stayed dark and the secondary button was unreadable. */
.lg-cookie-banner{background:var(--surface);border-color:var(--line);
  box-shadow:0 24px 60px rgba(20,22,26,.18)}
.lg-cookie-body{color:var(--text)}
.lg-cookie-btn{border-color:var(--line-strong)}
.lg-cookie-btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}
.lg-cookie-btn-secondary{background:transparent;color:var(--ink)}
.lg-cookie-btn-secondary:hover{border-color:var(--accent);color:var(--accent)}
.lg-cookie-link{color:var(--muted)}
.lg-cookie-link:hover{color:var(--accent)}

/* ---------- APPROVED HERO + NAV (ported from the lab) ---------- */
/* Logo centred with the navigation split either side. Columns are pinned so the
   logo holds the centre at every width: a 1fr track will not shrink below its
   content, so an unpinned layout pushed it off centre as soon as one side grew. */
.nav-inner{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  align-items:center;gap:1rem}
.navside-left{grid-column:1;justify-self:start;min-width:0}
.brand{grid-column:2;justify-self:center}
.navside-right{grid-column:3;justify-self:end;min-width:0}
.nav-links{gap:1.3rem;flex-wrap:nowrap}
.nav-links>li>a{white-space:nowrap}
.navtel{display:inline-flex;align-items:center;gap:.5rem;font-family:var(--font-mono);
  font-size:.8rem;color:var(--ink);white-space:nowrap}
.navtel svg{width:14px;height:14px;stroke:var(--accent);stroke-width:1.6;fill:none;
  stroke-linecap:round;stroke-linejoin:round}
.navtel:hover{color:var(--accent)}

/* Tagline carries the size; the headline sits smaller beneath it. */
.hero-tagline{font-family:var(--font-display);font-weight:800;letter-spacing:-.01em;
  font-size:clamp(1.9rem,4.4vw,3.5rem);line-height:1.12;color:#fff;margin:0 0 .8rem;
  max-width:20ch}
/* Marker block, painted as a background so it survives wrapping onto two lines.
   A positioned box only tracks the first line fragment. */
.hero-tagline .hl{color:#fff;padding:0 .12em;-webkit-box-decoration-break:clone;
  box-decoration-break:clone;background-image:linear-gradient(var(--accent),var(--accent));
  background-repeat:no-repeat;background-position:left center;background-size:0% 100%;
  animation:hlsweep .8s .35s cubic-bezier(.2,.7,.3,1) forwards}
@keyframes hlsweep{to{background-size:100% 100%}}
.hero-giant{font-family:var(--font-display);font-weight:800;text-transform:uppercase;
  letter-spacing:.14em;font-size:clamp(.82rem,1.4vw,1.02rem);line-height:1.3;
  color:rgba(255,255,255,.72);margin:0 0 1.3rem}
.hero-sub{max-width:56ch}
.hero-sub strong{display:block;color:#fff;font-size:1.16rem;font-weight:700;margin-bottom:0}

/* One square button plus an arrow link, rather than two competing buttons. */
.hero-actions{display:flex;gap:1.5rem;align-items:center;flex-wrap:wrap}
.hero-actions .btn.s{border-radius:0}
.hero-actions .btn.s:hover{background:#fff;border-color:#fff;color:var(--hero)}
.ghostlink{display:inline-flex;align-items:center;gap:.5rem;color:#fff;font-weight:600;
  font-size:.9rem;position:relative;padding:.4rem 0}
.ghostlink::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1px;
  background:#fff;transition:right .35s var(--ease)}
.ghostlink:hover::after{right:0}
.arw{width:15px;height:9px;display:inline-block;background:currentColor;
  -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 14'><path d='M0 7h20M14 1l6 6-6 6' fill='none' stroke='black' stroke-width='2'/></svg>") center/contain no-repeat;
  mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 14'><path d='M0 7h20M14 1l6 6-6 6' fill='none' stroke='black' stroke-width='2'/></svg>") center/contain no-repeat;
  transition:transform .3s}
.btn.s:hover .arw,.ghostlink:hover .arw{transform:translateX(3px)}

/* The agreed four stat boxes, replacing the compliance strip. */
.hero-stats{display:grid;grid-template-columns:repeat(4,1fr);max-width:1320px;
  margin:0 auto;border-top:1px solid rgba(255,255,255,.2)}
.hs{padding:1.3rem 1.1rem;text-align:center;position:relative}
.hs+.hs::before{content:"";position:absolute;left:0;top:24%;bottom:24%;width:1px;
  background:rgba(255,255,255,.2)}
.hs .n{display:block;font-family:var(--font-display);font-weight:800;color:#fff;
  font-size:clamp(1.35rem,2.6vw,2rem);line-height:1.05;font-variant-numeric:tabular-nums}
.hs .n i{font-style:normal;color:var(--accent-light)}
.hs .n em{font-style:normal;opacity:.45;font-weight:400}
.hs .n.w{font-size:clamp(.95rem,1.5vw,1.24rem);line-height:1.2;max-width:15ch;margin:0 auto}
.hs .l{display:block;font-family:var(--font-mono);font-size:.58rem;letter-spacing:.18em;
  text-transform:uppercase;color:rgba(255,255,255,.62);margin-top:.5rem}

@media(max-width:900px){.hero-stats{grid-template-columns:repeat(2,1fr)}
  .hs:nth-child(3)::before{display:none}}
@media(max-width:1180px){.nav-inner{grid-template-columns:auto 1fr auto}
  .brand{grid-column:1;justify-self:start}.nav-inner>nav{grid-column:3}}

/* dropdowns belong to their nav item, and the right-hand pair align right so
   they cannot run off the viewport */
.has-dd{position:relative}
.navside-right .dd{left:auto;right:0}
@media(max-width:1100px){.nav-links{gap:.9rem}.nav-links>li>a{font-size:.82rem}}
@media(max-width:1180px){
  /* Logo stays centred at every width, as agreed. The three tracks are kept and
     the left nav is display:none rather than hidden: a 1fr track will not shrink
     below its content, so leaving the links in the layout drags the logo off
     centre. Removing the item entirely leaves the empty track, and the two 1fr
     columns balance again. */
  .nav-inner{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr)}
  .navside-left{display:none}
  /* THE MOBILE MENU WAS EMPTY. The drawer markup lives inside .navside-left,
     which is hidden here so the logo can centre. The burger added .open to the
     <ul> inside it, but a child of a display:none parent has no layout box, so
     the panel opened at 0 by 0 with all four links inside it. On a phone that
     left the site with no navigation at all.
     Shown again only while the menu is open. The <ul> is position:fixed at that
     point, so .navside-left contributes no in-flow content and the logo stays
     centred. */
  body.nav-locked .navside-left{display:block}
  .brand{grid-column:2;justify-self:center}
  .navside-right{grid-column:3;justify-self:end}
  .navside-right .nav-links>li:not(.nav-cta){display:none}
  /* the drawer-only duplicates of Portfolio, About and the phone number */
  .nav-mob{display:list-item}
  .nav-mob-tel a{font-variant-numeric:tabular-nums;letter-spacing:.02em}
}
@media(max-width:520px){
  /* below this the number and the burger together crowd the logo out */
  .navside-right .nav-cta{display:none}
}

/* =======================================================================
   PREMIUM PASS
   Two-tone sections, dark footer, transparent nav, component detailing.
   ======================================================================= */

/* ---------- NAV: transparent over the hero, surface once past it ---------- */
.navbar{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;
  border-bottom:1px solid transparent}
.navbar .nav-links>li>a,.navbar .navtel{color:#fff}
.navbar .brand-logo{background-color:#fff}
.navbar.scrolled{background:rgba(250,250,248,.94);backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);border-bottom-color:var(--line)}
.navbar.scrolled .nav-links>li>a,.navbar.scrolled .navtel{color:var(--ink)}
.navbar.scrolled .brand-logo{background-color:var(--ink)}
.navbar.scrolled .nav-links>li>a:hover,.navbar.scrolled .navtel:hover{color:var(--accent)}
/* interior pages have no hero video, so the bar needs its surface immediately */
body:not(.has-hero) .navbar{background:rgba(250,250,248,.94);backdrop-filter:blur(14px);
  border-bottom-color:var(--line)}
body:not(.has-hero) .navbar .nav-links>li>a,
body:not(.has-hero) .navbar .navtel{color:var(--ink)}
body:not(.has-hero) .navbar .brand-logo{background-color:var(--ink)}
.navbtn{padding:.62rem 1.15rem;font-size:.82rem;border-radius:0;white-space:nowrap}
.nav-tel{margin-right:.2rem}


/* ---------- TWO TONE: alternating sections ----------
   Tokens are redefined here rather than components being patched one at a time.
   Anything that reads var(--ink), var(--text), var(--line) or var(--surface)
   inverts automatically, including components not yet written. The FAQ was the
   symptom that made this necessary: its summary used var(--ink) and vanished. */
.sec.alt{
  --ink:#ffffff;
  --text:rgba(255,255,255,.80);
  --muted:rgba(255,255,255,.58);
  --line:rgba(255,255,255,.16);
  --line-strong:rgba(255,255,255,.26);
  --surface:rgba(255,255,255,.05);
  --surface2:rgba(255,255,255,.08);
  --accent:#8ecec8;          /* same hue, legible value on dark */
  --accent-light:#a8ded9;
  --accent-ink:#0f1413;
  background:#14161a;
  color:var(--text);
}
/* things a token cannot express */
.sec.alt .secimg,.sec.alt .gcell img{filter:brightness(.96) contrast(1.03)}
.sec.alt .dwg svg{color:#fff;opacity:.9}
.sec.alt .btn.s{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.sec.alt .btn.s:hover{background:#fff;border-color:#fff;color:#14161a}
.sec.alt .hero-stats{border-top-color:var(--line)}
/* the bento's solid accent tile needs its own treatment inside an inverted block */
.sec.alt .bt-small{background:#2f6f6a;border-color:#2f6f6a}
.sec.alt .bt-small .bt-kick{color:rgba(255,255,255,.78)}
.sec.alt .bt-small h3,.sec.alt .bt-small p{color:#fff}

/* ---------- FOOTER: dark ---------- */
/* Literal, not var(--ink). The footer redefines --ink to white for its own
   contents, so painting the background from that token turned it white and put
   white text on it. A surface colour cannot come from a token the same element
   is about to override. */
footer{background:#14161a;color:rgba(255,255,255,.82);border-top:0}
footer h2{color:#fff;letter-spacing:.14em}
footer a{color:rgba(255,255,255,.74)}
footer a:hover{color:var(--accent-light)}
footer p{color:rgba(255,255,255,.62)}
.foot-logo{background-color:#fff}
.ftag{color:#fff}
.ftag::after{background:var(--accent-light)}
footer .fbot,footer .fg{border-color:rgba(255,255,255,.14)}

/* ---------- PREMIUM DETAILING ---------- */
/* Headings: tighter tracking and a hairline rule above the section eyebrow. */
h2{letter-spacing:-.028em;line-height:1.04}
.sec-head{position:relative}
.kick,.eyebrow{font-weight:500}
/* Trust row: the tick list read as a plain checklist. Boxed, ruled, quieter. */
.trust-strip{border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.trust-strip .t{display:flex;align-items:flex-start;gap:.7rem;padding:1.15rem 1.2rem;
  border-right:1px solid var(--line)}
.trust-strip .t:last-child{border-right:0}
.trust-strip .t b{display:block;font-family:var(--font-mono);font-size:.6rem;
  letter-spacing:.18em;text-transform:uppercase;color:var(--accent);margin-bottom:.25rem}
/* Capability pills: square, hairline, mono. Rounded chips read consumer. */
.pillrow{display:flex;flex-wrap:wrap;gap:.5rem}
.pillrow span,.caps span{display:inline-flex;align-items:center;border-radius:0;
  border:1px solid var(--line);padding:.55rem .9rem;font-family:var(--font-mono);
  font-size:.63rem;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  background:transparent;transition:border-color .25s,color .25s}
.pillrow span:hover,.caps span:hover{border-color:var(--accent);color:var(--accent)}
.sec.alt .pillrow span,.sec.alt .caps span{border-color:rgba(255,255,255,.18);
  color:rgba(255,255,255,.72)}
.sec.alt .pillrow span:hover{border-color:var(--accent-light);color:var(--accent-light)}
/* Cards: square, hairline, lift on hover rather than glow. */
.card,.scard,.bcard,.tcard,.costcard,.dwg,.gcell{border-radius:0}
.card,.scard{transition:border-color .3s var(--ease),transform .3s var(--ease)}
.card:hover,.scard:hover{transform:translateY(-3px);border-color:var(--accent)}
/* Section rhythm: more air, which is most of what reads as expensive. */
.sec{padding:7.5rem 0}
.sec-head{margin-bottom:3.6rem}

/* Sizing the split nav so four items a side genuinely fit.
   Measured at 1440: the left track was 521px and its content 595px, so
   "Renewable" ran 6px under the wordmark. A 2.2rem column-gap made it worse,
   because the gap comes out of the columns rather than adding to them.
   Gap, item spacing and type size are each trimmed a little instead of one
   being cut hard, which keeps the bar looking deliberate rather than cramped. */
.nav-inner{column-gap:1rem}
.brand{padding:0 .35rem}
.navside-left .nav-links,.navside-right .nav-links{min-width:0;flex-wrap:nowrap}
.nav-links{gap:1.05rem}
.nav-links>li>a{font-size:.8rem}
.navtel{font-size:.76rem}
.navbtn{padding:.58rem 1rem;font-size:.78rem}
@media(max-width:1240px){.nav-links{gap:1rem}.nav-links>li>a{font-size:.8rem}.navbtn{padding:.55rem .9rem;font-size:.76rem}}
@media(max-width:1120px){.navtel span{display:none}}
/* Measured: at 1100 the four left items still ran under the wordmark. Renewable
   drops first because it is already inside the Services dropdown, so nothing is
   actually lost from the navigation. */
/* These two rules used to drop the 4th nav item below 1180px and the 3rd below
   1020px, to stop the horizontal bar getting cramped. The burger only appears
   at 960px and down, so between 961 and 1180 the items were removed with no
   fallback: at 961-1020 the nav offered Services and What We Design only, and
   at 1021-1180 Renewable was gone. That band covers iPad Pro landscape and a
   half-screen laptop window.
   Measured before removing: with all four shown the row needs 936px of a 961px
   bar, so it fits on one line at every width from 961 up, with 25px spare at
   the tightest and no page overflow. The rules were not earning their cost. */

/* ---------- DIFFERENTIATOR BENTO ----------
   Asymmetric on purpose. An even grid reads as a list of equivalent claims, and
   these are not equivalent: the first tile is the strongest thing the practice
   can say, so it gets the room. Image and text share a tile, alternating which
   comes first, which is what stops it looking like cards. */
.btgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:1.1rem;margin-top:2.6rem}
.bt{position:relative;display:flex;flex-direction:column;overflow:hidden;
  border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.045);
  transition:border-color .35s var(--ease),transform .35s var(--ease)}
.bt:hover{border-color:var(--accent-light);transform:translateY(-3px)}
.bt-txt{padding:1.9rem 1.8rem}
.bt-kick{display:block;font-family:var(--font-mono);font-size:.58rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent-light);margin-bottom:.85rem}
.bt h3{font-family:var(--font-display);font-weight:800;letter-spacing:-.02em;
  font-size:1.32rem;line-height:1.2;color:#fff;margin-bottom:.7rem}
.bt p{color:rgba(255,255,255,.74);font-size:.93rem;line-height:1.7;margin:0;max-width:46ch}
.bt-img{position:relative;flex:1;min-height:190px;overflow:hidden}
.bt-img img{width:100%;height:100%;object-fit:cover;display:block;
  filter:grayscale(.1) contrast(1.04);transition:transform .9s var(--ease)}
.bt:hover .bt-img img{transform:scale(1.05)}

/* the shapes */
.bt-tall{grid-column:span 2;grid-row:span 2}
.bt-wide-top{grid-column:span 2}
.bt-small{grid-column:span 2}
.bt-wide{grid-column:span 4;flex-direction:row}
.bt-wide .bt-img{flex:0 0 44%;min-height:260px}
.bt-wide .bt-txt{flex:1;display:flex;flex-direction:column;justify-content:center;padding:2.4rem}
.bt-wide h3{font-size:1.7rem}
.bt-tall .bt-img{min-height:280px}
/* the text-only tile needs its own presence or it reads as a gap */
.bt-small{background:var(--accent);border-color:var(--accent);justify-content:center}
.bt-small .bt-kick{color:rgba(255,255,255,.75)}
.bt-small p{color:rgba(255,255,255,.9)}
.bt-small:hover{border-color:#fff;background:var(--accent)}

@media(max-width:1000px){
  .btgrid{grid-template-columns:repeat(2,1fr)}
  .bt-tall,.bt-wide-top,.bt-small{grid-column:span 2;grid-row:auto}
  .bt-wide{grid-column:span 2;flex-direction:column}
  .bt-wide .bt-img{flex:auto;min-height:220px}
}
@media(max-width:620px){
  .btgrid{grid-template-columns:1fr}
  .bt-tall,.bt-wide-top,.bt-small,.bt-wide{grid-column:span 1}
  .bt-txt{padding:1.5rem 1.35rem}
}

/* ---------- HERO v2 ----------
   Colour rather than a filled block, centred, and a much lighter wash so the
   footage reads. Dropping the wash costs contrast, so it is bought back locally:
   a soft radial behind the text block and a shadow on the type, which darkens
   only what sits under the words instead of the whole frame. */
.hero-inner{text-align:center}
.hero-tagline{font-size:clamp(1.05rem,2.05vw,1.55rem);line-height:1.4;margin:0 auto .55rem;
  max-width:32ch;font-weight:700;letter-spacing:0;
  text-shadow:0 2px 18px rgba(0,0,0,.5)}
/* colour only: no background, no sweep */
.hero-tagline .hl{background:none;padding:0;animation:none;color:#8ecec8}
.hero-giant{font-size:clamp(2.3rem,6.4vw,5.4rem);line-height:1;letter-spacing:-.025em;
  text-transform:uppercase;color:#fff;margin:0 auto 1.1rem;max-width:16ch;
  text-shadow:0 4px 34px rgba(0,0,0,.5)}
.hero-sub{margin:0 auto 2.2rem;text-align:center}
.hero-sub strong{font-size:1.14rem;text-shadow:0 2px 16px rgba(0,0,0,.55)}
.hero-actions{justify-content:center}
/* local contrast under the text, so the wash can stay light */
.hero-inner::before{content:"";position:absolute;left:50%;top:50%;
  width:min(1100px,92vw);height:min(680px,86%);transform:translate(-50%,-50%);
  background:radial-gradient(ellipse at center,rgba(8,12,12,.62),rgba(8,12,12,.28) 45%,transparent 72%);
  z-index:-1;pointer-events:none}
.hero-inner{position:relative;z-index:4}

/* the overall wash comes down a long way; the video was barely visible */
.duo{background:linear-gradient(180deg,rgba(15,20,19,.52) 0%,rgba(15,20,19,.14) 26%,
  rgba(15,20,19,.26) 62%,rgba(15,20,19,.86) 100%)}
.duo2{background:radial-gradient(120% 90% at 70% 18%,rgba(47,111,106,.13),transparent 60%)}
.herovid{filter:grayscale(.16) contrast(1.04) brightness(.82)}

/* ---------- READABILITY FLOOR ----------
   Measured rather than judged by eye. The paper --muted was 4.24 against a 4.5
   requirement, which is the kind of miss that never gets noticed in review and
   fails an accessibility audit later. The footer's secondary text was 3.78. */
footer p{color:rgba(255,255,255,.72)}
footer a{color:rgba(255,255,255,.80)}
.crumb a,.crumb{color:var(--muted)}
.sec.alt .crumb a,.sec.alt .dim{color:rgba(255,255,255,.78)}
/* The CTA was rendering dark-on-teal at 3.11. `.navbar.scrolled .nav-links>li>a`
   is more specific than `.navbtn`, so the link colour rule was winning over it.
   Matched at the same depth instead of reaching for !important. */
.navbar .nav-links>li.nav-cta>a.navbtn,
.navbar.scrolled .nav-links>li.nav-cta>a.navbtn{color:#fff;font-weight:700;
  background:var(--accent);border-color:var(--accent)}
.navbar .nav-links>li.nav-cta>a.navbtn:hover,
.navbar.scrolled .nav-links>li.nav-cta>a.navbtn:hover{background:var(--ink);
  border-color:var(--ink);color:#fff}

/* The footer is dark but inherits the paper tokens, and its paragraph sets
   color:var(--muted) inline, so darkening --muted for paper made the footer
   worse (3.78 down to 3.08). Redefining the tokens on the footer fixes it at
   source, including the inline rule, which no override could have reached. */
footer{
  --ink:#ffffff;
  --text:rgba(255,255,255,.82);
  --muted:rgba(255,255,255,.74);
  --line:rgba(255,255,255,.16);
  --accent:#8ecec8;
}

/* ============================================================
   HOME PAGE, approved 11 August 2026. See _review/DESIGN-DECISIONS.md.
   Sections butt directly together with no gap. Motion is transform and
   opacity only and sits behind prefers-reduced-motion.
   Stat counters reuse animateNum() in premium.js, which is why the rings
   carry .statblock and .n rather than a new mechanism.
   ============================================================ */
:root{--tealdark:#0c2423;--teal2:#8ecec8}

/* --- TRUST STRIP: photo behind, five identical columns --- */
.fx-trust{position:relative;overflow:hidden;background:var(--tealdark)}
.fx-trust>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.fx-veil{position:absolute;inset:0;background:linear-gradient(rgba(12,36,35,.80),rgba(12,36,35,.86))}
.fx-trust .container{position:relative;padding-top:1.9rem;padding-bottom:1.9rem}
.fx-trust-grid{display:grid;grid-template-columns:repeat(5,1fr)}
.fx-trust-grid>div{padding:0 1.2rem;border-left:1px solid rgba(168,222,217,.28)}
.fx-trust-grid>div:first-child{padding-left:0;border-left:0}
.fx-t-lab{font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;font-weight:800;color:#fff;line-height:1.35}
.fx-t-val{font-size:.75rem;color:rgba(255,255,255,.76);line-height:1.5;margin-top:.4rem}

/* --- TAGLINE BAND --- */
.fx-tag{background:var(--ink)}
.fx-tag .container{padding-top:2.6rem;padding-bottom:2.6rem}
.fx-tag-grid{display:grid;grid-template-columns:auto 1fr 1fr;gap:1.9rem;align-items:center}
.fx-vlabel{writing-mode:vertical-rl;transform:rotate(180deg);font-size:.62rem;letter-spacing:.28em;
 text-transform:uppercase;font-weight:800;color:var(--teal2)}
.fx-tag-h{font-family:var(--font-display);font-size:clamp(1.3rem,2.3vw,1.85rem);font-weight:800;
 letter-spacing:-.03em;line-height:1.12;color:#fff}
.fx-tag-sub{border-left:2px solid var(--accent);padding-left:1.3rem;color:rgba(255,255,255,.72);
 line-height:1.7;font-size:.87rem}

/* --- shared section head --- */
.fx-head{margin-bottom:1.4rem}
.fx-kick{display:block;font-size:.66rem;letter-spacing:.22em;text-transform:uppercase;
 font-weight:800;color:var(--accent)}
.fx-head h2{font-family:var(--font-display);font-size:clamp(1.35rem,2.4vw,1.95rem);font-weight:800;
 letter-spacing:-.03em;line-height:1.12;margin:.45rem 0 0;color:var(--ink)}

/* --- SERVICES: nine full-bleed alternating bands --- */
.fx-services{background:var(--bg);padding-top:2.6rem}
.fx-band{position:relative;display:block;overflow:hidden;text-decoration:none;isolation:isolate}
.fx-band>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
 transform:scale(1.02);transition:transform 1s cubic-bezier(.2,.7,.3,1)}
.fx-band:hover>img{transform:scale(1.06)}
.fx-band-veil{position:absolute;inset:0;z-index:-1;
 background:linear-gradient(90deg,rgba(14,16,20,.95) 6%,rgba(14,16,20,.34) 68%)}
.fx-band-veil.r{background:linear-gradient(270deg,rgba(14,16,20,.95) 6%,rgba(14,16,20,.34) 68%)}
.fx-band .container{min-height:132px;display:flex;align-items:center}
.fx-band-copy{max-width:38ch;padding:1.15rem 0}
.fx-band-copy.r{margin-left:auto;text-align:right}
.fx-band-k{font-family:var(--font-mono,ui-monospace,monospace);font-size:.66rem;color:var(--teal2);
 letter-spacing:.14em;display:block}
.fx-band h3{color:#fff;font-size:clamp(1rem,1.6vw,1.2rem);font-weight:800;letter-spacing:-.022em;
 margin:.28rem 0 .22rem;line-height:1.2;font-family:var(--font-display)}
.fx-band p{color:rgba(255,255,255,.72);font-size:.8rem;line-height:1.5;margin:0}
.fx-band-go{display:inline-block;margin-top:.6rem;color:var(--teal2);font-size:.72rem;font-weight:700;
 letter-spacing:.04em;position:relative}
.fx-band-go::after{content:"";position:absolute;left:0;bottom:-3px;height:1px;width:100%;
 background:var(--teal2);transform:scaleX(0);transform-origin:left;transition:transform .42s cubic-bezier(.2,.7,.3,1)}
.fx-band:hover .fx-band-go::after{transform:scaleX(1)}
.fx-band::after{content:"";position:absolute;top:-60%;left:-70%;width:34%;height:230%;z-index:0;
 background:linear-gradient(100deg,transparent,rgba(255,255,255,.12),transparent);
 transform:rotate(18deg) translateX(-140%);pointer-events:none}
.fx-band:hover::after{animation:fxsweep 1.1s cubic-bezier(.3,.1,.2,1)}
@keyframes fxsweep{to{transform:rotate(18deg) translateX(440%)}}

/* --- SECTORS: stacked full-width bands --- */
.fx-sectors{background:var(--bg);padding-top:2.6rem}
.fx-sector{position:relative;overflow:hidden}
.fx-sector>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
 transition:transform 1s cubic-bezier(.2,.7,.3,1)}
.fx-sector:hover>img{transform:scale(1.05)}
.fx-sector-veil{position:absolute;inset:0;background:linear-gradient(90deg,rgba(14,16,20,.93),rgba(14,16,20,.24))}
.fx-sector .container{position:relative;min-height:108px;display:flex;align-items:center}
.fx-sector-k{display:block;color:var(--teal2);font-size:.63rem;letter-spacing:.2em;
 text-transform:uppercase;font-weight:800}
.fx-sector-n{display:block;color:#fff;font-size:clamp(1rem,1.9vw,1.35rem);font-weight:800;
 letter-spacing:-.026em;margin-top:.25rem;font-family:var(--font-display)}

/* --- SELECTED WORK: contact-sheet grid, every tile a case study link --- */
.fx-work{background:var(--bg2)}
.fx-work .container{padding-top:2.8rem;padding-bottom:2.8rem}
.fx-sheet{display:grid;grid-template-columns:repeat(6,1fr);gap:.35rem;margin-top:.2rem}
.fx-tile{position:relative;display:block;overflow:hidden;aspect-ratio:16/10;background:var(--line)}
.fx-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
 transition:transform .9s cubic-bezier(.2,.7,.3,1)}
.fx-tile:hover img{transform:scale(1.09)}
.fx-tile-cap{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;
 padding:.6rem .65rem;background:linear-gradient(0deg,rgba(12,36,35,.94),rgba(12,36,35,.2) 62%,transparent);
 opacity:0;transition:opacity .4s cubic-bezier(.2,.7,.3,1)}
.fx-tile:hover .fx-tile-cap,.fx-tile:focus-visible .fx-tile-cap{opacity:1}
.fx-tile-s{display:block;color:var(--teal2);font-size:.56rem;letter-spacing:.16em;
 text-transform:uppercase;font-weight:800;line-height:1.2}
.fx-tile-n{display:block;color:#fff;font-size:.72rem;font-weight:700;line-height:1.25;margin-top:.16rem}
.fx-sheet-note{display:flex;justify-content:space-between;align-items:center;gap:1rem;flex-wrap:wrap;
 margin:1rem 0 0;color:var(--muted);font-size:.78rem}
.fx-sheet-note a{color:var(--accent);font-weight:700;text-decoration:none}
.fx-sheet-note a:hover{text-decoration:underline}

/* --- STATS: rings, counted by premium.js --- */
.fx-stats{background:var(--ink)}
.fx-stats .container{padding-top:2.8rem;padding-bottom:2.8rem}
.fx-stats .fx-head h2{color:#fff}
.fx-stats .fx-kick{color:var(--teal2)}
.fx-rings{display:flex;gap:1.6rem;flex-wrap:wrap;justify-content:center;margin-top:1.8rem}
.fx-ring{width:136px;height:136px;border:2px solid var(--teal2);border-radius:50%;display:flex;
 flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:.8rem;
 transition:transform .45s cubic-bezier(.2,.7,.3,1),border-color .45s,box-shadow .45s}
.fx-ring:hover{transform:translateY(-5px);border-color:#fff;box-shadow:0 0 0 5px rgba(142,206,200,.08)}
.fx-ring .n{font-size:1.5rem;font-weight:900;letter-spacing:-.035em;color:#fff;line-height:1;
 font-variant-numeric:tabular-nums;display:block}
.fx-ring-l{color:rgba(255,255,255,.64);font-size:.66rem;margin-top:.4rem;line-height:1.3}

/* --- WHY: frame photograph left, ink copy right, runs into the CTA --- */
.fx-why{display:grid;grid-template-columns:1fr 1fr;background:var(--ink)}
.fx-why-img{position:relative;min-height:360px;overflow:hidden}
.fx-why-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.fx-why-copy{padding:2.6rem 2.4rem}
.fx-why-copy .fx-kick{color:var(--teal2)}
.fx-why-copy h2{font-family:var(--font-display);font-size:clamp(1.35rem,2.3vw,1.85rem);font-weight:800;
 letter-spacing:-.03em;color:#fff;margin:.45rem 0 1.1rem;line-height:1.14}
.fx-why-row{padding:.85rem 0;border-bottom:1px solid rgba(255,255,255,.13)}
.fx-why-row:last-child{border-bottom:0}
.fx-why-row b{color:#fff;font-size:.95rem;line-height:1.35;display:block}
.fx-why-row p{color:rgba(255,255,255,.64);font-size:.82rem;margin:.32rem 0 0;line-height:1.6}

/* --- CTA: entirely teal, separating the ink above from the ink footer below --- */
.fx-cta{display:grid;grid-template-columns:1.15fr 1fr;background:var(--accent)}
.fx-cta-l{background:var(--accent);padding:2.9rem 2.4rem;display:flex;flex-direction:column;justify-content:center}
/* .86 not .72: at 10px on the teal accent, .72 measures 3.89:1 against a 4.5
   requirement. These are the trust marks under the closing CTA, so they are
   exactly the text a sceptical reader stops on. */
.fx-cta-k{font-size:.64rem;letter-spacing:.26em;text-transform:uppercase;color:rgba(255,255,255,.86);font-weight:800}
.fx-cta-l h2{color:#fff;font-size:clamp(1.5rem,2.8vw,2.1rem);font-weight:900;letter-spacing:-.038em;
 line-height:1.06;margin:.6rem 0 0;max-width:16ch;font-family:var(--font-display)}
.fx-cta-rule{height:1px;width:76px;background:rgba(255,255,255,.45);margin-top:1.1rem}
.fx-cta-marks{display:flex;gap:1.2rem;flex-wrap:wrap;margin-top:1.1rem;font-size:.7rem;
 letter-spacing:.05em;color:rgba(255,255,255,.86)}
.fx-cta-r{background:var(--accent);padding:2.9rem 2.4rem;display:flex;flex-direction:column;justify-content:center}
.fx-cta-r p{color:rgba(255,255,255,.94);line-height:1.7;font-size:.88rem;margin:0}
.fx-cta-btn{display:inline-flex;align-items:center;gap:.6rem;align-self:flex-start;margin-top:1.15rem;
 background:#fff;color:var(--accent);padding:.8rem 1.5rem;text-decoration:none;font-weight:800;
 font-size:.8rem;letter-spacing:.04em;position:relative;overflow:hidden;z-index:0}
.fx-cta-btn::before{content:"";position:absolute;inset:0;background:var(--ink);transform:scaleX(0);
 transform-origin:left;transition:transform .4s cubic-bezier(.2,.7,.3,1);z-index:-1}
.fx-cta-btn:hover{color:#fff}
.fx-cta-btn:hover::before{transform:scaleX(1)}
.fx-cta-tel{margin-top:.8rem;font-size:.78rem;color:rgba(255,255,255,.85)}
.fx-cta-tel a{color:#fff;font-weight:800;text-decoration:none}

/* --- FOOTER: sector-led. Scoped by class so the four footer{} rules
       elsewhere in this stylesheet cannot override it. --- */
/* Literal, NOT var(--ink). The footer element redefines --ink to #ffffff a few
   hundred lines above, an inversion trick left from an earlier design, so
   background:var(--ink) resolved to WHITE and the whole footer rendered
   white-on-white on every page. Anything inside .fx-foot that needs the dark
   value must use the literal for the same reason. */
footer.fx-foot{background:#14161a;color:#fff;padding:2.8rem 0 1.1rem;border-top:1px solid rgba(255,255,255,.1)}
.fx-foot-grid{display:grid;grid-template-columns:1.25fr 1fr 1fr 1fr;gap:1.8rem}
.fx-foot-logo{display:block;width:172px;height:62px;background-color:#fff;
 -webkit-mask:url(/images/logo/lockup.svg) left center/contain no-repeat;
 mask:url(/images/logo/lockup.svg) left center/contain no-repeat}
.fx-foot-tel{display:block;color:#fff;text-decoration:none;font-weight:800;font-size:1.08rem;margin-top:1rem}
.fx-foot-mail{display:block;color:rgba(255,255,255,.6);text-decoration:none;font-size:.8rem;margin-top:.2rem}
.fx-foot-addr{font-style:normal;color:rgba(255,255,255,.46);font-size:.75rem;line-height:1.65;margin:.8rem 0 0}
footer.fx-foot .fx-f-h{font-size:.63rem;letter-spacing:.2em;text-transform:uppercase;color:var(--teal2);
 font-weight:800;margin:0 0 .65rem;font-family:var(--font-display);line-height:1.3}
.fx-foot-grid a{display:block;color:rgba(255,255,255,.6);text-decoration:none;font-size:.78rem;
 padding:.22rem 0;transition:color .28s}
.fx-foot-grid a:hover{color:#fff}
.fx-foot-legal{border-top:1px solid rgba(255,255,255,.1);margin-top:1.8rem;padding-top:.9rem;
 display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;font-size:.66rem;
 line-height:1.75;color:rgba(255,255,255,.55)}
/* .55 not .32. This line carries the company number and place of registration,
   which the Trading Disclosures Regulations require to be on the website; at
   .32 it measured about 2.8:1, which is present but not readable. */
/* The legal line sits at .45 alpha, which is fine for the static copyright
   text but not for the links inside it: they measured 2.90:1. A link has to
   be readable AND distinguishable, so these are lifted and underlined rather
   than left to inherit. */
.fx-foot-legal a{color:rgba(255,255,255,.82);text-decoration:none;
 border-bottom:1px solid rgba(255,255,255,.28);padding-bottom:1px}
.fx-foot-legal a:hover{color:#fff;border-bottom-color:var(--teal2,#8ecec8)}

@media(prefers-reduced-motion:reduce){
  .fx-band::after{animation:none}
  .fx-band>img,.fx-sector>img,.fx-tile img,.fx-ring,.fx-cta-btn::before{transition:none}
}
@media(max-width:900px){
  .fx-trust-grid{grid-template-columns:repeat(2,1fr);gap:1.1rem}
  .fx-trust-grid>div{border-left:0;padding:0}
  .fx-tag-grid{grid-template-columns:1fr;gap:1.1rem}
  .fx-vlabel{writing-mode:horizontal-tb;transform:none}
  .fx-tag-sub{border-left:0;border-top:2px solid var(--accent);padding:.9rem 0 0}
  .fx-why,.fx-cta,.fx-foot-grid{grid-template-columns:1fr}
  .fx-sheet{grid-template-columns:repeat(3,1fr)}
  .fx-why-img{min-height:230px}
  .fx-band-copy.r{margin-left:0;text-align:left}
  .fx-band-veil,.fx-band-veil.r{background:linear-gradient(90deg,rgba(14,16,20,.94) 15%,rgba(14,16,20,.55))}
}

/* ==========================================================================
   SERVICE PAGE TEMPLATE  (sv-)  approved by Sahir, 11 August 2026
   Reaches ~170 pages: all service hubs, specialist, renewables, rail.
   Picks: B 01 cover, work 03, related 03, D 10 answer, E 03 standards,
   F 02 process, G 08 FAQ. Motion is transform/opacity only and sits behind
   prefers-reduced-motion at the foot of this block.
   ========================================================================== */
.sv-pad{padding:clamp(2.4rem,4vw,4rem) 0}
.sv-eyeb{font-size:.62rem;letter-spacing:.28em;text-transform:uppercase;font-weight:800;
 color:var(--accent);display:block}
.sv-ix{font-family:ui-monospace,'DM Mono',Menlo,monospace;font-size:.64rem;letter-spacing:.1em}
.sv-h{font-size:clamp(1.5rem,2.6vw,2rem);font-weight:900;letter-spacing:-.035em;
 margin:.5rem 0 0;line-height:1.05;color:var(--ink)}
.sv-head{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;
 flex-wrap:wrap;margin-bottom:1.7rem}
.sv-all{color:var(--accent);font-size:.8rem;font-weight:800;letter-spacing:.03em;text-decoration:none}
.sv-ul{position:relative;display:inline-block}
.sv-ul::after{content:"";position:absolute;left:0;bottom:-3px;height:1px;width:100%;background:currentColor;
 transform:scaleX(0);transform-origin:right;transition:transform .5s cubic-bezier(.2,.6,.2,1)}
.sv-ul:hover::after,a:hover .sv-ul::after{transform:scaleX(1);transform-origin:left}
.sv-zoom{position:relative;overflow:hidden;isolation:isolate;display:block;text-decoration:none}
.sv-zoom img{width:100%;height:100%;object-fit:cover;display:block;
 transition:transform 1.1s cubic-bezier(.2,.6,.2,1)}
.sv-zoom:hover img{transform:scale(1.055)}
.sv-zoom::after{content:"";position:absolute;top:-60%;left:-70%;width:32%;height:230%;z-index:4;
 background:linear-gradient(90deg,transparent,rgba(255,255,255,.16),transparent);transform:skewX(-18deg)}
.sv-zoom:hover::after{animation:svsweep 1.15s cubic-bezier(.3,.1,.2,1)}
@keyframes svsweep{from{left:-70%}to{left:120%}}

/* --- B 01: what we cover. Teal panel, white grid beneath. --- */
.sv-cover-top{background:var(--accent);padding:clamp(2.4rem,4vw,4rem) clamp(1.4rem,3vw,2.6rem) 2.2rem}
.sv-cover-top .sv-eyeb{color:rgba(255,255,255,.86)}
.sv-cover-rule{height:1px;width:58px;background:rgba(255,255,255,.45);margin:.9rem 0}
.sv-cover-top h2{color:#fff;font-size:clamp(1.6rem,3vw,2.2rem);font-weight:900;
 letter-spacing:-.038em;margin:0;line-height:1.02}
.sv-cover-top p{color:rgba(255,255,255,.88);line-height:1.75;max-width:64ch;margin:1rem 0 0;font-size:.9rem}
.sv-cover-grid{background:var(--bg);display:grid;grid-template-columns:repeat(3,1fr);
 padding:0 clamp(1.4rem,3vw,2.6rem) clamp(2.4rem,4vw,4rem);list-style:none;margin:0}
.sv-cover-grid>li{padding:19px 22px;border-bottom:1px solid var(--line);border-right:1px solid var(--line)}
.sv-cover-grid>li>*{display:flex;justify-content:space-between;align-items:flex-start;gap:14px;
 color:var(--ink);font-size:.88rem;line-height:1.35;font-weight:700;text-decoration:none}
.sv-cover-grid a{transition:padding-left .45s cubic-bezier(.2,.6,.2,1)}
.sv-cover-grid li:hover a{padding-left:12px}
.sv-cover-grid .mk{color:var(--accent);opacity:.55;font-weight:400;flex:0 0 auto}
.sv-cover-2{grid-template-columns:repeat(2,1fr)}
.sv-cover-3{grid-template-columns:repeat(3,1fr)}
.sv-cover-4{grid-template-columns:repeat(4,1fr)}
.sv-cover-grid span.mk{opacity:.3;color:var(--muted)}

/* --- In detail: dark. The longest read on the page, given its own weight. --- */
.sv-detail{background:var(--ink)}
.sv-detail .sv-eyeb{color:var(--teal2,#8ecec8)}
.sv-detail h2{color:#fff;font-size:clamp(1.5rem,2.6vw,2rem);font-weight:900;
 letter-spacing:-.035em;margin:.5rem 0 0;line-height:1.05;max-width:24ch}
.sv-detail.sv-detail-paper{background:var(--bg2)}
.sv-detail-paper .sv-eyeb{color:var(--accent)}
.sv-detail-paper h2{color:var(--ink)}
.sv-detail-paper .sv-article p{color:var(--text)}
.sv-detail-paper .sv-article p:first-child{color:var(--ink)}
.sv-article{margin-top:1.5rem;max-width:70ch}
.sv-article p{color:rgba(255,255,255,.74);line-height:1.85;font-size:1rem;margin:0 0 1.15rem}
.sv-article p:last-child{margin-bottom:0}
/* C 06: the labelled rail. Grid rather than a float so a long label wraps
   inside its own column instead of pushing the prose sideways. */
.sv-railed{max-width:none}
.sv-row{display:grid;grid-template-columns:210px 1fr;gap:34px;padding:20px 0;
 border-top:1px solid rgba(255,255,255,.14)}
.sv-lab{color:var(--teal2,#8ecec8);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;
 font-weight:800;line-height:1.5}
.sv-p{max-width:70ch}
.sv-p p{margin:0}
/* The closing "How Lead Group helps" row is the only one that sells, so it is
   marked off from the explanatory rows above it rather than reading as a
   fourth point of theory. */
.sv-row-help{border-top-color:var(--accent)}
.sv-row-help .sv-lab{color:#fff}
.sv-row-help .sv-p p{color:#fff}
.sv-detail-paper .sv-row{border-top-color:var(--line)}
.sv-detail-paper .sv-lab{color:var(--accent)}
.sv-detail-paper .sv-row-help{border-top-color:var(--accent)}
.sv-detail-paper .sv-row-help .sv-lab,.sv-detail-paper .sv-row-help .sv-p p{color:var(--ink)}
.sv-help-plain{border-top:1px solid var(--accent);padding-top:1.1rem;margin-top:1.2rem}
/* Topic body sections that sit on paper rather than in the dark block. */
/* Doubled class, deliberately. The dark rule .sv-article p:first-child is
   declared later in this file at the same specificity, so it was winning and
   painting the opening paragraph of every paper section in near-white on
   paper: 1.04:1 contrast, invisible, on 112 topic pages and every policy. */
.sv-article.sv-article-paper p{color:var(--text)}
.sv-article.sv-article-paper p:first-child{color:var(--text);font-size:1rem}
/* Location chips: the nearby-locations links, on paper above the dark related
   block. Chips rather than a bulleted list so six place names read as one
   band instead of a column of orphaned lines. */
.sv-chips{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:1.2rem}
.sv-chips a{border:1px solid var(--line2);padding:8px 15px;font-size:.84rem;color:var(--ink);
 text-decoration:none;background:var(--bg);font-weight:600;
 transition:border-color .35s,color .35s}
.sv-chips a:hover{border-color:var(--accent);color:var(--accent)}
.sv-chips a.more{border-color:transparent;color:var(--accent);padding-left:.6rem}
/* Solid hero: the approved treatment for subjects the library has no
   photography for (rail, wind, hydro, offshore, battery, civil). Ink rather
   than paper, so the page opens with the same weight as a photographic hero
   instead of looking like something failed to load. */
.phero.phero-solid{background:var(--ink);position:relative;overflow:hidden}
.phero.phero-solid::after{content:"";position:absolute;inset:0;pointer-events:none;
 background:radial-gradient(120% 90% at 82% 8%,rgba(47,111,106,.30),transparent 62%)}
.phero.phero-solid>*{position:relative;z-index:1}
.phero.phero-solid h1{color:#fff}
.phero.phero-solid .lede{color:rgba(255,255,255,.76)}
.phero.phero-solid .crumb,.phero.phero-solid .crumb a{color:rgba(255,255,255,.62)}
.phero.phero-solid .crumb a:hover{color:var(--teal2,#8ecec8)}
/* Flat cell for a tile or band whose subject has no photography. Sits in the
   same stacking position an image would, so the veil and caption above it are
   unchanged. */
.sv-noimg{position:absolute;inset:0;display:block;background:var(--ink);
 background-image:radial-gradient(120% 100% at 78% 12%,rgba(47,111,106,.42),transparent 64%)}
.fx-band>.sv-noimg{z-index:-2}
/* One issued drawing, on ink. The SVGs use stroke="currentColor" so they take
   the section colour; on a dark ground that means white line work, which is
   how a drawing is read on a screen anyway. */
.sv-dwg{background:var(--ink)}
.sv-dwg .sv-eyeb{color:var(--teal2,#8ecec8)}
.sv-dwg .sv-h{color:#fff}
.sv-dwg .sv-all{color:var(--teal2,#8ecec8)}
.sv-dwg-fig{margin:0;display:grid;grid-template-columns:1.35fr .65fr;gap:40px;align-items:start}
/* Capped, because these sheets vary from a single detail to a full layout and
   an uncapped one ran to nine hundred pixels and dominated the page it was
   meant to support. object-fit keeps the whole sheet visible rather than
   cropping engineering off the edge. */
.sv-dwg-fig svg{width:100%;height:auto;max-height:440px;object-fit:contain;display:block;
 color:rgba(255,255,255,.82);transition:color .5s}
.sv-dwg-fig:hover svg{color:var(--teal2,#8ecec8)}
.sv-dwg-fig figcaption{color:#fff;font-size:.95rem;font-weight:800;letter-spacing:-.02em;
 line-height:1.3;border-top:1px solid rgba(255,255,255,.2);padding-top:1.1rem}
.sv-dwg-fig figcaption span{display:block;color:rgba(255,255,255,.6);font-size:.8rem;
 font-weight:400;line-height:1.7;margin-top:.6rem;letter-spacing:0}
@media(max-width:860px){.sv-dwg-fig{grid-template-columns:1fr;gap:20px}}
/* Policy pages. A draft clause is marked so loudly that it cannot be mistaken
   for finished text, because the failure mode here is a half-written policy
   being read by a contractor at PQQ stage. */
.pol-sec{padding-top:0;padding-bottom:0}
.pol-sec+.pol-sec{padding-top:0}
.pol-sec .sv-h{font-size:clamp(1.1rem,1.8vw,1.35rem);margin:2.2rem 0 .8rem}
.pol-sec .sv-article p{font-size:.95rem;line-height:1.8}
.pol-meta{color:var(--muted);font-size:.85rem;margin:0;line-height:1.7}
.pol-meta b{color:#7a2e22}
mark.pol-todo{display:block;background:#7a2e22;color:#fff;padding:12px 15px;margin:.7rem 0;
 font-size:.86rem;line-height:1.65;border-radius:2px}
mark.pol-todo b{color:#fff;display:block;margin-bottom:.25rem;letter-spacing:.04em;
 text-transform:uppercase;font-size:.68rem}
/* Lead magnet landing page. The form panel is ink so it reads as the thing to
   act on, against the contents list on paper beside it. */
.lm-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:48px;align-items:start}
.lm-contents{list-style:none;padding:0;margin:1.2rem 0 0;counter-reset:c}
.lm-contents li{display:grid;grid-template-columns:34px 1fr;gap:14px;padding:13px 0;
 border-top:1px solid var(--line);color:var(--text);font-size:.92rem;line-height:1.6}
.lm-contents .sv-ix{color:var(--accent)}
.lm-facts{display:grid;grid-template-columns:repeat(2,1fr);gap:14px 24px;margin-top:1.8rem;
 border-top:1px solid var(--line);padding-top:1.3rem}
.lm-facts .lab{font-size:.6rem;letter-spacing:.24em;text-transform:uppercase;font-weight:800;
 color:var(--muted);display:block}
.lm-facts b{color:var(--ink);font-size:.9rem;display:block;margin-top:.2rem}
.lm-why{color:var(--muted);font-size:.87rem;line-height:1.75;margin-top:1.6rem;
 border-left:2px solid var(--accent);padding-left:16px}
.lm-panel{background:var(--ink);padding:32px 30px;position:sticky;top:96px}
.lm-panel h2{color:#fff;font-size:1.3rem;font-weight:900;letter-spacing:-.03em;margin:0 0 1.2rem}
.lm-form label{display:block;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
 font-weight:800;color:rgba(255,255,255,.62);margin-bottom:1rem}
.lm-form input{display:block;width:100%;margin-top:.45rem;padding:11px 13px;
 background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.22);color:#fff;
 font:inherit;font-size:.92rem;letter-spacing:0;text-transform:none;border-radius:2px}
.lm-form input:focus{outline:2px solid var(--teal2,#8ecec8);outline-offset:1px;
 background:rgba(255,255,255,.1)}
.lm-row{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
.lm-note{color:rgba(255,255,255,.56);font-size:.76rem;line-height:1.65;margin:.2rem 0 1.2rem}
.lm-note a{color:var(--teal2,#8ecec8)}
.lm-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
@media(max-width:900px){.lm-grid{grid-template-columns:1fr;gap:32px}
 .lm-panel{position:static}.lm-row{grid-template-columns:1fr}}





/* Ticked list inside a dark block. Two columns, because eight one-line facts
   in a single column reads as a form rather than as evidence. */
.sv-tick{list-style:none;padding:0;margin:1.6rem 0 0;display:grid;
 grid-template-columns:1fr 1fr;gap:0 40px}
.sv-tick li{position:relative;padding:10px 0 10px 26px;
 border-top:1px solid rgba(255,255,255,.14);color:rgba(255,255,255,.78);
 font-size:.88rem;line-height:1.55}
.sv-tick li::before{content:"¹3";position:absolute;left:0;top:10px;
 color:var(--teal2,#8ecec8);font-weight:800}
@media(max-width:860px){.sv-tick{grid-template-columns:1fr}}



@media(max-width:860px){.sv-row{grid-template-columns:1fr;gap:8px;padding:16px 0}}

/* The opening paragraph carries the argument, so it is set a step up. */
.sv-article p:first-child{color:rgba(255,255,255,.92);font-size:1.06rem}

/* --- work 03: tinted paper, hero tile with a caption bar, three stacked --- */
.sv-work{background:var(--bg2)}
.sv-work-grid{display:grid;grid-template-columns:1.55fr 1fr;gap:12px;align-items:start}
.sv-work-hero{height:360px}
.sv-work-hero .veil{position:absolute;inset:0;z-index:2;
 background:linear-gradient(0deg,rgba(10,12,15,.5),transparent 55%)}
.sv-work-cap{background:var(--bg);border:1px solid var(--line);border-top:0;padding:20px 22px;
 display:flex;justify-content:space-between;align-items:flex-end;gap:20px}
.sv-work-cap b{color:var(--ink);font-size:1.2rem;font-weight:900;letter-spacing:-.03em;
 display:block;margin-top:.4rem}
.sv-work-cap .sv-all{white-space:nowrap}
.sv-work-cap .s{color:var(--muted);font-size:.83rem;display:block}
.sv-work-col{display:grid;grid-template-rows:repeat(3,1fr);gap:12px}
.sv-work-sm{height:148px}
.sv-work-sm .veil{position:absolute;inset:0;z-index:2;
 background:linear-gradient(0deg,rgba(10,12,15,.9) 4%,rgba(10,12,15,.2) 58%)}
.sv-work-sm .m{position:absolute;left:0;right:0;bottom:0;padding:16px 18px;z-index:3}
.sv-work-sm .k{font-size:.56rem;letter-spacing:.28em;text-transform:uppercase;font-weight:800;
 color:var(--teal2,#8ecec8);display:block}
.sv-work-sm .t{color:#fff;font-size:.92rem;font-weight:800;letter-spacing:-.02em;display:block;
 margin-top:.25rem;line-height:1.2}

/* --- related 03: dark section, teal duotone tiles, links ruled beneath --- */
.sv-rel{background:var(--ink)}
.sv-rel .sv-eyeb{color:var(--teal2,#8ecec8)}
.sv-rel .sv-h{color:#fff}
.sv-rel .sv-all{color:var(--teal2,#8ecec8)}
.sv-rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.sv-rel-t{height:146px}
.sv-rel-t img{filter:grayscale(1) contrast(1.12) brightness(.92);transition:transform 1.1s cubic-bezier(.2,.6,.2,1),filter .6s}
.sv-rel-t .tint{position:absolute;inset:0;z-index:2;background:var(--accent);
 mix-blend-mode:multiply;opacity:.9;transition:opacity .6s}
/* A second, darker pass under the caption. Multiply alone over a light aerial
   photograph lands on a flat mid-green; desaturating first and then laying the
   teal over it is a true duotone and holds white type. */
.sv-rel-t .tint::after{content:"";position:absolute;inset:0;
 background:linear-gradient(0deg,rgba(8,26,25,.78),rgba(8,26,25,.05) 62%)}
.sv-rel-t:hover img{filter:grayscale(.55) contrast(1.06) brightness(1)}
.sv-rel-t:hover .tint{opacity:.66}
.sv-rel-t .m{position:absolute;inset:0;padding:20px 22px;display:flex;flex-direction:column;
 justify-content:space-between;z-index:3}
.sv-rel-t .sv-ix{color:rgba(255,255,255,.6)}
.sv-rel-t b{color:#fff;font-size:1rem;font-weight:800;letter-spacing:-.022em;display:block;line-height:1.2}
.sv-rel-t .d{color:rgba(255,255,255,.72);font-size:.76rem;display:block;margin-top:.25rem}
.sv-rel-foot{border-top:1px solid rgba(255,255,255,.16);margin-top:2rem;padding-top:1.5rem;
 display:grid;grid-template-columns:1fr 1fr .8fr;gap:34px}
.sv-rel-foot .lab{font-size:.58rem;letter-spacing:.28em;text-transform:uppercase;font-weight:800;
 color:rgba(255,255,255,.62);display:block}
.sv-rel-foot .row{display:flex;flex-wrap:wrap;gap:.45rem;margin-top:.7rem}
.sv-rel-foot a{color:#fff;font-size:.81rem;border:1px solid rgba(255,255,255,.16);
 padding:6px 13px;font-weight:600;text-decoration:none;transition:border-color .35s,background .35s}
.sv-rel-foot a:hover{border-color:var(--teal2,#8ecec8);background:rgba(255,255,255,.06)}

/* --- D 10: the answer block as a full teal band --- */
.sv-ans{background:var(--accent);padding:clamp(2.4rem,4vw,3.6rem) 0}
.sv-ans h2{color:#fff;font-size:clamp(1.3rem,2.2vw,1.6rem);font-weight:900;letter-spacing:-.03em;margin:0}
.sv-ans p{color:rgba(255,255,255,.9);line-height:1.8;max-width:72ch;margin:.7rem 0 0}
.sv-ans-dims{display:grid;grid-template-columns:repeat(4,1fr);margin-top:1.6rem;list-style:none;padding:0}
.sv-ans-dims li{border-top:1px solid rgba(255,255,255,.35);padding:12px 18px 0 0;
 color:#fff;font-size:.86rem;line-height:1.4;font-weight:700}

/* --- E 03: standards as a dark two-column strip --- */
.sv-std{background:var(--ink);padding:clamp(2.4rem,4vw,3.4rem) 0}
.sv-std h2{color:#fff;font-size:clamp(1.4rem,2.4vw,1.8rem);font-weight:900;letter-spacing:-.035em;
 margin:.3rem 0 1.3rem}
.sv-std-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 40px}
.sv-std-grid>div{border-top:1px solid rgba(255,255,255,.16);padding:20px 0 26px}
.sv-std-grid b{color:var(--teal2,#8ecec8);font-size:.9rem;display:block}
.sv-std-grid p{color:rgba(255,255,255,.66);font-size:.83rem;line-height:1.65;margin:.4rem 0 0}

/* --- F 02: process as a horizontal track --- */
.sv-proc-track{position:relative;display:grid;gap:0}
.sv-proc-track>div{position:relative;padding-right:24px}
.sv-proc-track>div::after{content:"";position:absolute;top:11px;left:34px;right:0;height:1px;
 background:rgba(20,22,26,.22)}
.sv-proc-track>div:last-child::after{display:none}
.sv-proc-dot{width:23px;height:23px;border-radius:50%;background:var(--accent);color:#fff;
 display:flex;align-items:center;justify-content:center;font-size:.68rem;font-weight:700;
 position:relative;z-index:2}
.sv-proc-track h3{color:var(--ink);font-size:.95rem;margin:.8rem 0 0;font-weight:800}
.sv-proc-track p{color:var(--muted);font-size:.83rem;margin:.3rem 0 0;line-height:1.6}

/* --- G 08: compact FAQ accordion with teal markers --- */
/* The FAQ follows the work strip on a service page but follows the process
   track directly on an audience page, where both are plain paper and merged
   into one continuous block. A hairline gives the seam in either case. */
.sv-faq-sec{border-top:1px solid var(--line)}
.sv-faq details{border-bottom:1px solid var(--line);padding:14px 0}
.sv-faq summary{cursor:pointer;color:var(--ink);font-weight:600;font-size:.94rem;list-style:none;
 display:flex;gap:9px;align-items:baseline}
.sv-faq summary::-webkit-details-marker{display:none}
.sv-faq summary::before{content:"+";color:var(--accent);font-weight:800;flex:0 0 18px;font-size:1.05rem;line-height:1.35;display:inline-block;transform-origin:center;transition:transform .35s cubic-bezier(.2,.6,.2,1)}
.sv-faq details[open] summary::before{transform:rotate(45deg)}
.sv-faq details p{color:var(--muted);line-height:1.7;font-size:.86rem;margin:.5rem 0 0 22px;max-width:76ch}

@media(max-width:900px){
 .sv-cover-grid,.sv-cover-2,.sv-cover-3,.sv-cover-4{grid-template-columns:repeat(2,1fr)}
 .sv-work-grid,.sv-rel-grid,.sv-std-grid,.sv-rel-foot{grid-template-columns:1fr}
 .sv-ans-dims{grid-template-columns:1fr 1fr}
 .sv-proc-track{grid-template-columns:1fr}
 .sv-proc-track::before{display:none}
 .sv-proc-track>div{padding:0 0 18px}
}
@media(max-width:560px){.sv-cover-grid,.sv-cover-2,.sv-cover-3,.sv-cover-4{grid-template-columns:1fr}.sv-ans-dims{grid-template-columns:1fr}}
@media (prefers-reduced-motion:reduce){
 .sv-zoom img,.sv-ul::after,.sv-cover-grid a,.sv-rel-t .tint,.sv-rel-foot a{transition:none}
 .sv-zoom:hover::after{animation:none}
 .sv-zoom:hover img{transform:none}
}

/* ==========================================================================
   MOBILE AND TABLET, 13 August 2026
   Three real problems found by measuring at 390, 768 and 1024 rather than by
   looking at one screenshot:
     1. fourteen label and eyebrow styles rendered between 9.0px and 10.9px,
        which is under the readable floor on a handset, and they are uppercase
        and letterspaced, which makes small worse rather than better
     2. tap targets down to 15px high against the WCAG 2.5.8 minimum of 24px,
        including the breadcrumb, the CTA phone number and every link in a
        "what we cover" cell
     3. the footer dropped straight from four columns to one below 900px, so a
        768px tablet wasted half its width
   ========================================================================== */

/* --- the whole "what we cover" cell becomes the tap target ---------------
   The padding was on the <li> and the <a> sat inside it, so the anchor was
   only as tall as its text and the surrounding 19px of padding did nothing
   when tapped. Moving the padding onto the anchor makes the cell itself
   clickable, which is both the accessible fix and the one a thumb expects. */
.sv-cover-grid>li{padding:0}
.sv-cover-grid>li>*{padding:19px 22px;min-height:56px;align-items:center}

/* --- tablet: two footer columns rather than one ------------------------- */
@media(min-width:601px) and (max-width:900px){
  .fx-foot-grid{grid-template-columns:1fr 1fr;gap:2rem 2.4rem}
  .sv-cover-grid,.sv-cover-2,.sv-cover-3,.sv-cover-4{grid-template-columns:1fr 1fr}
  .sv-rel-grid,.sv-std-grid{grid-template-columns:1fr 1fr}
  .sv-ans-dims{grid-template-columns:1fr 1fr}
  .lm-grid{grid-template-columns:1fr}
  .sv-work-grid{grid-template-columns:1fr}
}

/* --- touch widths: readable text and reachable targets ------------------ */
@media(max-width:1024px){
  /* Nothing below 11px. These are all uppercase, letterspaced labels, where
     small is harder to read than the size alone suggests. */
  .sv-eyeb,.fx-kick,.fx-cta-k,.fx-sector-k,.fx-band-k,.fx-f-h,.fx-tile-s,
  .fx-ring-l,.fx-vlabel,.sv-ix,.sv-rel-foot .lab,.lm-facts .lab,
  .hero-stats .l,.hs .l,.k,.kick,.eyebrow{font-size:11px!important;letter-spacing:.16em}
  .sv-proc-dot{font-size:11px}
  .fx-foot-legal{font-size:.72rem}

  /* 24px minimum on every target a thumb has to find. Vertical padding rather
     than height, so the text keeps its position and only the hit area grows. */
  .crumb a{display:inline-block;padding:5px 0}
  .fx-cta-tel a{display:inline-block;padding:5px 0}
  .sv-all,.fx-sheet-note a{display:inline-block;padding:3px 0}
  .fx-foot-legal a{display:inline-block;padding:4px 0}
  .fx-foot-grid a{padding:5px 0}
  .sv-chips a{padding:10px 15px}
  .sv-rel-foot a{padding:9px 14px}
  ul.subs li a{display:inline-block;padding:4px 0}
  /* Standalone links that sit alone in their own paragraph. Scoped to those
     rather than to every inline link, because padding an anchor that sits
     mid-sentence pushes the surrounding text lines apart. */
  .container>p>a:only-child,
  .note>a:only-child,
  .answer p>a:only-child{display:inline-block;padding:4px 0}
  /* The drawing caption is the label on the one asset nobody else publishes. */
  .dwg figcaption{font-size:11px}

  /* THE STICKY CALL BAR WAS HALF INVISIBLE. .stickybar a inherits color:var(--ink),
     which is #14161a, sitting on a bar painted rgba(14,15,18,.97). Near-black on
     near-black, about 1.05:1, so the "Call us" half read as an empty dark block
     on every page at every touch width. Only the teal "Get a quote" half was
     ever visible. */
  .stickybar a{color:#fff}
  .stickybar a.primary{background:var(--accent);color:#fff}
  .stickybar a:first-child{border-right:1px solid rgba(255,255,255,.16)}

  /* And the back-to-top button sat on top of that same bar, covering part of
     the CTA and putting two competing targets under the same thumb. Lift it
     clear of the bar's 56px and shrink it, since it is secondary to both. */
  .back-to-top{bottom:calc(56px + .9rem);right:.9rem;width:42px;height:42px}
  /* Consent-line and opt-out links on the magnet landing page. Small, but
     the opt-out is the one a reader who dislikes forms goes looking for. */
  .lm-note a,.pol-meta a{display:inline-block;padding:5px 0}
  /* The 17 city links in the footer coverage line, added 14 August. They sit
     in flowing text, so inline-block with vertical padding is the only way to
     reach 24px without breaking the sentence across lines. */
  .floc a{display:inline-block;padding:4px 0}
}

/* --- handset --------------------------------------------------------- */
@media(max-width:600px){
  /* The drawing is the one element that gets smaller the narrower the screen,
     because it scales to width. Cap it lower so it does not become a smudge. */
  .sv-dwg-fig svg{max-height:300px}
  /* Long uppercase eyebrows wrap badly at 390 in a two-word gap. */
  .sv-eyeb,.fx-kick{letter-spacing:.14em}
  /* The stat rings sat four-across and squeezed. */
  .fx-rings{grid-template-columns:1fr 1fr;gap:1.4rem}
  .sv-row{gap:6px}
}

/* ==========================================================================
   MOBILE DRAWER TEXT COLOUR, 17 August 2026
   The drawer is painted var(--bg2), which is cream, but top-level nav links
   inherit white from `.navbar .nav-links>li>a{color:#fff}` declared at line
   707. Every top-level label rendered at 1.13:1 against the drawer: Services,
   What We Design, Who We Serve, Renewable, Portfolio, About. Invisible. The
   sub-items beneath them were fine at 16:1, which is why it survived every
   screenshot: the menu looked populated.
   This has to live at the end of the file to win on order, because it matches
   the same specificity as the rule it corrects.
   ========================================================================== */
@media(max-width:1180px){
  .navbar .nav-links>li>a{color:var(--ink)}
  .navbar .nav-links>li>a:hover,
  .navbar .nav-links>li.has-dd.open>a{color:var(--accent)}
  .navbar .nav-links .navtel{color:var(--ink)}
  .navbar .nav-links .navtel a{color:var(--ink)}
}

/* Inline form failure message. Replaces navigating the visitor to a raw JSON
   error page when /api/contact answers with a 500, which lost whatever they
   had typed. Hidden until there is something to say, so it never occupies
   space in the normal case. */
.form-error{display:none;margin:0;padding:.85rem 1rem;border-radius:var(--radius);
  background:#fdecec;border:1px solid #e4b4b4;color:#8d2020;
  font-size:.9rem;line-height:1.45}
.form-error.is-shown{display:block}
