
:root{--navy:#06111a;--navy2:#0a1a25;--panel:#0d2230;--green:#8cc63e;--blue:#19a7df;--white:#f7fafc;--muted:#9eafb9;--ink:#18232c;--light:#f2f5f6;--line:#dce4e8;--max:1220px}
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:#06111a;font-family:Inter,Segoe UI,Arial,sans-serif;color:var(--ink);line-height:1.6}a{text-decoration:none;color:inherit}.container{max-width:var(--max);margin:auto;padding:0 24px}
.top{background:#03090e;color:#c7d1d7;font-size:12px}.top .container{display:flex;justify-content:flex-end;gap:22px;padding:7px 24px}
header{position:sticky;top:0;z-index:20;background:rgba(6,17,26,.97);border-bottom:1px solid #203744;color:#fff}.nav{height:86px;display:flex;align-items:center;justify-content:space-between;gap:20px}.brand img{height:52px;width:auto;display:block}.links{display:flex;align-items:center;gap:23px;font-size:13px;font-weight:800}.links a:hover{color:var(--green)}.quote{border:1px solid var(--blue);padding:11px 15px;border-radius:6px;color:#fff}.quote:hover{background:var(--blue);color:#06111a!important}
/* The real plant photograph sits behind everything, with a scrim over it so the headline stays legible: dark on the left where the copy is, lifting to the right where the support panel sits. The SVG technical layer is kept underneath as a fallback tint. */
.hero{min-height:650px;color:#fff;display:flex;align-items:center;position:relative;background:#06111a}.hero .container{padding-top:75px;padding-bottom:75px}.eyebrow{text-transform:uppercase;letter-spacing:2px;font-size:12px;font-weight:900;color:var(--green)}h1{font-size:clamp(45px,6vw,76px);line-height:1.02;margin:12px 0 22px;max-width:730px}h1 span{color:var(--green)}.hero p{font-size:19px;color:#d3dde2;max-width:700px}.pills{display:flex;flex-wrap:wrap;gap:9px;margin:24px 0}.pill{border:1px solid #35505e;border-radius:30px;padding:7px 12px;font-size:12px;background:rgba(3,10,15,.45)}.buttons{display:flex;flex-wrap:wrap;gap:12px}.btn{display:inline-block;padding:14px 19px;border-radius:7px;font-weight:900}.primary{background:var(--green);color:#06111a}.secondary{border:1px solid var(--blue);color:#fff}.secondary:hover{background:var(--blue);color:#06111a}
.trust{background:#091923;color:#fff;border-bottom:1px solid #223945}.trust .grid{display:grid;grid-template-columns:repeat(4,1fr)}.trust .item{padding:18px 16px;border-right:1px solid #233b47}.trust strong{display:block}.trust span{color:var(--muted);font-size:12px}
.section{padding:80px 0}.section.alt{background:var(--light)}.section.dark{background:var(--navy);color:#fff}.section h2{font-size:40px;line-height:1.1;margin:7px 0 14px}.lead{max-width:790px;color:var(--muted)}
.services{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;margin-top:34px}.service{background:#fff;border:1px solid var(--line);border-radius:10px;overflow:hidden;transition:.2s}.service:hover{transform:translateY(-4px);box-shadow:0 15px 30px rgba(6,17,26,.09)}.service img{width:100%;display:block}.service .body{padding:18px}.service h3{margin:0 0 7px;font-size:18px}.service p{margin:0;color:#697782;font-size:13px}.service a{display:inline-block;margin-top:12px;color:#5b8c22;font-weight:900;font-size:12px}
.cap-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;margin-top:35px;border:1px solid #284451;border-radius:10px;overflow:hidden}.cap{padding:26px;background:#0b1d29;border-right:1px solid #284451}.cap h3{margin:0 0 6px}.cap p{margin:0;color:#aab9c1;font-size:13px}
.split{display:grid;grid-template-columns:1fr 1fr;gap:55px;align-items:center}.panel{border:1px solid var(--line);border-radius:12px;padding:30px;background:#fff}.darkpanel{background:#0b1d29;border:1px solid #284451;color:#fff;border-radius:12px;padding:34px}.darkpanel p{color:#b7c5cc}.credentials{display:grid;grid-template-columns:1fr 1fr;gap:13px;margin-top:25px}.credential{background:var(--light);border-left:4px solid var(--green);padding:14px}.credential strong{display:block}.note{font-size:12px;color:#71808a}
.contact{display:grid;grid-template-columns:.8fr 1.2fr;gap:35px}.contact-card{background:#0b1d29;color:#fff;border-radius:12px;padding:30px}.contact-row{padding:15px 0;border-bottom:1px solid #29424f}.contact-row:last-child{border:0}.contact-row strong{display:block}.contact-row a{color:#d9f0c2}.form{display:grid;gap:13px}.form label{font-size:13px;font-weight:800}.form input,.form select,.form textarea{display:block;width:100%;padding:12px;margin-top:5px;border:1px solid #ccd7dd;border-radius:6px;font:inherit}.form textarea{min-height:140px}.form button{border:0;cursor:pointer;font:inherit}
.footer{background:#03090e;color:#9faeb6;padding:45px 0 25px}.footer-grid{display:grid;grid-template-columns:1.3fr 1fr 1fr 1fr 1fr;gap:25px}.footer img{width:205px}.footer h4{color:#fff;margin:0 0 9px}.footer a:hover{color:var(--green)}.copyright{border-top:1px solid #1d303a;margin-top:30px;padding-top:18px;font-size:11px;display:flex;justify-content:space-between;gap:20px}.badges{display:flex;gap:7px;flex-wrap:wrap;margin-top:15px}.badge{border:1px solid #304854;border-radius:20px;padding:4px 8px;font-size:10px}
@media(max-width:1000px){.links{display:none}.services{grid-template-columns:repeat(2,1fr)}.cap-grid,.trust .grid{grid-template-columns:repeat(2,1fr)}.footer-grid{grid-template-columns:repeat(2,1fr)}.split,.contact{grid-template-columns:1fr}}
@media(max-width:600px){.top{display:none}.nav{height:72px}.brand img{height:40px}.hero{min-height:650px}.hero .container{padding-top:55px}.hero p{font-size:16px}.services,.credentials,.cap-grid,.trust .grid,.footer-grid{grid-template-columns:1fr}.section{padding:58px 0}.section h2{font-size:32px}.copyright{display:block}.copyright span{display:block;margin-top:8px}}

/* 2026-08-26 — mobile navigation. .links was display:none below 1000px with
   no replacement, so none of the seven links were reachable on a phone. The
   button toggles the same list rather than a second copy of it. */
.navtoggle{display:none;background:none;border:0;padding:10px;cursor:pointer}
.navtoggle span{display:block;width:24px;height:2px;background:#fff;margin:5px 0;border-radius:2px;transition:.2s}
.navtoggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.navtoggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.navtoggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media(max-width:1000px){
  .navtoggle{display:block}
  /* height must become auto: .nav has a FIXED height, so an expanded menu
     overflowed the header's painted background and the links rendered
     transparently over the hero. Legible only if the header grows with it. */
  .nav{flex-wrap:wrap;height:auto;min-height:72px}
  .links{display:none;order:3;flex-basis:100%;flex-direction:column;align-items:stretch;gap:0;padding:8px 0 14px}
  .links.open{display:flex}
  .links a{padding:13px 4px;border-bottom:1px solid #203744;font-size:14px}
  .links a:last-child{border-bottom:0}
  .links .quote{margin-top:10px;text-align:center}
}

/* v2 design pass 2026-08-26 — brings the live site back to the mockup.
   Three mechanical causes were behind "missing pictures" and "strange
   background": (1) body had no background-color, so gaps showed white;
   (2) the service "icons" were 640x420 placeholder TILES with the service
   name baked in as text, which is why every card showed its title twice;
   (3) the hero background SVG had copy baked into it, which collided with
   the real CTA buttons. */
.service{background:#fff}
.service img{width:100%;height:120px;object-fit:contain;padding:26px 0 6px;background:transparent;display:block}
.service .body{padding:0 18px 20px;text-align:center}
.service .body h3{font-size:15px;letter-spacing:.02em;margin:6px 0 6px}
.service .body p{font-size:13px;color:var(--muted);min-height:38px}

/* hero: give the copy room and hang the support panel on the right */
.hero .container{position:relative}
.heropanel{position:absolute;right:0;max-width:calc(100% - 24px);box-sizing:border-box;top:50%;transform:translateY(-50%);width:290px;
  background:rgba(13,34,48,.92);border:1px solid #22404f;border-radius:12px;padding:18px 18px 16px;
  backdrop-filter:blur(2px)}
.heropanel img{width:100%;height:120px;object-fit:contain;display:block;margin-bottom:10px}
.heropanel .hp-t{font-size:13px;font-weight:800;letter-spacing:.12em;color:#fff}
.heropanel .hp-s{font-size:13px;font-weight:800;letter-spacing:.12em;color:var(--green);margin-bottom:8px}
.heropanel p{font-size:12.5px;color:var(--muted);line-height:1.55;margin:0 0 10px}
.heropanel a{font-size:12.5px;font-weight:700;color:var(--green)}
@media(max-width:1100px){.heropanel{position:static;transform:none;width:auto;max-width:100%;box-sizing:border-box;margin-top:26px}}

/* trust strip icons */
.trust .item{display:flex;gap:12px;align-items:flex-start}
.trust .ico{width:26px;height:26px;flex:none;color:var(--green);margin-top:2px}

/* the world-map figure on remote support */
.mapfig{margin:0 0 34px}
.mapfig img{width:100%;max-width:760px;display:block;border:1px solid #1d3644;border-radius:12px}
.mapfig figcaption{font-size:13px;color:var(--muted);margin-top:10px;max-width:760px}

/* v2 design pass, part 2 — take the page dark, as the mockup is.
   Setting body dark on its own left the light sections showing dark ink on a
   dark ground, because they had no background of their own and relied on the
   browser default. The mockup is uniformly dark, so the sections follow it
   rather than being patched back to white. */
.section{background:var(--navy);color:#dfe8ee}
.section.alt{background:var(--navy2)}
.section h2{color:#fff}
.section .lead,.section p{color:var(--muted)}
.panel{background:var(--panel);border-color:#1d3644;color:#dfe8ee}
.panel h3,.panel h2{color:#fff}

/* service cards: dark tiles with the green line icons, as drawn in the mockup */
.service{background:var(--panel);border:1px solid #1d3644}
.service:hover{border-color:var(--green);transform:translateY(-2px)}
.service .body h3{color:#fff}
.service .body p{color:var(--muted)}
.service .body a{color:var(--green)}

/* keep the hero headline and the support panel out of each other's way */
.hero .container>div:first-child,.hero .container>.eyebrow{max-width:640px}
.hero h1,.hero p,.hero .pills,.hero .buttons{max-width:640px}
.heropanel{top:auto;bottom:38px;transform:none}
/* reserve the panel's column so no hero copy can run underneath it */
@media(min-width:1101px){.hero .container{padding-right:330px}}
@media(max-width:1240px){.heropanel{width:250px}}

/* round 1 additions 2026-08-26 */
.aboutportrait{margin:0;display:flex;flex-direction:column;align-items:flex-start}
.aboutportrait img{width:100%;max-width:330px;display:block}
.aboutportrait figcaption{margin-top:-18px;padding-left:4px}
.aboutportrait figcaption strong{display:block;color:#fff;font-size:16px}
.aboutportrait figcaption span{display:block;color:var(--green);font-size:12px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;margin-top:3px}

.sparecards{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;margin-top:22px}
.sparecard{margin:0;background:var(--panel);border:1px solid #1d3644;border-radius:10px;overflow:hidden}
.sparecard img{width:100%;height:150px;object-fit:cover;display:block}
.sparecard figcaption{padding:12px 14px 14px}
.sparecard figcaption strong{display:block;color:#fff;font-size:14px;margin-bottom:4px}
.sparecard figcaption span{color:var(--muted);font-size:12.5px;line-height:1.5}
@media(max-width:700px){.sparecards{grid-template-columns:1fr}}

/* contact form: consent, honeypot and the status line */
.consent{display:flex;gap:10px;align-items:flex-start;font-size:12.5px;color:var(--muted);line-height:1.5;margin:4px 0 10px}
/* The tick box must carry its OWN box metrics. `.form input,.form select,
   .form textarea{width:100%}` also matches this checkbox and out-specifies a
   single `.consent` class, so it grew to the full row width and left the
   sentence beside it exactly 0px — one character per line, 2145px tall, with
   Send pushed off the bottom. It looked "hidden"; it was 100% wide.
   Same family as the honeypot below. Type-scoped + !important on the metrics
   only, so nothing in `.form` can reclaim them. */
.consent input[type=checkbox],.form .consent input[type=checkbox]{
  width:17px!important;height:17px!important;min-width:17px;padding:0!important;
  margin:3px 0 0!important;flex:0 0 17px;accent-color:var(--green)}
/* min-width:0 so the consent sentence can WRAP. Without it the flex child
   refuses to shrink below its longest word and the page scrolled sideways. */
/* `anywhere` (not `break-word`) is deliberate here ONLY as far as long URLs
   go — but it also drops min-content to a single character, which is what
   turned the collapse above into a silent sliver instead of a loud overflow.
   `break-word` keeps whole words intact, so if this box is ever squeezed
   again the text spills sideways and the smoke gate's overflow check FAILS
   instead of the page quietly becoming unreadable. */
.consent span{flex:1 1 auto;min-width:0;overflow-wrap:break-word}
.consent a{color:var(--green);text-decoration:underline}
/* Honeypot. left:-9999px pushed the document wider; clip it in place instead —
   still invisible and out of the tab order, but it cannot affect layout. */
/* !important on the box metrics: the form's own `.form input{width:100%}`
   out-specifies a single .hp class, so the honeypot rendered full width and
   pushed the page sideways. */
.hp,.form .hp{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0!important}
.formmsg{min-height:20px;font-size:13px;margin:10px 0 0}
.formmsg.ok{color:var(--green);font-weight:700}
.formmsg.err{color:#ff9b8a;font-weight:700}

/* ── HERO: photo and scrim as SEPARATE layers ──────────────────────────
   They used to be one `background:` stack, which meant the only way to make
   the photograph brighter was to thin the dark veil over the headline too —
   brightness and legibility fought each other. Split in two, each is tuned on
   its own: the photo gets a real brightness lift, the scrim keeps the text
   readable. Founder, 2026-08-26: "he can hardly see it".

   Position 44% (was centre) slides the visible window LEFT through the frame,
   so the technician sits slightly RIGHT of where he was — off the headline,
   still overlapped by the South Africa panel, which is the composition he
   asked to keep. */
.hero::before,.hero::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none}
.hero::before{background:url("../images/hero-plant.jpg") 44% center/cover no-repeat;
  filter:brightness(1.72) contrast(.94) saturate(1.06)}
/* Eased at every stop. The left end stays the heaviest because that is where
   the headline, the body copy and the two OUTLINED buttons sit — an outlined
   button has no fill of its own, so its legibility is entirely the scrim's
   job. Measured, not eyeballed: see the contrast probe in the round-3 pack. */
.hero::after{background:linear-gradient(90deg,
  rgba(6,17,26,.76) 0%,rgba(6,17,26,.60) 38%,rgba(6,17,26,.26) 62%,rgba(6,17,26,.44) 100%)}
/* Copy sits above both layers. */
.hero .container{position:relative;z-index:1}
/* On a phone the copy runs the full width over the middle of the photo, so it
   needs a vertical scrim as well — the horizontal one is nearly gone by then. */
@media(max-width:1100px){
  .hero::after{background:linear-gradient(180deg,
    rgba(6,17,26,.80) 0%,rgba(6,17,26,.66) 45%,rgba(6,17,26,.78) 100%)}
  .hero::before{background-position:50% center;filter:brightness(1.5) contrast(.95) saturate(1.06)}
}

/* Best-effort qualifier (2026-08-27). Sits directly above the copyright rule
   on every page, so it qualifies every breakdown-support claim on the
   site rather than just the one on the homepage. */
.fineprint{border-top:1px solid #1d303a;margin-top:30px;padding-top:16px;
  font-size:11.5px;line-height:1.6;color:#b6c4cc}
/* the copyright block already draws a rule; with the qualifier above it that
   would be two rules stacked, so drop the second one */
.fineprint + .copyright{border-top:0;margin-top:6px;padding-top:0}
