/* ==========================================================================
   Runicha Enterprises — design system

   Dark editorial theme: near-black canvas with a blue cast, serif display over
   a grotesk body, and tinted cards that borrow their colours from ink itself.
   Cyan, magenta, amber and black were sitting right there.
   ========================================================================== */

/* ==========================================================================
   THEME

   Dark is the base palette and the site's own identity. Light is a complete
   override under :root[data-theme="light"] — one block, not two, because the
   inline script in <head> resolves the system preference to an explicit
   data-theme before the first paint. Doing it there rather than with a
   prefers-color-scheme media query is what keeps this from being written
   twice, and the attribute is what the toggle flips anyway.

   Nothing below this block should name a literal colour. Anything that did was
   a value that could only ever be right on one of the two grounds.
   ========================================================================== */
:root{
  color-scheme:dark;

  /* canvas — not pure black. The logo is blue, so the ground is given the
     faintest blue cast and everything above it sits in the same family. */
  --bg:#04060a;
  --surface:#0b0f16;
  --surface-2:#0f141d;
  --surface-3:#151c27;
  --line:rgba(255,255,255,.09);
  --line-strong:rgba(255,255,255,.19);

  /* type */
  --text:#ffffff;
  --soft:#dfe5ec;
  --muted:#8794a3;
  /* --dim carries the breadcrumbs, spec labels, the copyright and the trademark
     note. At 12px those need AA, so it is a step lighter than it looks like it
     wants to be: the old #5a6572 measured 3.4:1 on this ground. */
  --dim:#748092;

  /* Translucent fills. On a dark ground these are white at low alpha; on a
     light one they have to become dark at low alpha, or every card, tag and
     input turns into an invisible white-on-white box. */
  --film:rgba(255,255,255,.065);
  --film-2:rgba(255,255,255,.018);
  --film-hi:rgba(255,255,255,.12);
  --film-hi-2:rgba(255,255,255,.04);
  --film-soft:rgba(255,255,255,.035);
  --field:rgba(255,255,255,.04);
  --hover:rgba(255,255,255,.07);
  --hover-soft:rgba(255,255,255,.06);
  --edge:rgba(255,255,255,.16);
  --edge-2:rgba(255,255,255,.10);

  /* grounds and atmospherics */
  --veil:rgba(4,6,10,.82);
  --veil-solid:rgba(4,6,10,.97);
  --band:linear-gradient(90deg,#05080d,#0a111b 50%,#05080d);
  --band-glow-1:rgba(47,143,212,.14);
  --band-glow-2:rgba(19,96,196,.12);
  --panel:linear-gradient(160deg,#0a1220,#070b12 60%);
  --foot-bg:#03050a;
  --grid-line:rgba(63,189,240,.10);
  --glow-1:rgba(47,143,212,.30);
  --glow-2:rgba(63,189,240,.20);
  --shadow-menu:0 30px 70px rgba(0,0,0,.72);
  --shadow-art:drop-shadow(0 26px 40px rgba(0,0,0,.65));
  --obj-cast:rgba(0,0,0,.8);   /* the hero product's own contact shadow */
  /* Photographs on a dark ground. They come out of bright studios, so they are
     held back a little and dissolved into the card at top and bottom rather
     than being left to end at a lit edge. */
  --shot-filter:brightness(.88) saturate(.94);
  --shot-veil:linear-gradient(180deg,
      rgba(4,6,10,.34) 0%, rgba(4,6,10,0) 34%,
      rgba(4,6,10,.55) 78%, rgba(4,6,10,.97) 100%);
  --noise:.035;

  /* The primary button and the skip link are the page ground inverted. */
  --invert-bg:#ffffff;
  --invert-fg:#04060a;
  --invert-glow:rgba(255,255,255,.30);

  --scroll-track:#04060a;
  --scroll-thumb:#22303f;
  --scroll-thumb-hi:#32485e;

  /* brand — straight off the mark: a bright wave blue, a deep navy, and the
     cyan that sits between them. */
  --brand:#2f8fd4;
  --brand-lite:#3fbdf0;
  --brand-deep:#1360c4;
  --accent:#2f8fd4;
  --accent-2:#3fbdf0;
  --accent-3:#5b83f0;
  /* the accent as TEXT on the page ground — the pale cyan above is legible on
     black and invisible on white, so this one is themed separately */
  --accent-ink:#3fbdf0;
  --chip-fg:#04121f;          /* the glyph drawn on a tint-coloured chip */

  /* ink tints — base, the ink colour text sits in, and the accent it glows with */
  --cyan:#02485f;    --cyan-ink:#dcf6ff;    --cyan-acc:#35c2ea;
  --blue:#062a63;    --blue-ink:#dde3ff;    --blue-acc:#5b83f0;
  --magenta:#5c0447; --magenta-ink:#ffdcf6; --magenta-acc:#e05ab4;
  --amber:#5f3a01;   --amber-ink:#ffeedc;   --amber-acc:#f0a13f;
  --green:#024a35;   --green-ink:#dcffee;   --green-acc:#2fd69b;
  --violet:#310466;  --violet-ink:#e7dcff;  --violet-acc:#9b6bff;
  --steel:#1e2733;   --steel-ink:#e4ecf5;   --steel-acc:#8fa6bd;
  --red:#5e0a12;     --red-ink:#ffdee1;     --red-acc:#f0565f;

  /* signature line — the wave in the logo, unrolled */
  --spectrum:linear-gradient(91deg,#0b2f6b 0%,#1360c4 22%,#2f8fd4 45%,#3fbdf0 62%,#a8e6ff 78%,#0b2f6b 100%);
  --spectrum-soft:linear-gradient(120deg,#1360c4,#2f8fd4,#3fbdf0,#a8e6ff);

  /* fonts */
  --display:"Sorts Mill Goudy",Georgia,"Times New Roman",serif;
  --sans:"Host Grotesk","Inter",system-ui,-apple-system,"Segoe UI",sans-serif;

  /* shape */
  --r-sm:12px;
  --r-md:20px;
  --r-lg:30px;
  --r-xl:40px;
  --r-pill:100px;

  /* rhythm */
  --pad:clamp(20px,5vw,64px);
  --gap:clamp(16px,2.2vw,28px);
  --section:clamp(64px,9vw,124px);
  --max:1240px;
}

/* ------------------------------------------------------------------- light
   Not a white page with the dark values inverted. The ground is a cool grey
   rather than pure white so the white surfaces above it still read as cards,
   and every tint is re-cut: the ink accents that glow on black are far too
   pale to carry text on white, and the deep tint bases used behind the product
   art become near-black smudges. Both sets are replaced, not tweaked. */
:root[data-theme="light"]{
  color-scheme:light;

  --bg:#f2f5f9;
  --surface:#ffffff;
  --surface-2:#f7f9fc;
  --surface-3:#eef2f7;
  --line:rgba(9,26,48,.12);
  --line-strong:rgba(9,26,48,.24);

  --text:#08111c;
  --soft:#243040;
  --muted:#57657a;
  --dim:#5c6b80;   /* 4.96:1 on the page ground — see the note in :root */

  --film:rgba(9,26,48,.045);
  --film-2:rgba(9,26,48,.012);
  --film-hi:rgba(9,26,48,.075);
  --film-hi-2:rgba(9,26,48,.02);
  --film-soft:rgba(9,26,48,.035);
  --field:rgba(9,26,48,.035);
  --hover:rgba(9,26,48,.06);
  --hover-soft:rgba(9,26,48,.05);
  --edge:rgba(9,26,48,.14);
  --edge-2:rgba(9,26,48,.10);

  --veil:rgba(244,247,251,.86);
  --veil-solid:rgba(246,249,252,.98);
  --band:linear-gradient(90deg,#e8eef6,#f6f9fc 50%,#e8eef6);
  --band-glow-1:rgba(47,143,212,.15);
  --band-glow-2:rgba(19,96,196,.10);
  --panel:linear-gradient(160deg,#e6eef8,#f8fafd 60%);
  --foot-bg:#ecf1f7;
  --grid-line:rgba(19,96,196,.09);
  --glow-1:rgba(47,143,212,.20);
  --glow-2:rgba(63,189,240,.15);
  --shadow-menu:0 26px 60px rgba(9,26,48,.16);
  --shadow-art:drop-shadow(0 22px 34px rgba(9,26,48,.22));
  --obj-cast:rgba(9,26,48,.30);
  /* On a light ground a photograph needs no holding back — only the same soft
     landing into the card, so the two share an edge instead of butting. */
  --shot-filter:brightness(1) saturate(1);
  --shot-veil:linear-gradient(180deg,
      rgba(255,255,255,.10) 0%, rgba(255,255,255,0) 40%,
      rgba(242,245,249,.45) 82%, rgba(242,245,249,.96) 100%);
  --noise:.02;               /* banding is a dark-gradient problem, not a light one */

  --invert-bg:#0b131d;
  --invert-fg:#ffffff;
  --invert-glow:rgba(11,19,29,.28);

  --scroll-track:#e6ecf3;
  --scroll-thumb:#c2cfdc;
  --scroll-thumb-hi:#a3b4c6;

  --accent-ink:#1360c4;
  --chip-fg:#ffffff;

  /* tint bases go pale (they sit behind artwork), accents go deep (they carry
     text and small marks) */
  --cyan:#d3eff9;    --cyan-acc:#0d7fa3;
  --blue:#dde5fb;    --blue-acc:#3a5fd0;
  --magenta:#fbdcf1; --magenta-acc:#b4308a;
  --amber:#fbe8cf;   --amber-acc:#a9660a;
  --green:#d0f5e6;   --green-acc:#0a8f63;
  --violet:#e7dcfb;  --violet-acc:#6d3fd2;
  --steel:#dfe7ef;   --steel-acc:#54697e;
  --red:#fbdcde;     --red-acc:#c22f3a;

  --spectrum:linear-gradient(91deg,#0b2f6b 0%,#1360c4 22%,#2f8fd4 45%,#3fbdf0 62%,#1360c4 78%,#0b2f6b 100%);
  --spectrum-soft:linear-gradient(120deg,#0b3f9e,#1360c4,#2f8fd4,#0d7fa3);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;color:inherit}
ul,ol{margin:0;padding:0;list-style:none}
::selection{background:var(--brand);color:#fff}

/* Fine grain over the whole page. Near-black gradients band badly on cheap
   panels; a little noise breaks the banding up and warms the ground. */
body::after{
  content:"";position:fixed;inset:0;z-index:1;pointer-events:none;opacity:var(--noise);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:var(--scroll-track)}
::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:100px}
::-webkit-scrollbar-thumb:hover{background:var(--scroll-thumb-hi)}

/* ====================================================================== SPLASH
   A coder printing the company's own name: the head crosses the line and the
   characters appear behind it, each jetting a drop as it lands.

   The dismissal is a CSS animation with fill-mode:forwards, NOT a JS timer.
   That distinction is the whole safety story — if the script is blocked, fails
   to parse or never runs, a JS-dismissed overlay would leave the entire site
   behind a full-screen panel for ever. Here the worst case is that the visitor
   waits out the animation. main.js only ever hurries it up. */
.splash{
  position:fixed;inset:0;z-index:9999;
  display:grid;place-items:center;
  background:
    radial-gradient(70% 90% at 50% 40%,var(--glow-1),transparent 62%),
    var(--bg);
  animation:splashOut .6s cubic-bezier(.4,0,.2,1) 2.05s forwards;
}
@keyframes splashOut{to{opacity:0;visibility:hidden;pointer-events:none}}
.splash.done{animation:splashOut .45s cubic-bezier(.4,0,.2,1) forwards}
:root.splash-seen .splash{display:none}

.splash-inner{display:grid;justify-items:center;gap:26px}

.splash-mark{
  display:block;width:96px;height:55px;
  background:url("../img/logo-mark-dark.png") center/contain no-repeat;
  animation:splashRise .7s cubic-bezier(.22,1,.36,1) both;
}
:root[data-theme="light"] .splash-mark{background-image:url("../img/logo-mark.png")}
@keyframes splashRise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

/* the line being printed */
.splash-print{position:relative;padding-bottom:14px}
.sp-line{
  display:flex;align-items:center;
  font-family:ui-monospace,"SFMono-Regular",Menlo,monospace;
  font-size:clamp(13px,2.6vw,17px);letter-spacing:.22em;
  color:var(--text);
}
.sp-line b{
  font-weight:500;opacity:0;
  animation:splashInk .28s ease-out both;
  /* The index the generator stamped on each character becomes its delay, which
     is what keeps the letters in step with the head above them. */
  animation-delay:calc(0.42s + var(--i) * 0.042s);
}
/* A flex item, so it needs flex-basis and no shrink: `width` alone gets
   squeezed back to nothing and RUNICHA ENTERPRISES prints as one word. */
.sp-gap{flex:0 0 .8em}
@keyframes splashInk{
  from{opacity:0;transform:translateY(-6px) scaleY(.6)}
  to  {opacity:1;transform:none}
}

/* the printhead crossing the line */
.sp-head{
  position:absolute;left:0;top:-16px;
  width:20px;height:12px;border-radius:3px 3px 5px 5px;
  background:linear-gradient(155deg,#3a4756,#141b25);
  border:1px solid rgba(255,255,255,.14);
  animation:splashTravel .84s cubic-bezier(.45,.05,.35,1) .38s both;
}
.sp-head i{
  position:absolute;left:50%;bottom:-3px;translate:-50% 0;
  width:6px;height:3px;border-radius:0 0 2px 2px;
  background:var(--brand-lite);box-shadow:0 0 8px var(--brand-lite);
}
@keyframes splashTravel{
  from{transform:translateX(0)}
  /* container width less the head's own, so it finishes flush with the last
     character instead of overshooting the line by its own length. */
  to  {transform:translateX(calc(100cqw - 100%))}
}
/* Percentages on translateX resolve against the element's OWN width — 20px —
   so the head would crawl a fifth of an inch. The line's width is what it has
   to cross, so the print block becomes the container it measures against. */
.splash-print{container-type:inline-size}

.splash-bar{
  width:130px;height:2px;border-radius:2px;overflow:hidden;
  background:var(--line-strong);
}
.splash-bar i{
  display:block;height:100%;width:100%;border-radius:2px;
  background:var(--spectrum-soft);transform-origin:left;
  animation:splashFill 1.9s cubic-bezier(.3,.6,.3,1) both;
}
@keyframes splashFill{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* Reduced motion keeps the panel — it is a brand moment, not decoration — but
   holds it still and gets out of the way quickly. */
@media (prefers-reduced-motion:reduce){
  .splash{animation:splashOut .3s linear .5s forwards}
  .splash-mark,.sp-line b,.splash-bar i{animation:none;opacity:1;transform:none}
  .sp-head{display:none}
  .splash-bar i{transform:scaleX(1)}
}

/* ---------------------------------------------------------- pointer trail
   An ink ribbon drawn behind the cursor. Sits above everything and takes no
   pointer events, so it can never intercept a click. */
.cursor-trail{
  position:fixed;top:0;left:0;z-index:9000;pointer-events:none;
  /* width/height are NOT optional. <canvas> is a replaced element, so inset:0
     alone does not stretch it the way it stretches a div — it keeps its
     intrinsic 300x150 box, the bitmap gets squeezed into that corner, and every
     drawn point lands nowhere near the pointer. */
  width:100%;height:100%;
  display:none;                       /* main.js turns it on, and only where it belongs */
}
.cursor-trail.on{display:block}

.skip{
  position:absolute;left:-9999px;top:12px;z-index:200;
  background:var(--invert-bg);color:var(--invert-fg);padding:10px 18px;border-radius:var(--r-pill);
}
.skip:focus{left:16px}

/* --------------------------------------------------------- layout helpers */
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--pad)}
.section{padding-block:var(--section);position:relative;z-index:2}
.center{text-align:center}
.spectrum-line{height:2px;width:100%;background:var(--spectrum);border-radius:100px}

/* ----------------------------------------------------------- typography */
h1,h2,h3,h4{margin:0;font-weight:400;font-family:var(--display);letter-spacing:-.03em;line-height:1.1}
.h-xl{font-size:clamp(36px,6vw,72px)}
.h-lg{font-size:clamp(31px,4.4vw,54px)}
.h-md{font-size:clamp(26px,3.2vw,40px)}
.h-sm{font-size:clamp(20px,2.1vw,27px)}
.h-xs{font-size:clamp(17px,1.6vw,20px)}
p{margin:0}

.lead{font-size:clamp(15.5px,1.35vw,18px);color:var(--soft);line-height:1.66}
.lead-sm{font-size:15px;color:var(--muted);line-height:1.65;max-width:64ch}
.small{font-size:14px;line-height:1.6}
.muted{color:var(--muted)}
.dim{color:var(--dim)}

.grad-text{
  background:var(--spectrum-soft);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
}

.kicker{
  font-family:var(--sans);
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted);font-weight:600;
  display:inline-flex;align-items:center;gap:10px;
}
.kicker::before{
  content:"";width:22px;height:2px;border-radius:2px;
  background:var(--spectrum-soft);flex-shrink:0;
}
.sec-head.center .kicker::after{
  content:"";width:22px;height:2px;border-radius:2px;
  background:var(--spectrum-soft);flex-shrink:0;
}

/* -------------------------------------------------------------------- chips */
.chip{
  display:inline-flex;align-items:center;gap:9px;
  padding:8px 18px;border:1px solid var(--edge);border-radius:var(--r-pill);
  font-size:12.5px;letter-spacing:.04em;color:var(--soft);
  background:linear-gradient(140deg,rgba(47,143,212,.20),rgba(63,189,240,.07));
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.1);
}
.chip .dot{
  width:7px;height:7px;border-radius:50%;background:var(--accent-ink);
  box-shadow:0 0 12px var(--accent-ink);animation:pulse 2.4s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.55;transform:scale(.82)}}

/* ------------------------------------------------------------------ buttons */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:14px 28px;border-radius:var(--r-pill);
  font-size:15px;font-weight:500;letter-spacing:-.01em;
  border:1px solid transparent;transition:.25s cubic-bezier(.4,0,.2,1);
  white-space:nowrap;
}
.btn-primary{background:var(--invert-bg);color:var(--invert-fg)}
.btn-primary:hover{
  transform:translateY(-2px);
  box-shadow:0 14px 34px -10px var(--invert-glow),0 0 26px -6px rgba(47,143,212,.75);
}
.btn-ghost{background:transparent;color:var(--text);border-color:var(--line-strong)}
.btn-ghost:hover{
  background:rgba(47,143,212,.14);border-color:rgba(63,189,240,.55);transform:translateY(-2px);
  box-shadow:0 12px 30px -14px rgba(47,143,212,.85);
}
.btn-sm{padding:10px 20px;font-size:14px}
.btn .arrow{transition:transform .25s}
.btn:hover .arrow{transform:translateX(4px)}
.btn:focus-visible,a:focus-visible,button:focus-visible{outline:2px solid var(--accent-ink);outline-offset:3px}

.link-arrow{
  display:inline-flex;align-items:center;gap:7px;
  font-size:14px;color:var(--soft);border-bottom:1px solid transparent;
  transition:.2s;padding-bottom:2px;width:fit-content;
}
.link-arrow:hover{color:var(--text);border-bottom-color:var(--line-strong);gap:11px}

/* ======================================================================= NAV */
.nav{
  position:fixed;inset:0 0 auto 0;z-index:100;
  transition:background .3s,border-color .3s;
  border-bottom:1px solid transparent;
}
.nav.scrolled{
  background:var(--veil);
  -webkit-backdrop-filter:blur(20px) saturate(1.6);backdrop-filter:blur(20px) saturate(1.6);
  border-bottom-color:var(--line);
}
/* the wave hairline, revealed once the header detaches from the hero */
.nav::after{
  content:"";position:absolute;inset:auto 0 0 0;height:1px;
  background:var(--spectrum);opacity:0;transition:opacity .35s;
}
.nav.scrolled::after{opacity:.6}
.nav-inner{
  position:relative;
  display:flex;align-items:center;justify-content:space-between;gap:24px;
  height:76px;max-width:var(--max);margin-inline:auto;padding-inline:var(--pad);
}

/* ------------------------------------------------------------------- brand
   The real mark from the supplied logo, beside the company name set in type.
   The artwork is a stacked lockup: used whole at header height it would put
   "ENTERPRISES" at about four pixels tall, so the header takes the mark — the
   half that survives being small — and the complete logo runs in the footer.

   Background-images, not <img>, so the theme swaps them and the browser only
   fetches the one it needs. tools/logo.mjs cuts these from brand/. */
.brand{display:flex;align-items:center;gap:11px;flex-shrink:0}
/* 232x132 artwork, so this box holds that 1.76:1. Squeezing a logo is the one
   thing you are never allowed to do to it. */
.mark{
  display:block;width:63px;height:36px;flex-shrink:0;
  background:url("../img/logo-mark-dark.png") center/contain no-repeat;
}
:root[data-theme="light"] .mark{background-image:url("../img/logo-mark.png")}

/* The full lockup, 356x300. */
.foot-logo{
  display:block;width:114px;height:96px;
  background:url("../img/logo-dark.png") left center/contain no-repeat;
}
:root[data-theme="light"] .foot-logo{background-image:url("../img/logo.png")}

.wordmark{display:grid;line-height:1}
.wordmark b{
  font-weight:600;font-size:18px;letter-spacing:-.02em;color:var(--text);
}
.wordmark i{
  font-style:normal;font-size:9.5px;letter-spacing:.32em;text-transform:uppercase;
  color:var(--muted);margin-top:3px;
}

.nav-links > ul{display:flex;align-items:center;gap:2px}
/* The child combinators are load-bearing. Written as a plain `.nav-links a`
   this also matches every link inside the mega panel — which lives in the same
   subtree — and repaints the panel's call-to-action button as a grey nav link:
   at (0,1,1) it outranks .btn-primary and strips the white pill off it. */
.nav-links > ul > li > a,.nav-trigger{
  display:flex;align-items:center;gap:6px;
  padding:9px 15px;border-radius:var(--r-pill);
  font-size:14.5px;color:var(--soft);background:none;border:0;transition:.2s;
}
.nav-links > ul > li > a:hover,.nav-trigger:hover{color:var(--text);background:var(--hover)}
.nav-links > ul > li > a.current,.nav-trigger.current{color:var(--text);background:rgba(47,143,212,.16)}
.nav-trigger svg{transition:transform .25s}
.has-menu.open .nav-trigger svg{transform:rotate(180deg)}

.nav-actions{display:flex;align-items:center;gap:12px}
/* nowrap is load-bearing. As a shrinkable flex item the number broke across
   three lines on a ~1000px window, where the links are still on show and the
   header has run out of room; the links give up the space instead. */
.nav-phone{
  display:flex;align-items:center;gap:8px;font-size:14px;color:var(--soft);
  padding:8px 4px;transition:.2s;white-space:nowrap;flex-shrink:0;
}
.nav-phone:hover{color:var(--text)}
.nav-phone svg{color:var(--accent-ink);flex-shrink:0}

/* ------------------------------------------------------------ theme switch
   Both glyphs are in the DOM; CSS picks the one that matches the theme, so the
   button never shows the wrong icon while the script is still loading. The sun
   shows on the dark theme, because it is an offer rather than a status. */
.theme-toggle{
  display:grid;place-items:center;flex-shrink:0;
  width:38px;height:38px;border-radius:50%;
  background:var(--film-soft);border:1px solid var(--line);color:var(--soft);
  transition:.25s cubic-bezier(.4,0,.2,1);
}
.theme-toggle:hover{
  color:var(--text);border-color:var(--line-strong);background:var(--hover);
  transform:translateY(-1px);
}
.theme-toggle svg{width:17px;height:17px;grid-area:1/1}
.theme-toggle .tt-label{display:none}
.i-moon{display:none}
:root[data-theme="light"] .i-sun{display:none}
:root[data-theme="light"] .i-moon{display:block}

/* In the sheet it is a labelled row, not a bare icon — there is room for the
   word, and a lone circle at the bottom of a menu explains nothing. */
.mm-theme{
  display:flex;align-items:center;gap:12px;
  padding:13px 4px;font-size:17px;color:var(--soft);
  background:none;border:0;border-bottom:1px solid var(--line);text-align:left;
}
.mm-theme svg{width:19px;height:19px;flex-shrink:0;color:var(--accent-ink)}
.mm-theme .tt-label{display:block}

/* ------------------------------------------------------------ mega dropdown
   The panel is positioned against the HEADER ROW, not against its trigger.
   Anchored to the trigger it can only ever be wrong: centred on it, a 900px
   panel runs off the left on narrower desktops; left-aligned to it, off the
   right. .nav-inner is always inside the viewport, so centring there always
   fits — and top:100% still lands just under the header, because .nav-inner
   IS the header row. */
.has-menu{position:static}
.menu{
  position:absolute;top:calc(100% + 12px);left:50%;translate:-50% 0;
  width:min(960px,calc(100% - 2 * var(--pad)));padding:18px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);
  box-shadow:var(--shadow-menu);
  display:grid;grid-template-columns:repeat(4,1fr);gap:10px;
  opacity:0;visibility:hidden;transform:translateY(-8px);transition:.22s;
}
/* the gap bridge — part of .menu, so crossing it never leaves .has-menu and
   closes the panel before the pointer can reach it */
.menu::before{content:"";position:absolute;left:0;right:0;top:-16px;height:16px}
.has-menu.open .menu{opacity:1;visibility:visible;transform:translateY(0)}
.menu .grp{display:grid;gap:4px;align-content:start}
.menu .grp > .kicker{padding:6px 12px 8px}
/* :not(.btn) so the panel's own call-to-action keeps its pill padding and
   radius instead of being flattened into a menu row like the links around it */
.menu a:not(.btn){display:flex;gap:11px;padding:11px 12px;border-radius:var(--r-sm);transition:background .2s}
.menu a:not(.btn):hover{background:var(--hover-soft)}
.menu .ic{
  width:34px;height:34px;flex-shrink:0;border-radius:10px;
  display:grid;place-items:center;
}
.menu .ic svg{width:18px;height:18px}
.menu .t{display:block;font-size:14.5px;color:var(--text);font-weight:500;line-height:1.3}
.menu .d{display:block;font-size:12px;color:var(--muted);line-height:1.45;margin-top:2px}
.menu-foot{
  background:linear-gradient(150deg,rgba(47,143,212,.16),rgba(19,96,196,.05));
  border:1px solid var(--line);border-radius:var(--r-sm);padding:16px;
  align-content:start;gap:10px;
}
.menu-foot .d{font-size:12.5px}

/* burger + mobile sheet */
.burger{display:none;background:none;border:0;padding:8px}
.burger span{display:block;width:22px;height:1.5px;background:var(--text);margin:5px 0;transition:.25s;border-radius:2px}
.burger.on span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.burger.on span:nth-child(2){opacity:0}
.burger.on span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

.mobile-menu{
  position:fixed;inset:76px 0 0 0;z-index:99;
  background:var(--veil-solid);
  -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
  overflow-y:auto;padding:24px var(--pad) 60px;
}
.mm-inner{display:grid;gap:4px;max-width:var(--max);margin-inline:auto}
.mobile-menu a{padding:13px 4px;font-size:17px;border-bottom:1px solid var(--line)}
.mobile-menu .kicker{margin-top:22px;margin-bottom:6px}
.mobile-menu .mm-sub{font-size:15px;color:var(--soft);padding-left:14px}
.mobile-menu .btn{margin-top:22px;border-bottom:0}
.mm-call{text-align:center;color:var(--muted);border-bottom:0}

/* ====================================================================== HERO */
.hero{
  position:relative;overflow:hidden;
  padding-top:calc(76px + clamp(48px,7vw,96px));
  padding-bottom:clamp(40px,6vw,72px);
  z-index:2;
}
.hero-glow{position:absolute;inset:0;pointer-events:none;z-index:0}
.hero-glow i{
  position:absolute;display:block;border-radius:50%;filter:blur(10px);
  width:52vw;height:52vw;max-width:720px;max-height:720px;
  animation:drift 26s ease-in-out infinite alternate;
}
.hero-glow i:nth-child(1){
  top:-16%;left:-8%;
  background:radial-gradient(closest-side,var(--glow-1),transparent 70%);
}
.hero-glow i:nth-child(2){
  top:6%;right:-14%;
  background:radial-gradient(closest-side,var(--glow-2),transparent 70%);
  animation-delay:-13s;animation-duration:31s;
}
.hero-glow.small i{width:60vw;height:38vw;max-height:420px;top:-30%;left:50%;translate:-50% 0}
@keyframes drift{
  from{transform:translate3d(-3%,-2%,0) scale(1)}
  to  {transform:translate3d(4%,3%,0) scale(1.12)}
}
.hero-grid{
  position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:
    linear-gradient(var(--grid-line) 1px,transparent 1px),
    linear-gradient(90deg,var(--grid-line) 1px,transparent 1px);
  background-size:76px 76px;
  -webkit-mask-image:radial-gradient(ellipse 75% 55% at 50% 32%,#000 20%,transparent 78%);
  mask-image:radial-gradient(ellipse 75% 55% at 50% 32%,#000 20%,transparent 78%);
}
.hero-split{
  position:relative;z-index:2;
  display:grid;grid-template-columns:1.05fr .95fr;
  gap:clamp(28px,4vw,64px);align-items:center;
}
.hero-copy{display:grid;gap:22px;justify-items:start}
.hero-copy h1{max-width:15ch}
.hero-copy .lead{max-width:54ch}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap}

.hero-stats{
  position:relative;z-index:2;
  margin-top:clamp(40px,5vw,64px);padding:32px 0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  display:grid;grid-template-columns:repeat(4,1fr);gap:var(--gap);text-align:center;
}
.hero-stats .n{font-family:var(--display);font-size:clamp(28px,3.4vw,42px);letter-spacing:-.03em}
.hero-stats .l{font-size:13px;color:var(--muted);margin-top:5px}

/* The counters now sit a third of the way down rather than in the hero, so
   they need the rules the hero used to give them. */
/* The section after this one carries padding-top:0, so this bottom padding is
   the entire gap between the counters and the next heading. At 0 the two sat
   almost touching. */
.stats-band{padding-bottom:clamp(56px,7.5vw,104px)}
.stats-band .hero-stats{margin-top:0}

/* --------------------------------------------------------------- clients
   Set in the display face rather than boxed into cards. These are four names,
   and four cards would make a thin thing look like it was trying to fill a
   grid; as a line of type they read the way a reference list should. */
.clients{
  position:relative;z-index:2;
  margin-top:clamp(40px,5vw,64px);padding:26px 0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:clamp(20px,3vw,44px);flex-wrap:wrap;
}
.clients .kicker{flex-shrink:0}
.clients ul{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:clamp(18px,3.2vw,46px);flex:1;
}
.clients li{display:grid;gap:2px}
.c-name{
  font-family:var(--display);font-size:clamp(19px,2.1vw,26px);
  letter-spacing:-.02em;color:var(--soft);line-height:1.15;
  transition:color .25s;
}
.clients li:hover .c-name{color:var(--text)}
.c-sector{font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}

/* ----------------------------------------------------------- hero shot
   The real range, photographed. This replaced ~150 lines of pure-CSS 3D that
   drew an approximation of a cartridge — no drawing competes with the actual
   containers a buyer has on their own shelf.

   The photograph carries its own lit background, so it sits as a panel rather
   than floating free like the drawing did: rounded, edged, and lifted off the
   page with a shadow that is themed like every other one here. */
.hero-shot{
  position:relative;z-index:2;margin:0;
  border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line);
  box-shadow:0 34px 70px -34px var(--obj-cast);
  animation:heroFloat 9s ease-in-out infinite;
}
.hero-shot img{
  width:100%;height:auto;display:block;
  /* The studio background is a bright blue; on the dark theme it is held back
     the same way the product cards hold their photographs back. */
  filter:var(--shot-filter);
}
@keyframes heroFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}

@media (prefers-reduced-motion:reduce){
  .hero-glow i,.chip .dot,.hero-shot{animation:none}
  html{scroll-behavior:auto}
}


/* ============================================================== SECTION HEAD */
.sec-head{display:grid;gap:12px;margin-bottom:clamp(30px,3.4vw,46px);justify-items:start}
.sec-head.center{justify-items:center;text-align:center}
.sec-head h2{max-width:22ch}
.sec-head.center h2{max-width:26ch}

/* ================================================================ CATALOGUE
   The brochure download. One wide target rather than a small link: the whole
   panel is the anchor, so the icon, the words and the button all download it. */
.catalogue{
  display:flex;align-items:center;gap:clamp(18px,2.6vw,32px);flex-wrap:wrap;
  padding:clamp(22px,2.8vw,30px) clamp(22px,3vw,34px);
  border-radius:var(--r-lg);border:1px solid var(--line);
  background:linear-gradient(150deg,var(--film),var(--film-2));
  transition:.28s cubic-bezier(.4,0,.2,1);
}
.catalogue:hover{
  border-color:rgba(47,143,212,.45);transform:translateY(-2px);
  box-shadow:0 24px 50px -28px var(--obj-cast);
}
.cat-ic{
  flex-shrink:0;display:grid;place-items:center;
  width:60px;height:60px;border-radius:18px;color:var(--chip-fg);
  background:linear-gradient(150deg,var(--brand-lite),var(--brand-deep));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.3),0 12px 26px -14px var(--brand);
}
.cat-ic svg{width:27px;height:27px}
.cat-txt{display:grid;gap:7px;flex:1 1 300px}
.cat-txt .h-sm{color:var(--text);letter-spacing:-.025em;font-family:var(--display)}
.cat-txt .small{max-width:52ch}
.cat-go{display:grid;gap:9px;justify-items:center;flex-shrink:0}
/* a span styled as the button — a real <button> cannot live inside an <a> */
.catalogue .btn{pointer-events:none}
.catalogue:hover .btn{transform:translateY(-2px);box-shadow:0 14px 34px -10px var(--invert-glow)}
.catalogue .arrow{transition:transform .25s}
.catalogue:hover .arrow{transform:translateY(3px)}

@media (max-width:620px){
  .catalogue{gap:16px}
  .cat-go{justify-items:stretch;width:100%}
  .cat-go .btn{width:100%}
  .cat-go .small{text-align:center}
}

/* ============================================================ FAMILY CARDS */
.fam-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--gap)}
.fam-grid.four{grid-template-columns:repeat(4,1fr)}

/* Flex column rather than grid, purely so .fam-go can take margin-top:auto and
   sit on the baseline of every card in the row. With auto grid rows the link
   follows the copy, and eight blurbs of three to five lines leave the whole
   grid visibly ragged along the bottom. */
.fam{
  position:relative;display:flex;flex-direction:column;gap:11px;
  padding:26px 24px 24px;border-radius:var(--r-md);
  border:1px solid var(--line);
  background:linear-gradient(150deg,var(--film),var(--film-2));
  transition:.3s cubic-bezier(.4,0,.2,1);overflow:hidden;
}
/* the tint only shows on hover — a wall of eight saturated cards is a lot to
   look at, and the colour means more when it responds to you */
.fam::before{
  content:"";position:absolute;inset:0;opacity:0;transition:opacity .3s;
  background:radial-gradient(120% 90% at 12% 0%,var(--tint-base),transparent 72%);
}
.fam > *{position:relative;z-index:1}
.fam:hover{
  transform:translateY(-4px);border-color:var(--line-strong);
  box-shadow:0 24px 50px -24px var(--tint-acc);
}
.fam:hover::before{opacity:.55}
/* The product shot sits in a band across the top of the card, bled to the
   card's own edges — hence the negative margins, which undo the card padding
   on three sides only. */
.fam-shot{
  position:relative;
  display:block;margin:-26px -24px 4px;overflow:hidden;
  border-radius:var(--r-md) var(--r-md) 0 0;
  background:var(--surface-2);
}
.fam-shot img{
  width:100%;height:auto;aspect-ratio:4 / 3;object-fit:cover;
  transition:transform .5s cubic-bezier(.4,0,.2,1);
  filter:var(--shot-filter);
}
/* A tall bottle cropped to 4:3 from its centre loses its cap and the top of the
   label — which is where the product's name is. Biasing the window upward keeps
   the name in frame and costs only the base of the bottle. The generator tags
   these by reading the file's header, so a photo supplied later gets it too. */
.fam-shot img.is-portrait{object-position:center 30%}
.fam:hover .fam-shot img{transform:scale(1.045)}

/* A photograph is a bright rectangle, and against a near-black card it ended at
   a hard lit line along the bottom — the picture read as pasted onto the card
   rather than part of it. This dissolves the last fifth of the image into the
   card's own ground, and takes the top edge down a little so the picture sits
   under the rounded corner instead of glowing against it. It replaces a
   border-bottom, which was drawing the very line that had to go. */
.fam-shot::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--shot-veil);
}

/* No icon badge on a card any more: the line icon survives in the mega menu,
   where a row is too small for a product shot. On a card the two together were
   redundant, and the badge sat on top of the bottle it was drawing. */
.fam-k{font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--tint-acc);font-weight:600}
.fam h3{letter-spacing:-.025em}
.fam p{color:var(--muted)}
.fam-go{
  margin-top:auto;padding-top:8px;font-size:13.5px;color:var(--soft);
  display:inline-flex;align-items:center;gap:7px;transition:gap .25s;
}
.fam:hover .fam-go{gap:11px;color:var(--text)}

/* the eight ink tints, applied by class from the data file */
.tint-cyan   {--tint-base:var(--cyan);   --tint-ink:var(--cyan-ink);   --tint-acc:var(--cyan-acc)}
.tint-blue   {--tint-base:var(--blue);   --tint-ink:var(--blue-ink);   --tint-acc:var(--blue-acc)}
.tint-magenta{--tint-base:var(--magenta);--tint-ink:var(--magenta-ink);--tint-acc:var(--magenta-acc)}
.tint-amber  {--tint-base:var(--amber);  --tint-ink:var(--amber-ink);  --tint-acc:var(--amber-acc)}
.tint-green  {--tint-base:var(--green);  --tint-ink:var(--green-ink);  --tint-acc:var(--green-acc)}
.tint-violet {--tint-base:var(--violet); --tint-ink:var(--violet-ink); --tint-acc:var(--violet-acc)}
.tint-steel  {--tint-base:var(--steel);  --tint-ink:var(--steel-ink);  --tint-acc:var(--steel-acc)}
.tint-red    {--tint-base:var(--red);    --tint-ink:var(--red-ink);    --tint-acc:var(--red-acc)}
.menu .ic{background:var(--tint-acc);color:var(--chip-fg)}

/* ================================================================== PILLARS */
.pillar-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.pillar{
  display:grid;gap:10px;align-content:start;
  padding:26px 24px;border-radius:var(--r-md);
  border:1px solid var(--line);background:var(--surface);
  transition:.28s cubic-bezier(.4,0,.2,1);
}
.pillar:hover{border-color:rgba(63,189,240,.4);transform:translateY(-3px);background:var(--surface-2)}
.p-ic{
  width:44px;height:44px;border-radius:13px;display:grid;place-items:center;font-size:20px;
  background:linear-gradient(150deg,rgba(47,143,212,.3),rgba(19,96,196,.12));
  border:1px solid rgba(63,189,240,.24);
}

/* ==================================================================== STEPS */
.steps{
  display:grid;grid-template-columns:repeat(4,1fr);gap:var(--gap);
  counter-reset:step;position:relative;
}
.step{
  position:relative;display:grid;gap:10px;align-content:start;
  padding-top:26px;border-top:1px solid var(--line);
}
.step::after{
  content:"";position:absolute;inset:-1px auto auto 0;width:34%;height:2px;
  background:var(--spectrum-soft);border-radius:2px;
}
.s-n{
  font-family:var(--display);font-size:15px;color:var(--accent-ink);letter-spacing:.06em;
}

/* =============================================================== INDUSTRIES */
.ind-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap)}
.ind-grid.wide{grid-template-columns:repeat(2,1fr)}
.ind{
  display:flex;gap:15px;align-items:flex-start;
  padding:22px;border-radius:var(--r-md);
  border:1px solid var(--line);background:var(--surface);transition:.26s;
}
.ind:hover{border-color:rgba(63,189,240,.35);background:var(--surface-2)}
.i-ic{
  flex-shrink:0;width:42px;height:42px;border-radius:12px;
  display:grid;place-items:center;font-size:19px;
  background:linear-gradient(150deg,rgba(47,143,212,.26),rgba(19,96,196,.08));
  border:1px solid rgba(63,189,240,.2);
}
.ind h3{margin-bottom:5px}

/* ====================================================================== TAGS */
.tag-wrap{display:flex;flex-wrap:wrap;gap:10px}
.tag{
  padding:9px 17px;border-radius:var(--r-pill);font-size:13.5px;color:var(--soft);
  border:1px solid var(--line);background:var(--film-soft);transition:.2s;
}
.tag:hover{border-color:rgba(47,143,212,.55);color:var(--text)}

/* ==================================================================== FAULTS */
.fault-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--gap)}
.fault{
  padding:24px;border-radius:var(--r-md);border:1px solid var(--line);
  background:linear-gradient(150deg,var(--film),var(--film-2));
}
.fault h3{margin-bottom:8px;color:var(--accent-ink)}

/* ======================================================================= FAQ */
.faq-wrap{display:grid;grid-template-columns:.85fr 1.15fr;gap:clamp(28px,4vw,64px);align-items:start}
.faq-wrap .sec-head{margin-bottom:0;position:sticky;top:110px}
.faq{display:grid;gap:0;border-top:1px solid var(--line)}
.faq-item{border-bottom:1px solid var(--line)}
.faq-q{
  width:100%;display:flex;align-items:flex-start;justify-content:space-between;gap:20px;
  padding:22px 0;background:none;border:0;text-align:left;
  font-size:16.5px;color:var(--soft);transition:color .2s;line-height:1.45;
}
.faq-q:hover{color:var(--text)}
.faq-q .pm{
  flex-shrink:0;width:26px;height:26px;border-radius:50%;
  display:grid;place-items:center;font-size:17px;line-height:1;
  border:1px solid var(--line-strong);color:var(--accent-ink);
  transition:.28s cubic-bezier(.4,0,.2,1);
}
.faq-item.open .faq-q{color:var(--text)}
.faq-item.open .pm{transform:rotate(45deg);background:var(--brand);color:#fff;border-color:transparent}
.faq-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .32s cubic-bezier(.4,0,.2,1)}
.faq-a > p{overflow:hidden;font-size:14.5px;color:var(--muted);line-height:1.68}
.faq-item.open .faq-a{grid-template-rows:1fr}
.faq-item.open .faq-a > p{padding-bottom:24px}

/* ======================================================================= CTA */
.cta{
  position:relative;overflow:hidden;text-align:center;
  display:grid;gap:16px;justify-items:center;
  padding:clamp(40px,6vw,76px) clamp(24px,5vw,64px);
  border-radius:var(--r-xl);border:1px solid var(--line);
  background:var(--panel);
}
.cta-glow{
  position:absolute;inset:auto 50% -60% auto;translate:50% 0;
  width:min(120%,900px);aspect-ratio:2/1;
  background:radial-gradient(closest-side,rgba(47,143,212,.4),transparent 70%);
  filter:blur(8px);
}
/* :not(.cta-glow) is doing real work. This rule and .cta-glow above carry the
   same specificity, so as the later one it was winning and turning the glow
   from absolute back to relative — which put a decorative 450px-tall div into
   the grid as its own row and pushed every line of the panel that far down. */
.cta > *:not(.cta-glow){position:relative;z-index:1}
.cta h2{max-width:20ch}
.cta .lead{max-width:62ch}
.cta .hero-cta{justify-content:center;margin-top:6px}

/* ================================================================ PAGE HEAD */
.page-head{
  position:relative;overflow:hidden;z-index:2;
  padding-top:calc(76px + clamp(44px,6vw,84px));
  padding-bottom:clamp(28px,4vw,52px);
  border-bottom:1px solid var(--line);
}
.page-head.tall{padding-bottom:clamp(48px,7vw,90px)}
.page-head .wrap{position:relative;z-index:2;display:grid;gap:18px;justify-items:start}
.page-head.tall .wrap,.page-head .wrap.center{justify-items:center;text-align:center}
.page-head h1{max-width:19ch}
.page-head .lead{max-width:66ch}

.crumbs{display:flex;flex-wrap:wrap;gap:8px;font-size:13px;color:var(--dim)}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--text)}

/* ---------------------------------------------------------- product header */
.page-head.prod .wrap.prod-head{
  grid-template-columns:1.25fr .75fr;gap:clamp(24px,4vw,56px);
  align-items:center;justify-items:stretch;
}
.prod-head > div:first-child{display:grid;gap:16px;justify-items:start}
.prod-art{position:relative;display:grid;place-items:center;min-height:210px}
.pa-glow{
  position:absolute;width:76%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(closest-side,var(--tint-base),transparent 70%);
  filter:blur(6px);opacity:.9;
}
.prod-art img{
  position:relative;width:100%;max-width:340px;height:auto;
  border-radius:var(--r-md);
  filter:var(--shot-filter) var(--shadow-art);
}

/* ---------------------------------------------------------- product body */
.prod-body{display:grid;grid-template-columns:1.35fr .65fr;gap:clamp(28px,4vw,60px);align-items:start}
.prod-main{display:grid;gap:20px}
.prod-main > p{color:var(--soft);font-size:16px;line-height:1.72;max-width:70ch}

.range{display:grid;gap:2px}
.range li{
  display:flex;gap:14px;align-items:flex-start;
  padding:16px 0;border-bottom:1px solid var(--line);
}
.range li:first-child{border-top:1px solid var(--line)}
.r-dot{
  flex-shrink:0;width:9px;height:9px;margin-top:7px;border-radius:50%;
  background:var(--tint-acc,var(--accent-ink));box-shadow:0 0 10px var(--tint-acc,var(--accent-ink));
}
.r-code{display:block;font-size:15.5px;color:var(--text);font-weight:500;letter-spacing:-.01em}
.range p{margin-top:3px}

/* The printers a range fits, on each product page. A plain list rather than the
   home page's scrolling rail: someone reading a product page is checking
   whether their own machine is on it, and a moving strip is the wrong shape for
   a question with a yes/no answer. */
.fitment-list{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));
  gap:0 22px;
}
.fitment-list li{
  display:flex;align-items:center;gap:11px;
  padding:11px 0;border-bottom:1px solid var(--line);
  font-size:15.5px;color:var(--soft);letter-spacing:-.01em;
}
.fitment-list li::before{
  content:"";flex-shrink:0;width:7px;height:7px;border-radius:50%;
  background:var(--tint-acc,var(--accent-ink));
}

.notes{
  display:grid;gap:12px;padding:24px;border-radius:var(--r-md);
  border:1px solid var(--line);
  background:linear-gradient(150deg,rgba(47,143,212,.12),var(--film-2));
}
.notes ul{display:grid;gap:11px}
.notes li{
  position:relative;padding-left:22px;font-size:14.5px;color:var(--soft);line-height:1.6;
}
.notes li::before{
  content:"";position:absolute;left:0;top:9px;width:9px;height:2px;border-radius:2px;
  background:var(--spectrum-soft);
}

/* --------------------------------------------------------------- side rail */
.prod-side,.about-side,.contact-side{display:grid;gap:var(--gap);align-content:start;position:sticky;top:104px}
.spec{
  display:grid;gap:14px;padding:24px;border-radius:var(--r-md);
  border:1px solid var(--line);background:var(--surface);
}
.spec dl{display:grid;gap:0;margin:0}
.spec dl > div{
  display:grid;gap:3px;padding:13px 0;border-bottom:1px solid var(--line);
}
.spec dl > div:last-child{border-bottom:0;padding-bottom:0}
.spec dt{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
.spec dd{margin:0;font-size:14.5px;color:var(--soft);line-height:1.55}
.spec dd a{color:var(--accent-ink);border-bottom:1px solid transparent}
.spec dd a:hover{border-bottom-color:var(--accent-ink)}

.side-cta{
  display:grid;gap:12px;justify-items:start;padding:24px;border-radius:var(--r-md);
  border:1px solid rgba(63,189,240,.24);
  background:linear-gradient(155deg,rgba(47,143,212,.18),rgba(19,96,196,.05));
}

/* ==================================================================== ABOUT */
.about-grid{display:grid;grid-template-columns:1.35fr .65fr;gap:clamp(28px,4vw,60px);align-items:start}
.about-copy{display:grid;gap:18px}
.about-copy p{color:var(--soft);font-size:16px;line-height:1.72;max-width:70ch}
.about-copy h2{margin-top:14px}

/* ================================================================== CONTACT */
.contact-grid{display:grid;grid-template-columns:1.35fr .65fr;gap:clamp(28px,4vw,60px);align-items:start}
.enquiry{
  display:grid;gap:18px;padding:clamp(24px,3vw,34px);border-radius:var(--r-lg);
  border:1px solid var(--line);background:var(--surface);
}
.enquiry .row{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.enquiry label{display:grid;gap:8px;font-size:13px;letter-spacing:.04em;color:var(--muted)}
.enquiry input,.enquiry select,.enquiry textarea{
  width:100%;padding:13px 15px;border-radius:var(--r-sm);
  background:var(--field);border:1px solid var(--line);
  color:var(--text);font:inherit;font-size:15px;transition:.2s;
}
.enquiry textarea{resize:vertical;min-height:110px}
.enquiry input::placeholder,.enquiry textarea::placeholder{color:var(--dim)}
.enquiry input:focus,.enquiry select:focus,.enquiry textarea:focus{
  outline:0;border-color:rgba(63,189,240,.6);background:rgba(47,143,212,.08);
  box-shadow:0 0 0 3px rgba(47,143,212,.14);
}
.enquiry select{appearance:none;cursor:pointer}

/* ---------------------------------------------------- grade tick-boxes
   Every selector here is prefixed with .enquiry deliberately. `.enquiry label`
   is (0,1,1) and sets display:grid — a bare `.check` at (0,1,0) loses to it,
   and each tick-box would stack above its own text instead of sitting beside
   it. The prefix takes these to (0,2,0) and they win. */
.enquiry .grades{
  border:1px solid var(--line);border-radius:var(--r-md);
  margin:0;padding:18px 20px 20px;
  display:grid;gap:20px;background:var(--film-2);
}
.enquiry .grades > legend{
  padding:0 8px;font-size:13px;letter-spacing:.04em;color:var(--soft);
}
.enquiry .grades > legend .dim{font-size:12px;color:var(--dim);letter-spacing:0}
.enquiry .grade-group{display:grid;gap:9px}
.enquiry .g-title{
  font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--tint-acc);font-weight:600;
}
.enquiry .checks{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));
  gap:2px 18px;
}
.enquiry .check{
  display:flex;align-items:flex-start;gap:9px;
  font-size:13.5px;line-height:1.4;color:var(--soft);
  letter-spacing:0;cursor:pointer;padding:5px 0;
}
.enquiry .check:hover{color:var(--text)}
.enquiry .check input{
  flex-shrink:0;width:16px;height:16px;margin:1px 0 0;padding:0;
  accent-color:var(--brand);cursor:pointer;
}
.enquiry .check input:focus-visible{outline:2px solid var(--accent-ink);outline-offset:2px}
.enquiry select option{background:var(--surface);color:var(--text)}
.enquiry .btn{justify-self:start}
.form-note{margin-top:-4px}
.form-note a{color:var(--accent-ink);border-bottom:1px solid transparent}
.form-note a:hover{border-bottom-color:var(--accent-ink)}
.form-note.sent{color:var(--green-acc)}
.form-note.failed{color:var(--amber-acc)}
.enquiry .btn[disabled]{opacity:.6;pointer-events:none}
/* The honeypot. Off-screen rather than display:none, because a bot that reads
   the stylesheet skips anything hidden — and clipped rather than a negative
   margin, so it cannot widen the page. */
.hp{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* =================================================================== FOOTER */
.footer{position:relative;z-index:2;padding-top:0;background:var(--foot-bg)}
.footer .wrap{padding-top:clamp(48px,6vw,80px);padding-bottom:34px}
.foot-grid{
  display:grid;grid-template-columns:1.6fr .8fr .8fr .8fr 1fr;
  gap:var(--gap);padding-bottom:44px;
}
.foot-brand{display:grid;gap:16px;align-content:start;max-width:38ch}
.foot-contact{display:grid;gap:5px;font-size:14px}
.foot-contact a{color:var(--accent-ink);width:fit-content;border-bottom:1px solid transparent}
.foot-contact a:hover{border-bottom-color:var(--accent-ink)}
.foot-col{display:grid;gap:9px;align-content:start;font-size:14px}
.foot-col .kicker{margin-bottom:3px}
.foot-col a{color:var(--muted);width:fit-content;transition:color .2s}
.foot-col a:hover{color:var(--text)}

/* The catalogue download. A bordered card rather than another line of link
   text: in a column of links, a link reads as a page. The arrow-into-tray icon
   and the "PDF · 6 pages · 1.0 MB" line are both there to say "file" before
   anyone clicks. */
.foot-catalogue{
  display:inline-flex;align-items:center;gap:13px;
  margin-top:4px;padding:12px 18px 12px 14px;
  border:1px solid var(--line);border-radius:var(--r-pill);
  background:var(--film);width:fit-content;
  transition:.25s cubic-bezier(.4,0,.2,1);
}
.foot-catalogue:hover{
  border-color:rgba(47,143,212,.5);background:var(--hover);transform:translateY(-1px);
}
.fc-ic{
  flex-shrink:0;display:grid;place-items:center;
  width:36px;height:36px;border-radius:50%;color:var(--chip-fg);
  background:linear-gradient(150deg,var(--brand-lite),var(--brand-deep));
}
.fc-ic svg{width:18px;height:18px;transition:transform .25s}
.foot-catalogue:hover .fc-ic svg{transform:translateY(2px)}
.fc-txt{display:grid;gap:2px;line-height:1.3}
.fc-txt b{font-size:14.5px;font-weight:500;color:var(--text)}
.fc-txt i{font-style:normal;font-size:11.5px;color:var(--dim);letter-spacing:.02em}

.foot-bar{
  display:grid;gap:12px;padding-top:26px;border-top:1px solid var(--line);
}

/* ==================================================== reveal on scroll */
.reveal{opacity:0;transform:translateY(18px);transition:opacity .6s cubic-bezier(.22,1,.36,1),transform .6s cubic-bezier(.22,1,.36,1)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none;transition:none}}

/* ========================================================== RESPONSIVE
   Four breakpoints, each doing one job: drop the four-across grids to two,
   collapse the split layouts to one column, swap the desktop nav for the
   sheet, then tighten what is left for a phone. */
/* The header row gives way in two steps. First the links tighten: at 1140 the
   row is already 16px over, and trimming the link padding buys back more than
   the overflow without the lockup moving. */
@media (max-width:1140px){
  .nav-inner{gap:16px}
  .nav-links > ul > li > a,.nav-trigger{padding:9px 11px}
  .nav-actions{gap:9px}
}

@media (max-width:1080px){
  /* The header row runs out of width before the burger arrives: with the links
     still on show, the number was the item that broke -- over three lines at
     first, then shouldering the quote button off the edge. It steps out here
     instead, and is still one tap away in the Consumables panel. */
  .nav-phone{display:none}
  .fam-grid,.fam-grid.four{grid-template-columns:repeat(2,1fr)}
  .steps{grid-template-columns:repeat(2,1fr)}
  .pillar-grid{grid-template-columns:repeat(2,1fr)}
  .ind-grid{grid-template-columns:repeat(2,1fr)}
  /* Four link columns, not three: with brand spanning the full width above
     them, three left the fourth stranded alone on a row of its own. */
  .foot-grid{grid-template-columns:repeat(4,1fr);row-gap:36px}
  .foot-brand{grid-column:1 / -1;max-width:52ch}
}

@media (max-width:920px){
  /* The switch moves into the sheet. Brand, toggle, quote button and burger do
     not fit across a 390px header without one of them being squeezed. */
  .nav-links,.nav-phone,.nav-actions .theme-toggle{display:none}
  .burger{display:block}
  .hero-split{grid-template-columns:1fr;gap:clamp(28px,6vw,48px)}
  .hero-copy{justify-items:center;text-align:center}
  .hero-copy h1,.hero-copy .lead{max-width:20ch}
  .hero-copy .lead{max-width:58ch}
  .hero-cta{justify-content:center}
  .hero-stats{grid-template-columns:repeat(2,1fr);row-gap:26px}
  /* kicker above the names, names two-up, rather than one long squeezed row */
  .clients{flex-direction:column;align-items:flex-start;gap:16px}
  .clients ul{display:grid;grid-template-columns:1fr 1fr;gap:16px 20px;width:100%}
  .prod-body,.about-grid,.contact-grid,.faq-wrap{grid-template-columns:1fr}
  .prod-side,.about-side,.contact-side{position:static}
  .faq-wrap .sec-head{position:static;margin-bottom:8px}
  .page-head.prod .wrap.prod-head{grid-template-columns:1fr}
  .prod-art{order:-1;min-height:150px}
  .ind-grid.wide{grid-template-columns:1fr}
  .fault-grid{grid-template-columns:1fr}
  /* Two and two, so the columns still pair off evenly. */
  .foot-grid{grid-template-columns:1fr 1fr}
}

@media (max-width:620px){
  .fam-grid,.fam-grid.four,.steps,.pillar-grid,.ind-grid{grid-template-columns:1fr}
  .enquiry .row{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr;row-gap:30px}
  .hero-stats{padding:26px 0}
  .wordmark i{letter-spacing:.26em;font-size:9px}
  .cta{border-radius:var(--r-lg)}

}
