/* ============================================================================
   SemperWise — the design system.

   THIS FILE IS THE TEMPLATE. Every page on the site loads it, so a change here
   changes the whole site. That is the point: it was extracted out of an inline
   <style> block on one page precisely so that the rest of the site could stop
   drifting away from it.

   Rules for working in here
   -------------------------
   1. Colour, spacing, radius and easing come from the tokens in :root. Do not
      write a new hex value into a component — add or reuse a token, so the
      dark/light switch keeps working. Anything hardcoded is a bug waiting for
      the other theme.
   2. The DARK theme is the base. The light theme is an override layer further
      down, under [data-theme="light"]. Light is what visitors get by default
      (see assets/js/nd-theme.js) — so when you add a component, style it for
      dark first and then check it on light before you call it done.
   3. Two bands stay dark in BOTH themes (#platform, #industries). Any
      [data-theme="light"] rule you add has to be checked against them or you
      get ink-on-navy text, which has already happened once.
   4. Paths are relative to this file: ../img/…, ../video/…. No PHP in here.

   Load order: this file, then page-level components. Nothing overrides it with
   !important; if you reach for that, the token is wrong.
   ========================================================================== */

:root{
  /* Brand constants — the same in both themes. */
  --navy:#03152d;--navy2:#062b58;--blue:#0b67c9;--cyan:#18c6dc;--orange:#ffad18;
  --maxw:1220px;--ease:cubic-bezier(.22,.61,.36,1);

  /* ---- SURFACES ----------------------------------------------------------
     Dark is the base; the [data-theme="light"] block further down overrides it.
     Every page background, card and border resolves through these four, which
     is what makes the switch reach past the hero and into the page. A component
     that writes a literal colour instead opts itself out of the switch — that
     is the bug to look for when something stays white in dark mode. */
  --bg:#081426;            /* the page itself                       */
  --surface:#0e2138;       /* cards, forms, panels raised off it    */
  --surface-2:#0a1a2e;     /* tinted bands, table stripes           */
  --line:rgba(120,200,240,.16);

  --ink:#e8f0f9;           /* body copy on --bg                     */
  --muted:#9db2c8;
  --soft:#0c1c30;
  --ice:#102944;

  --shadow-lg:0 30px 80px rgba(0,0,0,.42);--shadow-md:0 14px 35px rgba(0,0,0,.32);
}
/* ---------- reset ----------
   The template's own components each reset their own list and heading styles,
   which is why this block was missing for a while after the two stylesheets
   were merged — and why every page-level <ul> that did NOT belong to a
   component (.standards, .signal-list, …) came back with browser bullets and a
   40px indent. Element-level defaults belong here, once. */
*,*::before,*::after{box-sizing:border-box}
html{
  scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%;
  /* Anchor links land under a sticky header without this, and the thing you
     jumped to is the thing you cannot see. */
  scroll-padding-top:calc(var(--header-h,76px) + 16px);
}
ul,ol{margin:0;padding:0;list-style:none}
button{font:inherit;cursor:pointer}
svg,video{max-width:100%;display:block}
/* Removes the 300ms tap delay without disabling pinch-zoom. */
a,button,summary,[role="tab"]{touch-action:manipulation}
h1,h2,h3,h4{margin:0 0 .5em}
p{margin:0 0 1em}
p:last-child{margin-bottom:0}
body{margin:0;font-family:Manrope,Arial,sans-serif;color:var(--ink);background:var(--bg);overflow-x:hidden;line-height:1.6}
a{text-decoration:none;color:inherit}
img{max-width:100%;display:block}
.container{width:min(var(--maxw),92%);margin:auto}
:focus-visible{outline:3px solid var(--orange);outline-offset:3px}
.skip{position:absolute;left:-9999px;background:var(--orange);color:#102d4e;padding:12px 18px;z-index:200;font-weight:800}
.skip:focus{left:12px;top:12px}
.progress{position:fixed;top:0;left:0;height:3px;width:100%;z-index:90;pointer-events:none}
.progress i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--blue),var(--cyan),var(--orange))}

/* ---------- top bar ---------- */
.topbar{background:#021126;color:#9fb8cf;font-size:11px;padding:8px 0;letter-spacing:.5px}
.topbar .container{display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap}
.topbar a:hover{color:#fff}
.topbar .tb-right{display:flex;gap:20px;flex-wrap:wrap}

/* ---------- header + MEGA MENU ---------- */
header{position:sticky;top:0;z-index:80;background:rgba(3,14,30,.86);backdrop-filter:blur(16px);
  border-bottom:1px solid rgba(120,200,240,.12);transition:background .3s var(--ease),box-shadow .3s var(--ease)}
header.solid{background:rgba(3,14,30,.97);box-shadow:0 10px 34px rgba(0,0,0,.3)}
.hdr{display:flex;align-items:center;justify-content:space-between;gap:20px;min-height:76px}
.brand{display:flex;align-items:center;gap:12px;flex:none}
.brand img{width:52px;height:46px;object-fit:contain;filter:drop-shadow(0 3px 10px rgba(24,198,220,.35))}
.brand-word{font-family:"Space Grotesk",sans-serif;font-size:21px;font-weight:700;color:#fff;letter-spacing:-.3px;line-height:1.05;display:block}
.brand-word em{font-style:normal;color:var(--cyan)}
.brand-tag{display:block;color:#8fb0cc;font-size:8.5px;letter-spacing:2.2px;font-weight:700;margin-top:2px}
.nav{display:flex;align-items:center;gap:4px}
.nav-list{display:flex;align-items:center;gap:2px;list-style:none;margin:0;padding:0}
.nav-trigger,.nav-link{background:none;border:0;color:#d7e7f7;font:600 12.5px/1 Manrope,sans-serif;padding:13px 14px;cursor:pointer;display:inline-flex;align-items:center;gap:7px;border-radius:5px;transition:background .22s var(--ease),color .22s var(--ease)}
.nav-trigger:hover,.nav-link:hover,.has-mega.open .nav-trigger{background:rgba(255,255,255,.09);color:#fff}
.chev{width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg) translateY(-2px);transition:transform .25s var(--ease)}
.has-mega.open .chev{transform:rotate(-135deg) translateY(-2px)}
.has-mega{position:static}
.mega{position:absolute;left:0;right:0;top:100%;background:#041d3a;border-top:1px solid rgba(120,200,240,.16);
  box-shadow:0 34px 70px rgba(0,0,0,.42);opacity:0;visibility:hidden;transform:translateY(-10px);
  transition:opacity .26s var(--ease),transform .26s var(--ease),visibility .26s;z-index:85}
.has-mega.open .mega{opacity:1;visibility:visible;transform:none}
.mega-inner{width:min(var(--maxw),94%);margin:auto;display:grid;grid-template-columns:1fr 300px;gap:38px;padding:34px 0 38px}
.mega-cols{display:grid;gap:26px}
.mega-cols--2{grid-template-columns:repeat(2,1fr)}
.mega-cols--3{grid-template-columns:repeat(3,1fr)}
.mega-cols--4{grid-template-columns:repeat(4,1fr)}
.mega-title{font:800 9.5px/1 Manrope,sans-serif;letter-spacing:2px;text-transform:uppercase;color:var(--orange);margin:0 0 14px}
.mega-links{list-style:none;padding:0;margin:0}
.mega-links li{margin-bottom:3px}
.mega-links a{display:block;padding:8px 10px;border-radius:6px;transition:background .2s var(--ease),transform .2s var(--ease)}
.mega-links a:hover{background:rgba(255,255,255,.07);transform:translateX(3px)}
.mega-links b{display:block;color:#fff;font-size:13.5px;font-weight:700}
.mega-links small{display:block;color:#8fb0cc;font-size:11.5px;line-height:1.55;margin-top:3px}
.mega-promo{background:linear-gradient(150deg,#06315e,#0a6fc7);border-radius:10px;padding:26px;color:#fff;align-self:start}
.mega-promo-tag{display:inline-block;background:rgba(255,255,255,.16);padding:5px 10px;border-radius:20px;font-size:8.5px;letter-spacing:1.6px;font-weight:800;text-transform:uppercase}
.mega-promo h3,.mega-promo p.mega-promo-h{font-family:"Space Grotesk",sans-serif;font-size:19px;line-height:1.25;color:#fff;margin:12px 0 8px}
.mega-promo p{font-size:11.5px;line-height:1.7;color:#d3e7f8;margin:0 0 16px}
.mega-promo img{width:88px;height:78px;object-fit:contain;margin-bottom:10px}
.link-arrow{display:block;margin-top:11px;font-size:11px;font-weight:700;color:#9fe4f2}
/* On the promo tile the ground is lighter than the panel, so the general
   .link-arrow cyan drops to 3.6 there. */
.mega-promo .link-arrow{color:#e2f6fc}
.mega-foot{grid-column:1/-1;margin:6px 0 0;padding-top:16px;border-top:1px solid rgba(255,255,255,.1);font-size:11px;color:#8fb0cc}
.hdr-cta{display:flex;align-items:center;gap:12px;flex:none}
.hdr-cta .btn .btn-short{display:none}
.btn-sm{padding:10px 16px;font-size:10.5px}
.navtoggle{display:none;background:none;border:1px solid rgba(255,255,255,.3);color:#fff;width:44px;height:40px;border-radius:5px;cursor:pointer;font-size:17px}
.scrim{position:fixed;inset:0;background:rgba(2,10,22,.55);backdrop-filter:blur(2px);z-index:70;opacity:0;visibility:hidden;transition:opacity .26s var(--ease),visibility .26s}
.scrim.on{opacity:1;visibility:visible}
/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:9px;padding:14px 24px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.5px;border-radius:4px;cursor:pointer;border:0;transition:transform .25s var(--ease),box-shadow .25s var(--ease),background .25s var(--ease)}
.btn .arrow{transition:transform .3s var(--ease)}
.btn:hover .arrow{transform:translateX(5px)}
.btn-primary{background:var(--orange);color:#102d4e}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 14px 30px rgba(255,173,24,.36)}
.btn-outline{border:1px solid rgba(255,255,255,.4);color:#fff}
.btn-outline:hover{background:rgba(255,255,255,.1);transform:translateY(-2px)}
.btn-dark{background:var(--navy2);color:#fff}
.btn-dark:hover{transform:translateY(-2px);box-shadow:0 14px 30px rgba(6,43,88,.3)}

/* The secondary call to action, used beside .btn-primary on every service page
   and every .page-head. `.btn` sets no border and no colour of its own, so with
   this rule missing it rendered as a bare run of uppercase text next to the
   gold button — a button nobody could see was a button.

   It has to work on three different grounds: the page (which follows the
   theme), and the page banner and the closing CTA band (which stay dark in
   BOTH themes). Hence the second block. */
.btn-ghost{border:1px solid var(--line);color:var(--ink);background:transparent}
.btn-ghost:hover{border-color:var(--blue);color:var(--blue);transform:translateY(-2px)}
.page-head .btn-ghost,.svc-hero .btn-ghost,.cta-band .btn-ghost,
.section--dark .btn-ghost,.hero .btn-ghost{
  border-color:rgba(150,200,240,.34);color:#e8f0f9}
.page-head .btn-ghost:hover,.svc-hero .btn-ghost:hover,.cta-band .btn-ghost:hover,
.section--dark .btn-ghost:hover,.hero .btn-ghost:hover{
  border-color:var(--cyan);color:var(--cyan)}

/* ---------- hero (video + parallax) ---------- */
.hero{position:relative;overflow:hidden;color:#fff;padding:78px 0 92px;
  background:radial-gradient(circle at 50% 64%,rgba(18,116,211,.30),transparent 38%),
             linear-gradient(180deg,#020c1b 0%,#031b38 56%,#063b70 100%)}
.hero .layer{position:absolute;inset:0;will-change:transform;pointer-events:none}
.hero-glow{background:radial-gradient(ellipse 58% 44% at 50% 76%,rgba(18,171,223,.28),transparent 62%)}
.gridlines{left:-8%;right:-8%;bottom:-130px;top:auto;height:400px;opacity:.36;
  background-image:linear-gradient(rgba(83,188,235,.16) 1px,transparent 1px),linear-gradient(90deg,rgba(83,188,235,.16) 1px,transparent 1px);
  background-size:46px 46px;transform:perspective(420px) rotateX(58deg)}
.px-orb{position:absolute;border-radius:50%;filter:blur(64px);pointer-events:none;z-index:0}
.px-orb--cyan{background:rgba(24,198,220,.15)}.px-orb--blue{background:rgba(11,103,201,.17)}.px-orb--gold{background:rgba(255,173,24,.12)}
/* ---------- hero slider ---------- */
.hero-slider{position:relative;z-index:3}
.slides{position:relative}
.slide{display:grid;grid-template-columns:1.02fr .98fr;gap:50px;align-items:center;
  position:absolute;inset:0;opacity:0;visibility:hidden;transform:translateX(38px);
  transition:opacity .7s var(--ease),transform .7s var(--ease),visibility .7s;pointer-events:none}
.slide.on{position:relative;opacity:1;visibility:visible;transform:none;pointer-events:auto}
.no-anim .slide,.nojs-slide .slide{position:relative;opacity:1;visibility:visible;transform:none}
.slide-kicker{display:inline-flex;gap:9px;align-items:center;border:1px solid rgba(255,255,255,.26);
  padding:7px 13px;border-radius:30px;font-size:9.5px;letter-spacing:1.6px;text-transform:uppercase;
  color:#bde9ff;background:rgba(255,255,255,.05)}
.slide h1,.slide h2.slide-h{font-family:"Space Grotesk",sans-serif;font-size:clamp(34px,4.3vw,58px);
  line-height:1.02;letter-spacing:-2px;margin:18px 0 14px;font-weight:700;color:#fff}
.slide .accent{background:linear-gradient(95deg,#36d4e7,#7ce6f2 55%,#ffad18);-webkit-background-clip:text;background-clip:text;color:transparent}
.slide .lede{color:#c6d9ed;font-size:15.5px;line-height:1.8;max-width:560px;margin:0}
.slide .lede strong{color:#eaf4ff;font-weight:700}
.hero-actions{margin:24px 0 20px;display:flex;gap:11px;flex-wrap:wrap}
.hero-trust{list-style:none;display:flex;gap:20px;flex-wrap:wrap;padding:0;margin:0;font-size:12.5px;color:#a8c4dd}
.hero-trust li:before{content:"✓";color:#3ee08a;font-weight:900;margin-right:6px}
.slide-art{position:relative;border-radius:16px;border:1px solid rgba(120,200,240,.24);
  background:linear-gradient(160deg,rgba(8,38,74,.9),rgba(4,22,46,.92));box-shadow:0 34px 90px rgba(0,0,0,.42);
  aspect-ratio:16/11;display:grid;place-items:center}
/* The media is clipped rather than the panel, so the overhanging stat chips
   survive. Before this, .slide-art{overflow:hidden} cut them off at the
   border in both themes. 15px = the panel radius less its 1px border. */
.slide-art>video,.slide-art>svg,.video-veil{border-radius:15px}
.slide-art svg{width:100%;height:100%;display:block}
.slide-art--cycle{aspect-ratio:auto;min-height:330px;padding:6px}
.cy-stage{cursor:pointer}
.cy-stage .cy-node{transform-box:fill-box;transform-origin:center;
  transition:transform .25s var(--ease),filter .25s var(--ease)}
.cy-stage:hover .cy-node,.cy-stage:focus-visible .cy-node{transform:scale(1.45);filter:drop-shadow(0 0 8px rgba(63,216,232,.9))}
.cy-stage .cy-label{transition:fill .25s var(--ease)}
.cy-stage:hover .cy-label,.cy-stage:focus-visible .cy-label{fill:#fff}
.cy-stage:focus{outline:none}
.cy-stage:focus-visible .cy-label{text-decoration:underline}
#cyTitle,#cyBody{transition:opacity .2s var(--ease)}
.cy-swap #cyTitle,.cy-swap #cyBody{opacity:.25}
.slide-art video{width:100%;height:100%;object-fit:cover;display:block}
.video-veil{position:absolute;inset:0;background:linear-gradient(180deg,rgba(3,21,45,.06),rgba(3,21,45,.46));pointer-events:none}
/* Bottom-LEFT: bottom-right is where the KEV chip lives, and the two were
   overlapping once the chip stopped being clipped. */
.video-toggle{position:absolute;left:12px;bottom:12px;width:34px;height:34px;border-radius:50%;
  border:1px solid rgba(255,255,255,.35);background:rgba(3,21,45,.62);color:#fff;cursor:pointer;font-size:11px;backdrop-filter:blur(6px);z-index:3}
/* ---------- hero controls: one docked capsule ----------
   The slides are equal-height and the capsule is pinned to the bottom of the
   hero, so the controls stay put instead of jumping as each slide's text
   changes length — the old layout shifted vertically on every transition. */
.slides{position:relative;min-height:var(--slideh,430px)}
.hero-nav{position:relative;margin-top:26px;display:flex;justify-content:center}
.hero-capsule{display:inline-flex;align-items:center;gap:6px;padding:8px 10px;border-radius:60px;
  background:rgba(4,20,42,.72);border:1px solid rgba(120,200,240,.22);backdrop-filter:blur(14px);
  box-shadow:0 16px 40px rgba(0,0,0,.34)}
.hcap-btn{width:40px;height:40px;border-radius:50%;border:0;background:transparent;color:#cfe3f5;cursor:pointer;
  display:grid;place-items:center;transition:background .24s var(--ease),color .24s var(--ease),transform .24s var(--ease)}
.hcap-btn:hover{background:rgba(255,255,255,.12);color:#fff;transform:translateY(-1px)}
.hcap-btn svg{width:16px;height:16px}
.hcap-play{position:relative;width:44px;height:44px;background:rgba(255,173,24,.16);color:var(--orange)}
.hcap-play:hover{background:rgba(255,173,24,.26);color:#ffce6b}
.hcap-play .ring{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg);pointer-events:none}
.hcap-play .ring circle{fill:none;stroke-width:2}
.hcap-play .ring .bg{stroke:rgba(255,255,255,.12)}
.hcap-play .ring .fg{stroke:var(--orange);stroke-linecap:round;stroke-dasharray:126;stroke-dashoffset:126}
.hcap-play.running .ring .fg{animation:countdown var(--slidedur,7s) linear infinite}
@keyframes countdown{from{stroke-dashoffset:126}to{stroke-dashoffset:0}}
/* segmented progress — one segment per slide, the active one fills */
.hcap-segs{display:flex;gap:5px;padding:0 8px}
.hcap-segs button{position:relative;width:38px;height:4px;border-radius:4px;border:0;padding:0;cursor:pointer;
  background:rgba(255,255,255,.2);overflow:hidden;transition:width .4s var(--ease),background .3s var(--ease)}
.hcap-segs button:hover{background:rgba(255,255,255,.34)}
.hcap-segs button i{position:absolute;inset:0;width:0;background:linear-gradient(90deg,var(--cyan),var(--orange));border-radius:4px}
.hcap-segs button[aria-selected="true"]{width:62px}
.hcap-count{font-family:"Space Grotesk",sans-serif;color:#fff;font-size:12px;font-weight:700;padding:0 10px 0 4px;letter-spacing:.5px}
.hcap-count span{color:rgba(255,255,255,.42)}
@media(max-width:560px){
  .hcap-segs button{width:26px}.hcap-segs button[aria-selected="true"]{width:44px}
  .hero-capsule{gap:2px;padding:7px 8px}.hcap-count{display:none}
}

/* ---------- section header flourish ---------- */
.sec-head{position:relative}
.sec-rule{display:block;width:78px;height:3px;margin:0 0 16px;border-radius:3px;
  background:linear-gradient(90deg,var(--orange),var(--cyan));transform-origin:left;transform:scaleX(0);
  transition:transform .8s var(--ease) .15s}
.reveal.in .sec-rule,.in .sec-rule{transform:scaleX(1)}
.section--dark .sec-rule{background:linear-gradient(90deg,var(--cyan),var(--orange))}
.eyebrow-dot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--orange);margin-right:8px;vertical-align:middle}

/* ---------- capability cards: icon + spotlight ---------- */
.cap-grid{position:relative}
.cap-grid:hover .cap-card{opacity:.62;filter:saturate(.75)}
.cap-grid:hover .cap-card:hover{opacity:1;filter:none}
.cap-card{transition:transform .34s var(--ease),box-shadow .34s var(--ease),opacity .34s var(--ease),filter .34s var(--ease)}
.cap-num{position:absolute;right:16px;top:8px;font-family:"Space Grotesk",sans-serif;font-size:56px;font-weight:700;
  color:rgba(11,103,201,.07);line-height:1;pointer-events:none;transition:color .34s var(--ease),transform .34s var(--ease)}
.cap-card:hover .cap-num{color:rgba(11,103,201,.13);transform:translateY(-3px)}
.cap-card.feature .cap-num{color:rgba(255,255,255,.1)}
.cap-card.feature:hover .cap-num{color:rgba(255,255,255,.17)}
.cap-card{min-height:290px}
.cap-scene{position:absolute;right:-6px;bottom:-10px;width:186px;height:140px;color:var(--blue);
  opacity:0;transform:translateY(14px) scale(.94);pointer-events:none;
  transition:opacity .45s var(--ease),transform .45s var(--ease)}
.cap-scene svg{width:100%;height:100%;overflow:visible}
.cap-card:hover .cap-scene,.cap-card:focus-within .cap-scene{opacity:.22;transform:none}
.cap-card.feature .cap-scene{color:#a9e9f6}
.cap-card.feature:hover .cap-scene{opacity:.34}
.cap-card:hover .mini-list,.cap-card:hover p{position:relative;z-index:2}
.cap-ico{width:46px;height:46px;position:relative;z-index:2}
.cap-ico svg{width:100%;height:100%;overflow:visible}
.cap-ico .stroke{fill:none;stroke:var(--blue);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.feature .cap-ico .stroke{stroke:#8fe6f5}
.cap-ico .fillc{fill:var(--orange)}
.cap-card:hover .cap-ico .draw{animation:draw 1.1s var(--ease) forwards}
@keyframes draw{from{stroke-dashoffset:var(--len,120)}to{stroke-dashoffset:0}}
.cap-card .mini-list li{opacity:.86;transition:opacity .3s var(--ease),transform .3s var(--ease)}
.cap-card:hover .mini-list li{opacity:1;transform:translateX(3px)}

/* ---------- service cards: index + growing rail ---------- */
.svc-card{position:relative;overflow:hidden;padding-left:28px}
.svc-rail{position:absolute;left:0;top:0;bottom:0;width:4px;background:linear-gradient(180deg,var(--blue),var(--cyan));
  transform:scaleY(0);transform-origin:top;transition:transform .42s var(--ease)}
.svc-card:hover .svc-rail{transform:scaleY(1)}
.svc-idx{position:absolute;right:16px;bottom:8px;font-family:"Space Grotesk",sans-serif;font-size:46px;font-weight:700;
  color:rgba(9,36,69,.05);line-height:1;pointer-events:none;transition:color .34s var(--ease)}
.svc-card:hover .svc-idx{color:rgba(11,103,201,.11)}
.svc-more{display:inline-flex;align-items:center;gap:7px}
.svc-more .a{display:inline-block;transition:transform .3s var(--ease)}
.svc-card:hover .svc-more .a{transform:translateX(5px)}

.chip-float{position:absolute;display:flex;align-items:center;gap:10px;background:rgba(6,28,56,.88);
  border:1px solid rgba(120,200,240,.3);backdrop-filter:blur(9px);padding:10px 14px;border-radius:9px;
  font-size:11px;box-shadow:0 14px 34px rgba(0,0,0,.34);z-index:4}
.chip-float b{display:block;font-family:"Space Grotesk",sans-serif;font-size:13.5px;color:#fff}
.chip-float small{display:block;color:#9fc0dc;font-size:9.5px}
.chip-float .dot{width:9px;height:9px;border-radius:50%;background:#3fd8e8;flex:none}
.chip-float .dot--gold{background:var(--orange)}
.chip-a{left:-24px;top:14%}.chip-b{right:-20px;bottom:16%}

/* ---------- animated SVG bits ---------- */
.sweep{transform-origin:150px 105px;animation:sweep 4.2s linear infinite}
@keyframes sweep{to{transform:rotate(360deg)}}
.blip{transform-box:fill-box;transform-origin:center;animation:blip 3s ease-in-out infinite}
.blip:nth-of-type(2){animation-delay:.7s}.blip:nth-of-type(3){animation-delay:1.5s}.blip:nth-of-type(4){animation-delay:2.2s}
@keyframes blip{0%,100%{opacity:.15;transform:scale(.72)}50%{opacity:1;transform:scale(1.25)}}
.ringdash{stroke-dasharray:5 7;animation:dash 14s linear infinite}
@keyframes dash{to{stroke-dashoffset:-240}}
.tile{opacity:.35;animation:tilepulse 3.4s ease-in-out infinite}
@keyframes tilepulse{0%,100%{opacity:.3}50%{opacity:1}}
.flow{stroke-dasharray:4 9;animation:flow 2.6s linear infinite}
@keyframes flow{to{stroke-dashoffset:-52}}
.orbit-node{animation:nodepulse 2.8s ease-in-out infinite}
@keyframes nodepulse{0%,100%{opacity:.4}50%{opacity:1}}

/* ---------- traction ramp (hero slide 4) ----------
   The milestone ramp replays its draw every time the slide becomes active, so
   the animation is tied to `.slide.on` rather than to page load — otherwise it
   would have finished ~20s before the visitor ever reaches this slide. Every
   rule leaves the element in its finished state by default, which keeps the
   art readable in the no-JS / .no-anim fallback where no slide carries `.on`. */
.tr-line{stroke-dasharray:var(--trlen,300);stroke-dashoffset:0}
.slide.on .tr-line{animation:trDraw 2.2s var(--ease) both}
@keyframes trDraw{from{stroke-dashoffset:var(--trlen,300)}to{stroke-dashoffset:0}}
.slide.on .tr-area{animation:trFade 1.3s var(--ease) 1s both}
@keyframes trFade{from{opacity:0}to{opacity:1}}
.tr-mark{transform-box:fill-box;transform-origin:center}
.slide.on .tr-mark{animation:trPop .55s var(--ease) both;animation-delay:var(--d,0s)}
@keyframes trPop{from{opacity:0;transform:translateY(10px) scale(.72)}to{opacity:1;transform:none}}
.tr-spark{opacity:0}
.slide.on .tr-spark{opacity:1}
.hero-facts{list-style:none;padding:0;margin:20px 0 0;max-width:560px;display:grid;gap:9px}
.hero-facts li{position:relative;padding-left:20px;font-size:13px;line-height:1.65;color:#a8c4dd}
.hero-facts li:before{content:"";position:absolute;left:0;top:7px;width:8px;height:8px;border-radius:50%;
  background:linear-gradient(135deg,var(--cyan),var(--orange))}
.hero-facts b{color:#eaf4ff;font-weight:700}

/* ---------- pastel gradient cards ---------- */
.tint{border:0;border-radius:14px;overflow:hidden;position:relative}
.tint-a{background:linear-gradient(150deg,#16305c,#112748 55%,var(--surface))}
.tint-b{background:linear-gradient(150deg,#0f3a2c,#0d2c26 55%,var(--surface))}
.tint-c{background:linear-gradient(150deg,#46301a,#2e2318 55%,var(--surface))}
.tint-d{background:linear-gradient(150deg,#0e3a52,#0c2c42 55%,var(--surface))}
.tint-art{height:180px;display:grid;place-items:center;padding:16px}
.tint-art svg{width:100%;height:100%;max-height:150px}
/* A raised panel on the card's tinted ground. It was a hardcoded
   rgba(255,255,255,.9), which is the same trap as a literal hex: it does not
   follow the theme, so in dark mode the card's own near-white text was sitting
   on a near-white panel and the headline vanished. The earlier sweep for pale
   backgrounds only matched hex and walked straight past it. */
.tint-body{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.10);
  margin:0 16px 16px;padding:18px 20px;border-radius:10px}
.section--tinted{background:var(--surface-2)}
.section--tinted .head-split{grid-template-columns:.8fr 1.2fr;align-items:start;gap:44px}
.section--tinted .insight-grid{grid-template-columns:repeat(3,1fr)}
.section--tinted .insight{min-height:0}
.insight.tint:hover{transform:translateY(-6px);box-shadow:0 26px 60px rgba(3,21,45,.14)}
.tint-body small{display:block}
@media(max-width:980px){.section--tinted .head-split{grid-template-columns:1fr}.section--tinted .insight-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.section--tinted .insight-grid{grid-template-columns:1fr}}

/* The marquee and the four-across proof band were removed from the home page:
   a scrolling word ticker that was aria-hidden and unreadable while moving, and
   a stat bar that gave four different figures identical weight. Replaced by the
   ENGINE BAND further down this file. Their rules are gone rather than left
   behind — dead CSS is how a stylesheet starts lying about what the site does. */

/* ---------- sections ---------- */
/* ---------- vertical rhythm ----------
   Section padding is the single biggest thing on a page. Two adjacent sections
   contribute BOTH their paddings to the gap between them, so this number is
   doubled everywhere you actually see it — 76px here was a 152px gap, and on a
   measured interior page 28% of the total height was empty runs like that.

   The home page keeps the larger value: it is a handful of big statements and
   they need room. An interior page is seven or eight sections of substance and
   reads better tighter. `.is-home` / `.is-inner` come from layout-top.php. */
:root{ --section-y:76px }
.is-inner{ --section-y:52px }
.section{padding:var(--section-y) 0;position:relative}
.section--tight{padding:calc(var(--section-y) * .72) 0}
.section--paper{background:var(--surface-2)}
.section--dark{background:var(--navy);color:#fff;overflow:hidden}
.section--dark p,.section--dark .section-intro{color:#a9bfd6}
.section-label{color:#f28d00;text-transform:uppercase;font-size:11px;font-weight:800;letter-spacing:2.2px;margin:0}
.section h2{font-family:"Space Grotesk",sans-serif;font-size:clamp(26px,2.9vw,38px);line-height:1.12;letter-spacing:-1.3px;margin:10px 0 14px;font-weight:700}
.accent{color:var(--blue)}.section--dark .accent{color:var(--cyan)}
.section-intro{max-width:680px;color:var(--muted);line-height:1.82;font-size:15.5px;margin:0}
.head-split{display:grid;grid-template-columns:.92fr 1.08fr;gap:48px;align-items:end;margin-bottom:40px}

/* ---------- reveal / motion ---------- */
.js .reveal{opacity:0;transform:translateY(28px);transition:opacity .75s var(--ease),transform .75s var(--ease)}
.js .reveal.in,.no-anim .reveal{opacity:1!important;transform:none!important}
.reveal[data-d="1"]{transition-delay:.07s}.reveal[data-d="2"]{transition-delay:.14s}
.reveal[data-d="3"]{transition-delay:.21s}.reveal[data-d="4"]{transition-delay:.28s}
.reveal[data-d="5"]{transition-delay:.35s}
[data-px]{will-change:transform}

/* ---------- cards ---------- */
.cap-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.cap-card{background:var(--surface);border:1px solid var(--line);padding:26px;position:relative;overflow:hidden;transition:transform .32s var(--ease),box-shadow .32s var(--ease)}
.cap-card:hover{transform:translateY(-6px);box-shadow:var(--shadow-lg)}
.cap-card:after{content:"";position:absolute;left:0;top:0;height:3px;width:0;background:linear-gradient(90deg,var(--blue),var(--cyan));transition:width .45s var(--ease)}
.cap-card:hover:after{width:100%}
.cap-card.feature{background:linear-gradient(145deg,#06315e,#0a6fc7);color:#fff;border-color:transparent}
.cap-card.feature p{color:#d7e8f8}
.cap-card h3{font-family:"Space Grotesk",sans-serif;font-size:23px;margin:14px 0 8px}
.cap-card p{font-size:14px;line-height:1.72;color:var(--muted);margin:0}
.icon{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;background:var(--ice);color:var(--cyan);font-weight:800;font-family:"Space Grotesk",sans-serif;font-size:12px}
.feature .icon{background:rgba(255,255,255,.15);color:#fff}
.mini-list{padding:0;margin:16px 0 0;list-style:none;font-size:13px;line-height:2}
.mini-list li:before{content:"✓";color:var(--orange);font-weight:900;margin-right:7px}
.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.svc-card{background:var(--surface);border:1px solid var(--line);padding:24px;transition:transform .3s var(--ease),box-shadow .3s var(--ease),border-color .3s var(--ease)}
.svc-card:hover{transform:translateY(-5px);box-shadow:var(--shadow-md);border-color:#bcd8ee}
.svc-kicker{font-size:10.5px;letter-spacing:1.6px;text-transform:uppercase;color:var(--orange);font-weight:800}
.svc-card h3{font-family:"Space Grotesk",sans-serif;font-size:20px;margin:11px 0 7px;letter-spacing:-.3px}
.svc-card p{margin:0;font-size:13.5px;color:var(--muted);line-height:1.7}
.svc-more{display:inline-block;margin-top:13px;font-size:12px;font-weight:800;color:var(--blue)}
.svc-foot{margin-top:34px;text-align:center}
/* ---------- platform + dashboard ---------- */
.platform-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:13px;margin-bottom:44px}
.pgroup{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);padding:22px;border-radius:9px;transition:transform .3s var(--ease),background .3s var(--ease)}
.pgroup:hover{transform:translateY(-5px);background:rgba(255,255,255,.09)}
.pgroup h3{font-family:"Space Grotesk",sans-serif;font-size:20px;margin:10px 0 6px;color:#fff}
.pgroup .count{font-size:9px;color:var(--orange);font-weight:800;letter-spacing:1.4px;text-transform:uppercase}
.pgroup ul{list-style:none;padding:0;margin:13px 0 0;font-size:12.5px;line-height:1.9;color:#a9c2da}
.pgroup li:before{content:"▸";color:var(--cyan);margin-right:6px;font-size:9px}
.dash-wrap{perspective:1500px}
.dashboard{background:#0a2342;border:1px solid rgba(255,255,255,.14);border-radius:13px;padding:16px;box-shadow:0 34px 90px rgba(0,0,0,.36);transform:rotateX(var(--rx,4deg)) rotateY(var(--ry,-3deg));transition:transform .5s var(--ease)}
.dash-head{display:flex;justify-content:space-between;align-items:center;padding:3px 3px 13px;color:#a9bfd6;font-size:8.5px;letter-spacing:1.3px}
.dash-logo{font-weight:800;color:#fff;font-size:12px;font-family:"Space Grotesk",sans-serif;display:flex;align-items:center;gap:8px}
.dash-logo img{width:20px;height:18px;object-fit:contain}
.dash-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:10px}
.dash-panel{background:#071a31;border:1px solid rgba(255,255,255,.09);border-radius:8px;padding:14px;min-height:142px}
.dash-panel h4{margin:0 0 13px;font-size:9px;color:#9cb6cf;letter-spacing:1.3px}
.score{font-family:"Space Grotesk",sans-serif;font-size:40px;color:#48d8e7;line-height:1}
.bar{height:7px;background:#173b61;border-radius:8px;overflow:hidden;margin:10px 0}
.bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,#0b6fc8,#2ed5df);transition:width 1.5s var(--ease)}
.bar.in i{width:78%}
.metric-row{display:flex;justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.07);padding:8px 0;font-size:9px;color:#b9cce0}
.metric-row:last-child{border-bottom:0}
.metric-row b{color:#fff}
.sev{padding:1px 7px;border-radius:3px;font-size:8px;font-weight:800}
.sev-high{background:rgba(255,92,92,.16);color:#ff8f8f}.sev-med{background:rgba(255,173,24,.16);color:var(--orange)}

/* ---------- stats / why / chips ---------- */
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.stat{background:var(--surface);border:1px solid var(--line);padding:24px}
.stat b{font-family:"Space Grotesk",sans-serif;font-size:33px;color:var(--blue);display:block;line-height:1}
.stat span{display:block;font-weight:700;font-size:14px;margin:9px 0 5px}
.stat small{color:var(--muted);font-size:13px;line-height:1.65;display:block}
.split{display:grid;grid-template-columns:1.05fr .95fr;gap:52px;align-items:start}
.split p{color:var(--muted);font-size:15px;line-height:1.82}
.diff-list{list-style:none;padding:0;margin:22px 0 0}
.diff-list li{display:flex;gap:14px;padding:12px 0;border-bottom:1px solid var(--line);font-size:14px;align-items:baseline}
.diff-list .n{font-family:"Space Grotesk",sans-serif;color:var(--orange);font-weight:700;font-size:12px;flex:none}
.vm-card{background:linear-gradient(145deg,#06315e,#0a6fc7);color:#fff;padding:26px;margin-bottom:13px;border-radius:9px;position:relative;overflow:hidden}
.vm-card img{position:absolute;right:-26px;bottom:-26px;width:130px;opacity:.13}
.vm-card .section-label{color:#ffd88a}
.vm-card h3{font-family:"Space Grotesk",sans-serif;font-size:20px;margin:8px 0 8px}
.vm-card p{color:#d7e8f8;font-size:13.5px;line-height:1.78;margin:0;position:relative}
.values{display:grid;grid-template-columns:repeat(3,1fr);gap:13px;margin-top:44px}
.values div{background:var(--surface);border:1px solid var(--line);padding:20px}
.values h4{font-family:"Space Grotesk",sans-serif;margin:0 0 7px;font-size:17px;color:var(--blue)}
.values p{margin:0;font-size:13px;color:var(--muted);line-height:1.7}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:30px}
.chips span{border:1px solid rgba(255,255,255,.22);padding:10px 17px;border-radius:30px;font-size:13px;color:#cfe2f4;transition:background .22s var(--ease),transform .22s var(--ease)}
.chips span:hover{background:rgba(255,255,255,.1);transform:translateY(-3px)}

/* ---------- faq / insights / contact ---------- */
/* Left-aligned, not centred. Centring an 880px block inside a 1220px container
   put a ~170px inset on the left of the accordion while the section heading
   above it started hard against the container edge — the two read as belonging
   to different grids. */
.faq{max-width:900px;margin:28px 0 0}
.faq details{border:1px solid var(--line);background:var(--surface);margin-bottom:10px}
.faq details[open]{box-shadow:var(--shadow-md);border-color:#bcd8ee}
.faq summary{cursor:pointer;padding:19px 23px;font-weight:700;font-size:16px;font-family:"Space Grotesk",sans-serif;list-style:none;display:flex;justify-content:space-between;gap:16px;align-items:center}
.faq summary::-webkit-details-marker{display:none}
.faq summary:after{content:"+";color:var(--orange);font-size:21px;font-weight:400;transition:transform .3s var(--ease);flex:none}
.faq details[open] summary:after{transform:rotate(45deg)}
.faq .a{padding:0 22px 21px;color:var(--muted);font-size:14px;line-height:1.82}
.insight-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.insight{min-height:232px;padding:26px;background:linear-gradient(135deg,var(--ice),var(--surface));border:1px solid var(--line);display:flex;flex-direction:column;justify-content:flex-end;transition:transform .3s var(--ease),box-shadow .3s var(--ease)}
.insight:hover{transform:translateY(-6px);box-shadow:var(--shadow-lg)}
.insight.dark{background:linear-gradient(135deg,#06234a,#0b69b9);color:#fff}
.insight small{font-size:8.5px;color:#f39800;text-transform:uppercase;letter-spacing:1.6px;font-weight:800}
.insight h3{font-family:"Space Grotesk",sans-serif;font-size:18px;margin:10px 0;line-height:1.3}
.insight p{font-size:13px;line-height:1.72;color:var(--muted);margin:0 0 13px}
.insight.dark p{color:#c8dcee}.insight.dark .svc-more{color:#7ce6f2}
.cta{padding:80px 0;background:linear-gradient(120deg,var(--ice),var(--surface-2));position:relative;overflow:hidden}
.cta-box{display:flex;align-items:center;justify-content:space-between;gap:32px;position:relative;z-index:2}
.contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:50px;align-items:start}
.cdetail{list-style:none;padding:0;margin:22px 0 0}
.cdetail li{padding:13px 0;border-bottom:1px solid var(--line);font-size:14px}
.cdetail b{display:block;font-size:9.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--muted);font-weight:800;margin-bottom:2px}
.cdetail a{color:var(--blue);font-weight:700}
.form{background:var(--surface);border:1px solid var(--line);padding:28px;box-shadow:var(--shadow-md)}
.form label{display:block;font-size:10px;letter-spacing:1.2px;text-transform:uppercase;font-weight:800;color:var(--muted);margin:0 0 5px}
/* Fields follow the surface tokens, so the form is legible in both themes —
   it was white-on-white in light and white-on-navy in dark before. The
   placeholder is a deliberate --muted rather than a paler grey: a placeholder
   is still text a person has to read to know what the field wants. */
.form input,.form select,.form textarea{width:100%;padding:11px 13px;border:1px solid var(--line);
  border-radius:3px;font-family:inherit;font-size:13px;margin-bottom:14px;
  background:var(--surface-2);color:var(--ink)}
.form input::placeholder,.form textarea::placeholder{color:var(--muted);opacity:1}
[data-theme="light"] .form input,[data-theme="light"] .form select,[data-theme="light"] .form textarea{background:#fbfdff}
.form input:focus,.form select:focus,.form textarea:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(11,103,201,.14)}
.form textarea{min-height:96px;resize:vertical}
.form .note{font-size:10.5px;color:var(--muted);margin:4px 0 0}
footer{background:#07192e;color:#b4c7da;padding:60px 0 24px}
.footer-grid{display:grid;grid-template-columns:1.5fr repeat(3,1fr);gap:40px}
.footer-brand img{width:54px;height:48px;object-fit:contain}
.footer-brand h3{font-family:"Space Grotesk",sans-serif;font-size:21px;margin:10px 0 7px;color:#fff}
.footer-brand h3 em{font-style:normal;color:var(--cyan)}
.footer-brand p{font-size:12.5px;line-height:1.8;max-width:320px}
footer h4{color:#fff;font-size:10.5px;margin:0 0 14px;text-transform:uppercase;letter-spacing:1.3px}
footer ul{list-style:none;padding:0;margin:0}
footer li{font-size:12px;line-height:2.15}
footer li a:hover{color:#fff}
.copy{border-top:1px solid rgba(255,255,255,.1);margin-top:40px;padding-top:18px;font-size:9.5px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap}

@media(max-width:1080px){
 .mega-inner{grid-template-columns:1fr}
 .mega-promo{display:none}
}

/* The drawer's own call to action. It is inside .nav-list so that it lands at
   the foot of the open drawer on a handset, which means it is also in the
   desktop nav unless it is told otherwise — and on desktop it duplicates the
   button already sitting in .hdr-cta two elements to the right. */
.nav-cta-mobile{display:none}
/* Nav labels wrap rather than compress when the row runs out of room, which
   turns one 76px header into two ragged lines. Keep each label whole and let
   the row tighten instead. */
.nav-trigger,.nav-link{white-space:nowrap}
@media(max-width:1460px){
 .nav-trigger,.nav-link{padding:13px 10px;font-size:12px}
 .nav-list{gap:0}
}
@media(max-width:980px){
 .hero-grid,.head-split,.split,.contact-grid{grid-template-columns:1fr}
 /* The slides kept their two-column grid all the way down, which squeezed the
    art into a thumbnail beside a one-word-per-line column. Stack instead. */
 .slide{grid-template-columns:1fr;gap:30px}
 .slide-art{max-width:540px}
 .platform-grid,.cap-grid,.svc-grid,.insight-grid{grid-template-columns:repeat(2,1fr)}
 .chip-a,.chip-b{display:none}
}

/* ---------- the nav becomes a drawer ----------
   Chosen by measuring, not by convention: seven top-level items plus a portal
   link plus a CTA button start clipping the button off the right edge at about
   1280px. The threshold sits above that with room to spare, because a header
   that is one word from breaking is a header that breaks on the next word you
   add. If you change the nav, re-measure — do not assume this number holds. */
@media(max-width:1320px){
 .navtoggle{display:block}
 .nav{position:fixed;inset:0;top:0;background:#031428;flex-direction:column;justify-content:flex-start;padding:88px 22px 30px;overflow-y:auto;transform:translateX(100%);transition:transform .35s var(--ease);z-index:88}
 .nav.open{transform:none}
 .nav-list{flex-direction:column;align-items:stretch;width:100%;gap:2px}
 .nav-trigger,.nav-link{width:100%;justify-content:space-between;font-size:15px;padding:15px 12px}
 .mega{position:static;opacity:1;visibility:visible;transform:none;box-shadow:none;background:transparent;border:0;display:none}
 .has-mega.open .mega{display:block}
 .mega-inner{width:100%;padding:4px 0 14px;gap:18px}
 .mega-cols--2,.mega-cols--3,.mega-cols--4{grid-template-columns:1fr}
 .hdr-cta .nav-link-portal{display:none}
 /* In the drawer it is the only CTA on screen, so it comes back. */
 .nav-cta-mobile{display:block;margin-top:18px}
 .nav-cta-mobile a{display:block;text-align:center;background:var(--orange);color:#0e2b4c;
   font:800 13px/1 Manrope,sans-serif;letter-spacing:.6px;padding:16px;border-radius:7px}
}
@media(max-width:900px){
 .stats,.values,.footer-grid{grid-template-columns:repeat(2,1fr)}
 .cta-box{flex-direction:column;align-items:flex-start}
}
@media(max-width:820px){
 .tb-left,.topbar .tb-right span:not(.ts-icon),.tb-right a[href^="mailto"]{display:none}
 .topbar .container{justify-content:flex-end;gap:14px}
 .topbar .tb-right{gap:14px;flex-wrap:nowrap;align-items:center}
}
@media(max-width:560px){
 /* The header ran off the right edge on a phone in BOTH themes: brand +
    tagline + burger + a full-width "BOOK A DEMO" do not fit in 430px. The
    tagline is the least load-bearing of the four, and the button label can
    lose a word without losing its meaning. */
 .brand-tag{display:none}
 .brand img{width:42px;height:38px}
 .brand-word{font-size:18px}
 .hdr{gap:10px;min-height:64px}
 .hdr-cta{gap:8px}
 .hdr-cta .btn{padding:11px 13px;font-size:10px}
 /* "Book a demo" → "Demo". Dropping the verb keeps the meaning; dropping the
    noun did not — the first attempt at this read "BOOK A". */
 .hdr-cta .btn .btn-long{display:none}
 .hdr-cta .btn .btn-short{display:inline}
 .section{padding:60px 0}
 .cap-grid,.svc-grid,.insight-grid,.platform-grid,.stats,.values,.footer-grid{grid-template-columns:1fr}
 .topbar .container{justify-content:center}
 .topbar .tb-left{display:none}
}
@media (prefers-reduced-motion:reduce){
 html{scroll-behavior:auto}
 *,*:before,*:after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
 .js .reveal{opacity:1;transform:none}
 [data-px]{transform:none!important}
}
/* ══════════════════════════════════════════════════════════════════════════
   LIGHT THEME
   ══════════════════════════════════════════════════════════════════════════
   Activated by  ?theme=light  (remembered), or the switch bottom-right.
   Written as an OVERRIDE layer so the dark original is untouched and the two
   can be compared by flipping one attribute.

   The three decisions that make this read as professional rather than as a
   dark page with the lights turned on:

   1. THE HERO IS NOT WHITE. A flat white hero looks unfinished at this size.
      It is a layered field — a cool blue wash rising from the bottom, a warm
      highlight top-right, and the same perspective gridlines the dark version
      uses, re-tinted. Gradients here are wide and low-contrast: on light,
      anything stronger reads as a banner advert rather than a brand surface.

   2. THE PRODUCT PANEL STAYS DARK. The illustrations in the hero are drawn
      with light strokes for a dark ground; recolouring them would be a large
      change for a worse result. A light page with a dark product panel is
      also simply the better composition — it is where the eye should land,
      and it is what every serious SaaS home page does. It now carries a soft
      coloured glow so it reads as deliberate rather than left over.

   3. THE DARK BANDS STAY. Platform and Industries remain dark. An all-white
      page of this length loses its rhythm; two dark bands give it structure
      and make the light sections feel lighter. They are rebalanced, not kept
      by accident.
   ══════════════════════════════════════════════════════════════════════════ */

[data-theme="light"]{
  --bg:#fff;
  --surface:#fff;
  --surface-2:#f7fbff;
  --ink:#0c2038;          /* deepened: needs to carry body copy on white */
  --muted:#586a80;
  --line:#e2ebf4;
  --soft:#f6fafe;
  --ice:#eef6ff;
  --shadow-lg:0 26px 70px rgba(10,44,86,.10);
  --shadow-md:0 10px 28px rgba(10,44,86,.08);
  /* Gradient stops for light ground. The dark theme's cyan is too pale here,
     so each accent is taken a step deeper to hold contrast on white. */
  --grad-a:#0b67c9;
  --grad-b:#0a97bd;
  --grad-c:#d98a06;
}

[data-theme="light"] body{background:#fff;color:var(--ink)}

/* ---------- top bar ---------- */
/* The top strip was legible on paper — 5.37 against the lightest stop, over
   the 4.5 floor — and still read as faint: 11px at .5px tracking in a muted
   blue-grey is a lot of visual quietness for a line carrying the phone number.
   Darkened to 6.96, set a point larger, and the contact details are given
   their own weight so they read as information rather than decoration. */
[data-theme="light"] .topbar{background:linear-gradient(90deg,#eaf3ff,#f5faff 58%,#fff4e4);
  color:#42576d;border-bottom:1px solid #dbe7f3;font-size:12px;letter-spacing:.2px}
[data-theme="light"] .topbar a{color:#2d4157;font-weight:600}
[data-theme="light"] .topbar a:hover{color:var(--blue);text-decoration:underline}
[data-theme="light"] .tb-left{font-weight:600}

/* ---------- header ---------- */
[data-theme="light"] header{background:rgba(255,255,255,.82);border-bottom:1px solid var(--line)}
[data-theme="light"] header.solid{background:rgba(255,255,255,.96);box-shadow:0 8px 28px rgba(10,44,86,.09)}
[data-theme="light"] .brand-word{color:var(--ink)}
[data-theme="light"] .brand-word em{color:var(--blue)}
[data-theme="light"] .brand-tag{color:var(--muted)}
[data-theme="light"] .brand img{filter:none}
[data-theme="light"] .nav-trigger,
[data-theme="light"] .nav-link{color:#3c5570}
[data-theme="light"] .nav-trigger:hover,
[data-theme="light"] .nav-link:hover,
[data-theme="light"] .has-mega.open .nav-trigger{background:var(--ice);color:var(--blue)}
[data-theme="light"] .navtoggle{border-color:var(--line);color:var(--ink)}

/* ---------- mega menu ---------- */
[data-theme="light"] .mega{background:#fff;border-top:1px solid var(--line);box-shadow:0 28px 60px rgba(10,44,86,.14)}
[data-theme="light"] .mega-links a:hover{background:var(--ice)}
[data-theme="light"] .mega-links b{color:var(--ink)}
[data-theme="light"] .mega-links small{color:var(--muted)}
[data-theme="light"] .mega-title{color:#b0740a}
[data-theme="light"] .mega-foot{border-top-color:var(--line);color:var(--muted)}
[data-theme="light"] .link-arrow{color:var(--blue)}
/* …except inside the promo tile, which keeps its dark gradient on light. */
[data-theme="light"] .mega-promo .link-arrow{color:#e2f6fc}
[data-theme="light"] .mega-promo .link-arrow:hover{color:#fff}
/* The promo tile keeps its dark gradient — it is the one coloured object in
   an otherwise white panel and it does the job of an image. */
[data-theme="light"] .mega-promo{box-shadow:0 18px 40px rgba(6,49,94,.24)}

/* ---------- buttons ---------- */
[data-theme="light"] .btn-outline{border-color:#c2d4e6;color:var(--ink)}
[data-theme="light"] .btn-outline:hover{background:var(--ice);border-color:var(--blue);color:var(--blue)}
/* …except on the bands that stay dark in light mode, where ink-on-navy is an
   invisible label inside a visible border. Keep the dark-theme treatment. */
[data-theme="light"] .section--dark .btn-outline{border-color:rgba(255,255,255,.4);color:#fff}
[data-theme="light"] .section--dark .btn-outline:hover{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.7);color:#fff}

/* ══════════════════════ THE HERO ══════════════════════
   Four stacked layers, each doing one job:
     · a warm highlight, top-right, so the field is not uniformly cool
     · a blue wash rising from the bottom, which is what gives it depth
     · a faint cyan lift behind the headline
     · a flat base so the top of the page meets the header cleanly
   Percentages are wide and alphas low; the whole point is that you should
   not be able to see where one stop ends. */
[data-theme="light"] .hero{
  color:var(--ink);
  background:
    radial-gradient(ellipse 52% 40% at 88% 4%,rgba(255,173,24,.13),transparent 60%),
    radial-gradient(ellipse 78% 62% at 50% 108%,rgba(11,103,201,.16),transparent 64%),
    radial-gradient(ellipse 60% 44% at 22% 18%,rgba(24,198,220,.13),transparent 62%),
    linear-gradient(180deg,#fdfeff 0%,#f4f9ff 46%,#eaf3fd 100%);
}
/* A hairline at the foot of the hero, so it resolves into the next section
   instead of stopping. */
[data-theme="light"] .progress i{background:linear-gradient(90deg,#0a57b8,#0e9cc2 55%,var(--orange))}
[data-theme="light"] .hero:after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(11,103,201,.22),transparent);z-index:4}

[data-theme="light"] .hero-glow{background:radial-gradient(ellipse 58% 44% at 50% 78%,rgba(11,103,201,.10),transparent 62%)}
/* The gridlines are the signature of the dark hero and they survive the
   transfer well — re-tinted to blue and taken down to a whisper. */
[data-theme="light"] .gridlines{opacity:.5;
  background-image:linear-gradient(rgba(11,103,201,.11) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(11,103,201,.11) 1px,transparent 1px)}
[data-theme="light"] .px-orb{filter:blur(78px)}
[data-theme="light"] .px-orb--cyan{background:rgba(24,198,220,.16)}
[data-theme="light"] .px-orb--blue{background:rgba(11,103,201,.13)}
[data-theme="light"] .px-orb--gold{background:rgba(255,173,24,.14)}

[data-theme="light"] .slide-kicker{border-color:rgba(11,103,201,.22);color:#0a5ba8;
  background:rgba(255,255,255,.72);box-shadow:0 2px 10px rgba(10,44,86,.05)}
[data-theme="light"] .slide h1,
[data-theme="light"] .slide h2.slide-h{color:var(--ink)}
/* GRADIENT TEXT ON LIGHT — the one thing that does not transfer.
   The dark hero runs cyan → pale cyan → gold, which works because every stop
   is light and saturated against navy. Reproduced on white it fails twice:
   the pale stops disappear, and the blue→gold interpolation passes through
   olive, so "never sleeps" rendered a muddy khaki.
   The fix is to stay inside one hue family and go deeper, not brighter. Blue
   → teal holds contrast the whole way across and never transits a dead hue.
   Gold is not lost — it is reserved for the call to action, which is a
   stronger use of it than a third of a headline. */
[data-theme="light"] .slide .accent{
  /* Stops chosen against measured contrast, not by eye: the end of a gradient
     headline is still headline text. #11b1a4 looked right and scored 2.50 on
     the hero ground — under the 3.0 large-text minimum. Every stop now clears
     it, and the run still reads as one sweep rather than three colours. */
  background:linear-gradient(96deg,#0a57b8 0%,#0b78c9 32%,#0d92b6 66%,#0c8a7f 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
[data-theme="light"] .slide .lede{color:var(--muted)}
[data-theme="light"] .slide .lede strong{color:var(--ink)}
[data-theme="light"] .hero-trust{color:#5d7189}
[data-theme="light"] .hero-trust li:before{color:#12a05c}
[data-theme="light"] .hero-facts li{color:#5d7189}
[data-theme="light"] .hero-facts b{color:var(--ink)}

/* The product panel: deliberately dark, and lit so it reads as intentional.
   The glow sits BEHIND it, which is what stops a dark rectangle on a light
   page looking like a hole. */
[data-theme="light"] .slide-art{
  border-color:rgba(11,103,201,.18);
  background:linear-gradient(160deg,#08264a,#04162e 92%);
  box-shadow:0 34px 80px rgba(6,40,84,.30),0 0 0 1px rgba(255,255,255,.55);
}
[data-theme="light"] .slide-art:before{content:"";position:absolute;inset:-14%;z-index:-1;
  background:radial-gradient(ellipse at 50% 50%,rgba(24,198,220,.22),transparent 68%);filter:blur(30px)}

[data-theme="light"] .hero-capsule{background:rgba(255,255,255,.86);border-color:var(--line);
  box-shadow:0 12px 30px rgba(10,44,86,.12)}
[data-theme="light"] .hcap-btn{color:#4a6076}
[data-theme="light"] .hcap-btn:hover{background:var(--ice);color:var(--blue)}
/* Everything inside the capsule was drawn in white-on-translucent for the
   dark hero. On a white capsule the counter vanished entirely and the unfilled
   progress segments were invisible. */
[data-theme="light"] .hcap-count{color:var(--ink)}
[data-theme="light"] .hcap-count span{color:#7f95ad}
[data-theme="light"] .hcap-segs button{background:#d9e5f1}
[data-theme="light"] .hcap-segs button:hover{background:#c3d5e7}
[data-theme="light"] .hcap-segs button i{background:linear-gradient(90deg,#0b78c9,#11b1a4)}
[data-theme="light"] .hcap-play{background:rgba(255,173,24,.20);color:#c07c05}
[data-theme="light"] .hcap-play:hover{background:rgba(255,173,24,.32);color:#a86a02}
[data-theme="light"] .hcap-play .ring .bg{stroke:rgba(10,44,86,.14)}
/* The chips sit on the dark product panel in both themes, so they keep their
   dark treatment — but they gain a light rim so they read as lifted off it. */
[data-theme="light"] .chip-float{box-shadow:0 14px 34px rgba(6,40,84,.28),0 0 0 1px rgba(255,255,255,.14)}
/* The pause control is on the dark panel too; only its ring needs softening. */
[data-theme="light"] .video-toggle{border-color:rgba(255,255,255,.28)}

/* ---------- light sections ---------- */
[data-theme="light"] .section--paper{background:linear-gradient(180deg,#f7fbff,#fff)}
[data-theme="light"] .faq details,[data-theme="light"] .form,
[data-theme="light"] .svc-card,[data-theme="light"] .stat,[data-theme="light"] .values div{background:#fff}
[data-theme="light"] .section--tinted{background:linear-gradient(180deg,#f8fbff 0%,#fffaf3 54%,#f7fbff 100%)}
[data-theme="light"] .accent{color:var(--blue)}

/* The two dark bands stay dark, on purpose — see the note at the top. They
   are warmed slightly so they sit with the light sections rather than
   looking like a different site. */
[data-theme="light"] .section--dark{background:linear-gradient(165deg,#062a55 0%,#03152d 70%)}

/* ---------- the theme switch ----------
   Lives in the top bar beside the contact details rather than floating over
   the page. A fixed pill in the corner is fine for a reviewer and wrong for a
   visitor: it covers content on a phone and reads as a debug affordance. */
.theme-switch{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:30px;
  border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.07);color:inherit;
  font:700 10.5px/1 Manrope,sans-serif;letter-spacing:.4px;text-transform:uppercase;cursor:pointer;
  transition:background .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease)}
.theme-switch:hover{background:rgba(255,255,255,.16);color:#fff}
.theme-switch .ts-icon{display:grid;place-items:center;transition:transform .35s var(--ease)}
.theme-switch:hover .ts-icon{transform:rotate(35deg)}
[data-theme="light"] .theme-switch{border-color:#cddff0;background:rgba(255,255,255,.72);color:#2d4157}
[data-theme="light"] .theme-switch:hover{background:#fff;border-color:var(--blue);color:var(--blue)}
@media(max-width:560px){.theme-switch span:not(.ts-icon){display:none}.theme-switch{padding:5px 8px}}

/* ══════════════════════ PHOTOGRAPHY ══════════════════════
   Two photographs, used as TEXTURE behind the dark bands rather than as
   subject matter. Both are CC0 / public domain and self-hosted — see
   assets/img/CREDITS.md. Self-hosting is not a preference: production sends
   img-src 'self', so a hotlinked image is blocked outright.

   The restraint is the point. A security and compliance site loses credibility
   with every generic stock photo, not gains it; these exist to stop two large
   flat navy bands reading as empty, and they are pushed far enough back that
   you notice the depth before you notice the picture.

   Implementation: the photo sits on a ::before at low opacity under a gradient
   scrim, so the band's own colour still governs and every piece of text on top
   keeps the contrast it had when the background was flat. */
.has-photo{position:relative;isolation:isolate}
.has-photo:before{content:"";position:absolute;inset:0;z-index:-2;
  background-size:cover;background-position:center;background-repeat:no-repeat}
.has-photo:after{content:"";position:absolute;inset:0;z-index:-1}

/* Financial district at night, behind the regulated-industries band. The one
   photograph here with a literal relationship to its section: BFSI is the
   first of the sectors it lists. */
.photo-industries:before{background-image:url("../img/band-industries.jpg");opacity:.30}
.photo-industries:after{background:
  linear-gradient(180deg,rgba(3,21,45,.93) 0%,rgba(3,21,45,.80) 45%,rgba(3,21,45,.95) 100%)}

/* ISS star trails behind the platform band. Abstract rather than literal, and
   chosen for what a long exposure shows: continuity over time, which is the
   argument that section is making. Held right back — it is a surface, not a
   picture. */
.photo-platform:before{background-image:url("../img/band-platform.jpg");opacity:.55}
.photo-platform:after{background:
  linear-gradient(175deg,rgba(6,42,85,.72) 0%,rgba(4,26,56,.88) 42%,rgba(3,21,45,.94) 100%)}

/* No background-attachment:fixed. The orbs in these bands already parallax on
   scroll (data-px, in new-design.js); a photograph drifting at a third rate
   behind them reads as a rendering fault rather than as depth. */


/* ══════════════════════ SITE-WIDE ADDITIONS ══════════════════════
   Everything below arrived when this file stopped being one page's stylesheet
   and became the template for all of them. Same rules as the rest of the file:
   tokens only, dark first, then the light override. */

/* ---------- footer, widened ----------
   The footer carries five columns now (brand + four link groups), because it is
   the only cross-link between most of these pages. */
.footer-grid{grid-template-columns:1.55fr repeat(4,1fr);gap:36px}
.footer-col h4{margin-top:0}
.footer-col li a{color:inherit}
.footer-brand .brand{display:inline-block}
.footer-brand h3{margin-top:12px}
.footer-address{font-style:normal;display:block;font-size:12px;line-height:1.85;margin:14px 0 10px;color:#9db2c8}
.footer-address strong{display:block;color:#dce9f5;font-weight:700;margin-bottom:4px}
.footer-office{display:block;color:var(--orange);font-size:9px;letter-spacing:1.6px;text-transform:uppercase;font-weight:800;margin-top:8px}
.footer-office-contact{display:block;margin-top:8px}
.footer-office-contact a:hover{color:#fff}
.footer-status{font-size:11px;color:#8ba3ba;margin:10px 0 0}
.copy{display:flex;flex-wrap:wrap;align-items:center;gap:12px 24px;justify-content:space-between;
  margin-top:44px;padding-top:20px;border-top:1px solid rgba(255,255,255,.09);font-size:11.5px;color:#8ba3ba}
.copy-legal{display:flex;flex-wrap:wrap;gap:18px}
.copy-legal a:hover{color:#fff;text-decoration:underline}
.copy-sig{color:var(--cyan);letter-spacing:.4px}

/* ══════════════════════ THE PAGE BANNER ══════════════════════
   Every interior page opens on this. `.page-head` is the plain version and
   `.svc-hero` the two-column one that service pages use; both share everything
   below, so the height and rhythm are set in ONE place and a change reaches all
   61 pages. Service-page layout (the grid, figure and stat rail) is the only
   part still in pages.css.

   It used to be enormous — 854px on a service page, before a single line of
   content. Two reasons, both fixed here:

   1. Both banners added `var(--header-h)` to their top padding. That is correct
      for a `position:fixed` header, which would be lifted out of flow and would
      otherwise cover the top of the page. This header is `position:sticky`, so
      it already occupies its own space and that 76px was pure dead air on every
      interior page.
   2. The remaining padding was set with generous clamps tuned for a home-page
      hero, not for a page someone arrived at from search wanting an answer.

   The numbers below are deliberately modest. A banner's job on an interior page
   is to say where you are and what this page is about, then get out of the way. */
.page-head,.svc-hero{
  position:relative;overflow:hidden;isolation:isolate;
  background:linear-gradient(168deg,#062a55 0%,#03152d 74%);
  color:#b6cde2;
  padding:clamp(26px,3.2vw,38px) 0 clamp(32px,3.8vw,46px);
  border-bottom:1px solid rgba(120,200,240,.14);
}

/* The same perspective gridlines the home-page hero uses, masked so they fade
   out before they reach the text. */
.page-head:before,.svc-hero:before{
  content:"";position:absolute;inset:0;z-index:-2;
  background-image:
    linear-gradient(rgba(120,175,225,.055) 1px,transparent 1px),
    linear-gradient(90deg,rgba(120,175,225,.055) 1px,transparent 1px);
  background-size:62px 62px;
  -webkit-mask-image:radial-gradient(ellipse 80% 80% at 28% 42%,#000 18%,transparent 74%);
  mask-image:radial-gradient(ellipse 80% 80% at 28% 42%,#000 18%,transparent 74%);
}
.page-head:after,.svc-hero:after{
  content:"";position:absolute;top:-52%;right:-8%;width:560px;height:560px;max-width:110vw;
  background:radial-gradient(circle,rgba(24,198,220,.20),transparent 62%);
  filter:blur(30px);z-index:-1;pointer-events:none;
}

/* ---- breadcrumbs ---- */
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  font-size:11.5px;color:#9dbdd8;margin-bottom:14px}
.crumbs a{color:#bcd6ea}
.crumbs a:hover{color:#fff;text-decoration:underline;text-underline-offset:3px}
.crumbs [aria-hidden]{opacity:.42}
.crumbs [aria-current]{color:#fff;font-weight:700}

/* ---- the three lines of copy ---- */
.page-head .eyebrow,.svc-hero .eyebrow{
  color:var(--orange);text-transform:uppercase;font-size:10.5px;font-weight:800;
  letter-spacing:2.2px;margin:0 0 9px}
.page-head h1,.svc-hero h1{
  font-family:"Space Grotesk",sans-serif;font-weight:700;color:#fff;
  /* Smaller than it was. At the old clamp a two-word heading ran to three
     lines on a laptop and pushed everything below the fold on its own. */
  font-size:clamp(26px,3.1vw,40px);line-height:1.1;letter-spacing:-1.2px;
  margin:0;max-width:20ch}
.page-head h1 .accent,.svc-hero h1 .accent{color:var(--cyan)}
.page-head-lead{
  /* 62ch was too wide to scan comfortably against a dark ground. */
  max-width:58ch;color:#b6cde2;font-size:15px;line-height:1.7;margin:12px 0 0}
.page-head-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}

@media(max-width:700px){
  .page-head,.svc-hero{padding:20px 0 28px}
  .crumbs{margin-bottom:11px;font-size:11px}
  .page-head h1,.svc-hero h1{max-width:none}
  .page-head-lead{font-size:14.5px;margin-top:10px}
}

/* ---------- touch targets ----------
   44px is the smallest thing a thumb hits reliably. Applied to the chrome only;
   it is a floor, not a look. */
@media (hover:none),(max-width:820px){
  .nav-link,.nav-trigger{min-height:44px}
  .mega-links a{padding-block:12px}
  .link-arrow{padding-block:10px}
  .btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
  .copy-legal a,.footer-col li a{display:inline-block;padding-block:5px}
}

@media(max-width:1080px){.footer-grid{grid-template-columns:1.4fr repeat(2,1fr)}}
@media(max-width:700px){.footer-grid{grid-template-columns:1fr;gap:26px}.copy{justify-content:flex-start}}

/* ---------- light theme ---------- */
[data-theme="light"] .page-head{background:linear-gradient(168deg,#0a3468 0%,#03152d 76%)}

/* ---------- components that were written as light-only ----------
   These carried literal pale values in the base layer, so they stayed white
   when the page went dark — white cards with near-invisible text. They now
   resolve through the surface tokens, and their original light values are
   restored here so light mode is unchanged. */
/* :not(.feature) matters. Without it this rule sits later in the file at equal
   specificity to .cap-card.feature and wins, which painted the one blue card
   pale and left its white text invisible. */
[data-theme="light"] .cap-card:not(.feature){background:#f4f8fc;border:1px solid #e1ebf4}
[data-theme="light"] .cap-card:not(.feature) .icon,[data-theme="light"] .icon:not(.feature .icon){background:#dff1ff;color:var(--blue)}
[data-theme="light"] .insight{background:linear-gradient(135deg,#eaf7ff,#fff)}
[data-theme="light"] .tint-body{background:rgba(255,255,255,.9);border-color:rgba(255,255,255,.9)}
[data-theme="light"] .tint-a{background:linear-gradient(150deg,#e8eeff,#f3f7ff 55%,#ffffff)}
[data-theme="light"] .tint-b{background:linear-gradient(150deg,#e6f9ee,#f2fdf6 55%,#ffffff)}
[data-theme="light"] .tint-c{background:linear-gradient(150deg,#ffeee2,#fff7f0 55%,#ffffff)}
[data-theme="light"] .tint-d{background:linear-gradient(150deg,#e4f6fb,#f1fbfe 55%,#ffffff)}
[data-theme="light"] .cta{background:linear-gradient(120deg,#e8f7ff,#fff3dd)}

/* ══════════════════════ FRAMEWORK CHIPS ══════════════════════
   The twelve framework links, grouped India / International. One set of rules
   for both places they appear (the Compliance mega panel and the footer),
   because they used to be two copies of the same twelve <li> and only one of
   them ever got updated.

   Chips rather than a list: twelve stacked names is the tallest thing in both
   components, and it is not a list anyone reads in order — you arrive already
   knowing whether you need SEBI CSCRF or SOC 2. Wrapping them turns a 12-row
   column into two short blocks you can scan. */
.fw-group + .fw-group{margin-top:14px}
.fw-label{margin:0 0 7px;font:800 8.5px/1 Manrope,sans-serif;letter-spacing:1.8px;
  text-transform:uppercase;color:#7f9cb8}
.fw-chips{display:flex;flex-wrap:wrap;gap:6px;list-style:none;padding:0;margin:0}
.fw-chips a{display:block;padding:6px 11px;border-radius:30px;font-size:11.5px;font-weight:600;
  color:#cfe2f3;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10);
  white-space:nowrap;transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease)}
.fw-chips a:hover{background:rgba(255,255,255,.14);border-color:rgba(159,228,242,.5);color:#fff}
.fw-chips a[aria-current]{background:var(--cyan);border-color:var(--cyan);color:#06263c}

/* In the mega panel the column is narrow, so the chips wrap inside it. */
.mega-col--frameworks .link-arrow{margin-top:16px}

/* ---------- the footer strip ----------
   Full width under the link columns. The same twelve names that made one footer
   column eighteen items deep fit on two short rows here. */
.footer-frameworks{margin-top:38px;padding-top:24px;border-top:1px solid rgba(255,255,255,.09)}
.footer-frameworks h4{margin-bottom:12px}
.footer-frameworks .fw-group{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.footer-frameworks .fw-label{margin:0;flex:none;min-width:92px}
.footer-frameworks .fw-chips{flex:1 1 320px}
.fw-all{display:inline-block;margin-top:14px;font-size:11px;font-weight:700;color:var(--cyan)}
.fw-all:hover{text-decoration:underline}
@media(max-width:560px){
  .footer-frameworks .fw-group{display:block}
  .footer-frameworks .fw-label{margin-bottom:7px}
}

/* ---------- light theme ---------- */
/* The mega panel turns white on light; its chips have to follow. The footer
   stays dark in both themes, so it keeps the values above. */
[data-theme="light"] .mega .fw-label{color:#6b8299}
[data-theme="light"] .mega .fw-chips a{color:#27415c;background:#f2f7fc;border-color:#dce8f3}
[data-theme="light"] .mega .fw-chips a:hover{background:#e6f1fb;border-color:var(--blue);color:var(--blue)}
[data-theme="light"] .mega .fw-chips a[aria-current]{background:var(--blue);border-color:var(--blue);color:#fff}

/* ══════════════════════ THE ENGINE BAND ══════════════════════
   Sits between the hero and the capability groups. It replaced a scrolling
   word ticker and a four-across stat bar — see the note in index.php for why
   both went.

   Dark in both themes on purpose: it is the one place on the home page making
   a quantitative claim, and a dark ground reads as an instrument panel rather
   than as another content section. It also gives the light theme a second
   structural band, which the page needs for rhythm. */
.engine{background:linear-gradient(165deg,#062a55 0%,#03152d 72%);color:#b6cde2;
  padding:44px 0 40px;position:relative;overflow:hidden;isolation:isolate}
.engine:before{content:"";position:absolute;inset:0;z-index:-1;
  background:radial-gradient(760px 320px at 86% 0%,rgba(24,198,220,.16),transparent 64%)}

.engine-head{display:flex;flex-wrap:wrap;gap:10px 24px;justify-content:space-between;
  align-items:baseline;margin-bottom:24px}
.engine-eyebrow{margin:0;display:flex;align-items:center;gap:9px;color:var(--orange);
  font:800 10.5px/1 Manrope,sans-serif;letter-spacing:2.2px;text-transform:uppercase}
.engine-dot{width:6px;height:6px;border-radius:50%;background:var(--orange)}
.engine-asof{margin:0;font-size:12px;color:#9dbdd8}
.engine-asof a{color:#cfe9f7;font-weight:700}
.engine-asof a:hover{color:#fff;text-decoration:underline}

/* One figure leads, three support. The old version gave all four equal weight,
   so the eye had nowhere to land and none of the numbers registered. */
.engine-grid{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);
  gap:clamp(24px,3vw,48px);align-items:stretch}
.engine-lead{border:1px solid rgba(120,200,240,.20);border-radius:12px;padding:24px 26px;
  background:rgba(255,255,255,.035);display:flex;flex-direction:column;justify-content:center}
.engine-lead b{display:block;font-family:"Space Grotesk",sans-serif;font-weight:700;
  font-size:clamp(38px,5vw,60px);line-height:1;letter-spacing:-2px;color:#fff;
  font-variant-numeric:tabular-nums}
.engine-lead em{display:block;font-style:normal;margin-top:10px;color:var(--cyan);
  font:800 11px/1.3 Manrope,sans-serif;letter-spacing:1.6px;text-transform:uppercase}
.engine-lead span{display:block;margin-top:12px;font-size:13px;line-height:1.7;color:#a9c2da}

.engine-rows{display:grid;gap:0;align-content:center}
.engine-rows li{display:grid;grid-template-columns:minmax(96px,auto) 1fr;gap:18px;
  align-items:baseline;padding:15px 0;border-bottom:1px solid rgba(120,200,240,.14)}
.engine-rows li:first-child{padding-top:0}
.engine-rows li:last-child{border-bottom:0;padding-bottom:0}
.engine-rows b{font-family:"Space Grotesk",sans-serif;font-weight:700;font-size:26px;
  line-height:1;letter-spacing:-.8px;color:#fff;font-variant-numeric:tabular-nums;text-align:right}
.engine-rows em{display:block;font-style:normal;color:#dbe9f6;font-weight:700;font-size:13.5px}
.engine-rows span{display:block;margin-top:3px;font-size:12px;line-height:1.6;color:#8fadc8}

/* ---------- the lifecycle ----------
   Was the scrolling ticker: six words cycling past, aria-hidden, impossible to
   read while moving and saying nothing when you did. As a fixed sequence it
   carries its numbering and its descriptions, which is what it was for. */
.lifecycle{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:1px;
  list-style:none;margin:34px 0 0;padding:26px 0 0;border-top:1px solid rgba(120,200,240,.16)}
.lifecycle li{position:relative;padding:0 16px 0 0}
.lifecycle li+li{padding-left:16px}
.lifecycle li+li:before{content:"";position:absolute;left:0;top:4px;bottom:2px;width:1px;
  background:rgba(120,200,240,.14)}
.lc-n{display:block;color:var(--orange);font:800 9.5px/1 Manrope,sans-serif;letter-spacing:1.6px}
.lifecycle b{display:block;margin:7px 0 5px;color:#fff;font-size:14px;
  font-family:"Space Grotesk",sans-serif;font-weight:700}
.lc-d{display:block;font-size:11.5px;line-height:1.6;color:#8fadc8}

@media(max-width:980px){
  .engine-grid{grid-template-columns:1fr}
  .lifecycle{grid-template-columns:repeat(3,minmax(0,1fr));gap:20px 0}
  .lifecycle li:nth-child(3n+1){padding-left:0}
  .lifecycle li:nth-child(3n+1):before{display:none}
}
@media(max-width:620px){
  .engine{padding:32px 0 30px}
  .lifecycle{grid-template-columns:repeat(2,minmax(0,1fr))}
  .lifecycle li:nth-child(3n+1){padding-left:16px}
  .lifecycle li:nth-child(3n+1):before{display:block}
  .lifecycle li:nth-child(2n+1){padding-left:0}
  .lifecycle li:nth-child(2n+1):before{display:none}
  .engine-rows li{grid-template-columns:1fr;gap:4px}
  .engine-rows b{text-align:left}
}
