/* ============================================================================
   MagenX marketing page
   Aesthetic: light enterprise, airy, product-forward. Referenced against
   cyera.com for structure and materiality only. Not a design system, and no
   Cyera brand assets, colours or type are used. Palette and type are MagenX.
   Type: Geist Variable + Geist Mono, self-hosted (no external font requests).
   Icons: Phosphor Icons (regular), vendored as an inline sprite.
   Radius rule for the whole page: pills for interactive controls,
   20px for panels, 24px for media frames, 10px for small chips. Nothing else.
   ========================================================================== */

@font-face{
  font-family:'Geist';src:url('/assets/fonts/Geist-Variable.woff2') format('woff2-variations');
  font-weight:100 900;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Geist Mono';src:url('/assets/fonts/GeistMono-Variable.woff2') format('woff2-variations');
  font-weight:100 900;font-style:normal;font-display:swap;
}

:root{
  --paper:#eeece5;
  --paper-2:#e9e7df;
  --card:#f8f7f2;
  --ink:#14161b;
  --ink-2:#4c4f57;
  --ink-3:#62655d;
  --line:#ddd9cf;
  --line-2:#cbc6b9;
  --accent:#1a4fd8;
  --accent-2:#0f36a6;
  --accent-on:#ffffff;
  --accent-soft:#e8ecfc;
  --accent-edge:#c3d0f6;
  --deep:#0b1230;
  --deep-2:#141d47;
  --deep-line:rgba(163,187,240,.18);
  --deep-ink:#eef2fb;
  --deep-ink-2:#a8b6d8;
  --accent-bright:#2b8cff;
  --shadow-media:0 30px 70px -34px rgba(14,24,64,.48), 0 2px 8px rgba(14,24,64,.07);
  --shadow-panel:0 1px 2px rgba(14,24,64,.04);
  --r-panel:20px;
  --r-media:24px;
  --r-chip:10px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --wrap:1240px;
}



*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;color-scheme:light;
  -webkit-tap-highlight-color:transparent}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:'Geist',system-ui,-apple-system,'Segoe UI',sans-serif;
  font-size:17px;line-height:1.55;font-synthesis-weight:none;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
img{max-width:100%;display:block}
a{color:inherit}
h1,h2,h3{margin:0;letter-spacing:-.022em;line-height:1.06;font-weight:560;text-wrap:balance}
p{text-wrap:pretty}
p{margin:0}
ul{margin:0;padding:0;list-style:none}

.wrap{max-width:var(--wrap);margin:0 auto;padding-inline:clamp(20px,4vw,48px)}
.mono{font-family:'Geist Mono',ui-monospace,monospace;font-variant-numeric:tabular-nums}
.ico{width:1em;height:1em;flex:none;fill:currentColor}
.flip{transform:rotate(180deg)}

.skip{position:absolute;left:-9999px;top:0;z-index:100}
.skip:focus{left:12px;top:12px;background:var(--accent);color:var(--accent-on);padding:10px 16px;border-radius:999px}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

/* ---------- navigation: one line, 68px, never taller ---------- */
#top-sentinel{position:absolute;top:0;height:1px;width:1px}
.nav{
  position:sticky;top:0;z-index:20;height:68px;margin-bottom:-68px;
  background:transparent;
  border-bottom:1px solid transparent;transition:border-color .25s var(--ease),background .25s var(--ease);
}
.nav.stuck{
  border-bottom-color:var(--deep-line);
  background:color-mix(in srgb,var(--deep) 90%,transparent);
  backdrop-filter:saturate(140%) blur(14px);-webkit-backdrop-filter:saturate(140%) blur(14px);
}
.nav .wrap{max-width:none;padding-inline:clamp(18px,2.2vw,34px);height:100%;
  display:flex;align-items:center;gap:clamp(16px,3vw,40px);position:relative}
.brand{display:flex;align-items:center;gap:12px;text-decoration:none;color:#fff;
  font-family:'Geist',system-ui,sans-serif;font-weight:680;letter-spacing:-.02em;font-size:1.5rem}
.brand img{width:46px;height:46px}
.navlinks{display:flex;align-items:center;gap:clamp(2px,.6vw,8px);margin-inline:auto}
.nd{position:static}
.nd-t{
  display:flex;align-items:center;gap:7px;border:0;background:transparent;cursor:pointer;
  padding:9px 13px;border-radius:999px;font:inherit;font-size:.94rem;white-space:nowrap;
  color:rgba(232,240,255,.85);transition:color .2s var(--ease),background .2s var(--ease);
}
.nd-t:hover,.nd.open .nd-t{color:#fff;background:rgba(255,255,255,.08)}
.nd-p{
  position:absolute;top:calc(100% + 10px);left:50%;
  width:min(900px,calc(100vw - 48px));
  /* Deliberately not the reference's white sheet: the menu wears the product's
     own dark chrome, whatever the sky is doing behind it. */
  background:linear-gradient(180deg,#0d1531 0%,#111b3d 100%);color:var(--deep-ink);
  border:1px solid var(--deep-line);border-radius:var(--r-panel);
  transition:opacity .2s var(--ease),translate .2s var(--ease),visibility .2s;
  padding:clamp(18px,1.8vw,24px);
  box-shadow:0 40px 90px -34px rgba(4,10,34,.8);
  opacity:0;translate:-50% -10px;visibility:hidden;pointer-events:none;
}
.nd-p::before{content:"";position:absolute;left:0;right:0;top:-16px;height:16px}
.nd.open .nd-p{opacity:1;translate:-50% 0;visibility:visible;pointer-events:auto}
.nd-grid{display:grid;grid-template-columns:250px repeat(2,minmax(0,1fr));gap:clamp(16px,1.8vw,26px)}
.nd-hd{margin:0 0 6px;font-family:'Geist Mono',ui-monospace,monospace;font-weight:500;
  font-size:.66rem;letter-spacing:.15em;text-transform:uppercase;color:#7f92bd}
/* rows rather than a plain list: each one is its own hit target */
.nd-p a{display:block;padding:8px 11px;border-radius:9px;text-decoration:none;
  color:var(--deep-ink);font-size:.93rem;
  transition:background .16s var(--ease),color .16s var(--ease)}
.nd-p a:hover{background:rgba(143,194,255,.12);color:#fff}
.nd-tile{display:block;border-radius:12px;overflow:hidden;border:1px solid var(--deep-line);
  background:#0a1230;text-decoration:none;transition:border-color .18s var(--ease)}
.nd-tile:hover{border-color:rgba(143,194,255,.5)}
.nd-tile .shot{display:block;width:100%;height:auto;border-bottom:1px solid var(--deep-line)}
.nd-tile .mark{display:grid;place-items:center;height:118px;border-radius:9px;
  background:radial-gradient(ellipse at 50% 45%,rgba(95,150,255,.28),rgba(95,150,255,0) 72%)}
.nd-tile .mark img{width:58px;height:58px}
/* the tile keeps its dark card so the screenshot inside it always sits on the
   same ground, whatever the sky is doing */
.nd-tile h4{margin:0;padding:13px 14px 4px;font-size:.97rem;font-weight:620;color:#fff}
.nd-tile p{margin:0;padding:0 14px 14px;font-size:.85rem;line-height:1.5;color:#93a4cb}

.nav-actions{display:flex;align-items:center;gap:12px;margin-left:auto}
.nav .btn-primary{background:#f6f5f1;color:#0a1130;
  transition:background .2s var(--ease),color .2s var(--ease),border-color .2s var(--ease);
  border:1px solid transparent}
/* on hover it steps out of the way: the sky behind the nav shows through */
.nav .btn-primary:hover{background:rgba(8,14,38,.34);color:#fff;
  border-color:rgba(210,226,255,.55);backdrop-filter:blur(2px)}
.menubtn{display:none;width:36px;height:36px;place-items:center;border-radius:999px;
  border:1px solid rgba(210,226,255,.28);background:transparent;color:rgba(232,240,255,.88);cursor:pointer;padding:0}
.menubtn:hover{border-color:rgba(210,226,255,.62);color:#fff}
.menubtn .ico{font-size:18px}
/* anchors opened from the dropdowns land clear of the 68px nav */
.menupanel{
  position:fixed;inset:68px 0 auto 0;z-index:19;background:var(--paper);
  border-bottom:1px solid var(--line);display:none;overscroll-behavior:contain;
  padding:12px clamp(20px,4vw,48px) calc(24px + env(safe-area-inset-bottom));
  max-height:calc(100dvh - 68px);overflow-y:auto;
}
.menupanel.open{display:block}
.menupanel a:not(.btn){display:block;padding-block:14px;border-bottom:1px solid var(--line);
  text-decoration:none;color:var(--ink);font-size:1.05rem}
.menupanel .btn{margin-top:22px;width:100%;color:var(--accent-on)}
.menupanel .mp-h{margin:18px 0 2px;font-family:'Geist Mono',ui-monospace,monospace;font-size:.68rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}

/* ---------- buttons ---------- */
.btn,.menubtn,.nd-t,.nd-p a,.navlinks a,.fcol a,.menupanel a{touch-action:manipulation}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  height:46px;padding:0 22px;border-radius:999px;white-space:nowrap;
  font-size:.95rem;font-weight:560;text-decoration:none;border:1px solid transparent;cursor:pointer;
  transition:background .2s var(--ease),color .2s var(--ease),border-color .2s var(--ease),transform .12s var(--ease);
}
.btn-primary{background:var(--accent);color:var(--accent-on)}
.btn-primary:hover{background:var(--accent-2)}
.btn-ghost{border-color:var(--line-2);color:var(--ink)}
.btn-ghost:hover{border-color:var(--ink-3);background:color-mix(in srgb,var(--ink) 4%,transparent)}
.btn-sm{height:40px;padding:0 18px;font-size:.9rem}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:scale(.98)}
.btn .ico{font-size:1.05em}
.deep .btn-ghost{border-color:var(--deep-line);color:var(--deep-ink)}
.deep .btn-ghost:hover{border-color:var(--deep-ink-2);background:rgba(255,255,255,.05)}
.deep .btn-primary{background:#ffffff;color:#0b1230}
.deep .btn-primary:hover{background:#dfe6fb}

/* ---------- shared section furniture ---------- */
section{position:relative}
.sec{padding-top:var(--sec-pad-top);padding-bottom:clamp(72px,9vw,130px)}
.eyebrow{
  font-family:'Geist Mono',ui-monospace,monospace;font-size:.72rem;font-weight:500;
  text-transform:uppercase;letter-spacing:.2em;color:var(--accent);margin-bottom:20px;
}
.h2{font-size:clamp(2rem,1.25rem + 2.5vw,3.15rem)}
.lede{margin-top:20px;color:var(--ink-2);font-size:clamp(1.02rem,.98rem + .3vw,1.16rem);max-width:60ch;line-height:1.6}
.sec-head{max-width:56ch}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(18px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
.rv.in{opacity:1;transform:none}
.rv-2{transition-delay:.09s}.rv-3{transition-delay:.18s}.rv-4{transition-delay:.27s}.rv-5{transition-delay:.36s}

/* ---------- hero: full-bleed dark opening scene ---------- */
.hero{
  position:relative;isolation:isolate;overflow:hidden;color:#fff;
  min-height:min(780px,calc(100dvh - 5px));display:flex;align-items:center;
  padding-top:calc(68px + clamp(40px,5vw,80px));padding-bottom:clamp(48px,6vw,96px);
  background:linear-gradient(175deg,#04081f 0%,#071238 46%,#0b1c55 78%,#10265f 100%);
}
.hero .wrap{width:100%;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.9fr);
  gap:clamp(32px,4vw,64px);align-items:center;position:relative;z-index:2}
.hero p.hero-dawn{
  /* .hero p is (0,1,1) and would win on colour and margin, so match it.
     No --day opacity here: the intro `rise` animation also targets .hero p, and
     an animation's filled end state beats a normal declaration - the fade was
     silently dead. It is a line of copy, so it simply stays legible. */
  margin:0 0 18px;font-family:'Geist Mono',ui-monospace,monospace;
  font-size:.76rem;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.92)}
.hero h1{font-size:clamp(2.5rem,1.35rem + 3.5vw,4.1rem);font-weight:420;letter-spacing:-.028em;
  line-height:1.04;max-width:15ch;color:#fff}
.hero p{margin-top:26px;font-size:clamp(1.02rem,.98rem + .34vw,1.18rem);
  /* Fixed, deliberately: deriving this from --day meant re-resolving the colour
     and repainting the copy on every frame of the cycle. */
  color:#e8f0ff;
  max-width:52ch;line-height:1.5}
.hero-cta{margin-top:40px;display:flex;flex-wrap:wrap;align-items:center;gap:clamp(18px,2.4vw,34px)}

/* hero CTAs: light pill with an inset dark arrow, plus an underlined text link */
.btn-hero{
  display:inline-flex;align-items:center;gap:18px;height:60px;padding:0 8px 0 28px;
  border-radius:999px;background:#f6f5f1;color:#0a1130;text-decoration:none;
  font-size:1rem;font-weight:560;white-space:nowrap;touch-action:manipulation;
  transition:background .2s var(--ease),transform .12s var(--ease);
}
.btn-hero .badge{width:44px;height:44px;border-radius:999px;background:#0a1130;color:#fff;
  display:grid;place-items:center;transition:transform .2s var(--ease)}
.btn-hero .badge .ico{font-size:17px}
.btn-hero:hover{background:#fff;transform:translateY(-1px)}
.btn-hero:hover .badge{transform:translateX(3px)}
.btn-hero:active{transform:scale(.985)}
.link-hero{display:inline-flex;align-items:center;gap:10px;color:#fff;font-weight:520;font-size:1rem;
  text-decoration:underline;text-underline-offset:6px;text-decoration-thickness:1.5px;
  white-space:nowrap;touch-action:manipulation;transition:opacity .2s var(--ease)}
.link-hero:hover{opacity:.78}
.link-hero .ico{font-size:16px}


/* drifting fragments, the depth layer behind the sphere */
.hero-field{position:absolute;inset:0;z-index:1;pointer-events:none}
/* Nothing may be painted between this canvas and the copy: a DOM layer on
   top stops the canvas being composited on its own, and every frame then
   repaints the hero, glyphs included. The ground haze is drawn on canvas. */
#skyCanvas{position:absolute;inset:0;width:100%;height:100%;display:block;
  will-change:transform;transform:translateZ(0)}
/* the ground haze the ridges sit in */

@media (prefers-reduced-motion:no-preference){
  .hero h1,.hero p,.hero-cta{animation:rise .85s var(--ease) both}
  .hero p{animation-delay:.09s}
  .hero-cta{animation-delay:.18s}
  @keyframes rise{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}
}

.frame{
  border-radius:var(--r-media);overflow:hidden;border:1px solid var(--line-2);
  background:var(--deep);box-shadow:var(--shadow-media);
}
.frame img{width:100%;height:auto}

/* ---------- latest updates carousel ---------- */

/* ---------- establishing product shot ---------- */
.establish{margin-top:clamp(40px,5vw,64px)}

/* ---------- stat band ---------- */
.stats{border-bottom:1px solid var(--line);background:var(--paper)}
.stats .wrap{padding-block:clamp(36px,4.5vw,56px)}
.statgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,2.6vw,40px)}
.stat{padding-left:clamp(16px,2vw,28px);border-left:1px solid var(--line-2)}
.stat:first-child{padding-left:0;border-left:0}
.stat .n{display:block;font-size:clamp(1.06rem,.98rem + .34vw,1.24rem);font-weight:620;
  letter-spacing:-.02em;color:var(--ink)}
.stat .s{display:block;margin-top:10px;color:var(--ink-2);font-size:.93rem;line-height:1.55}

/* ---------- comparison ---------- */
.compare{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(18px,2.4vw,28px);margin-top:clamp(40px,5vw,64px)}
.panel{border-radius:var(--r-panel);border:1px solid var(--line);background:var(--card);padding:clamp(26px,3vw,38px);box-shadow:var(--shadow-panel)}
.panel.good{background:var(--accent-soft);border-color:var(--accent-edge)}
.panel h3{font-size:1.28rem;letter-spacing:-.02em}
.panel .kicker{font-size:.82rem;color:var(--ink-3);font-weight:520;margin-bottom:10px;letter-spacing:.01em}
.panel.good .kicker{color:var(--accent)}
.panel ul{margin-top:24px;display:grid;gap:16px}
.panel li{display:flex;gap:12px;align-items:flex-start;font-size:.99rem;line-height:1.5;color:var(--ink-2)}
.panel li>span{min-width:0}
.panel li .ico{margin-top:.32em;font-size:1.05rem;color:var(--ink-3)}
.panel.good li{color:var(--ink)}
.panel.good li .ico{color:var(--accent)}

/* ---------- platform bento: 5 items, 5 cells, no empty cell ---------- */
.bento{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:clamp(16px,1.8vw,22px);
  margin-top:clamp(40px,5vw,64px);align-items:start}
.cell{
  border-radius:var(--r-panel);border:1px solid var(--line);background:var(--card);
  padding:clamp(24px,2.6vw,34px);box-shadow:var(--shadow-panel);display:flex;flex-direction:column;
}
.cell-lg{grid-column:span 4}
.cell-sm{grid-column:span 2}
.cell-md{grid-column:span 3}
.cell h3{font-size:1.16rem;display:flex;align-items:center;gap:10px;letter-spacing:-.018em}
.cell h3 .ico{font-size:1.22rem;color:var(--accent)}
.cell .sub{margin-top:6px;color:var(--ink-3);font-size:.84rem;font-weight:520;letter-spacing:.01em}
.cell p{margin-top:16px;color:var(--ink-2);font-size:.97rem;line-height:1.55}
.cell .shot{margin-top:26px;border-radius:14px;overflow:hidden;border:1px solid var(--line-2);background:var(--deep);
  max-height:290px;box-shadow:0 18px 40px -28px rgba(14,24,64,.5)}
.cell .shot img{width:100%;height:auto;object-fit:cover;object-position:top left}
.cell.tinted{
  background:linear-gradient(150deg,var(--deep) 0%,var(--deep-2) 100%);
  border-color:var(--deep-2);color:var(--deep-ink)
}
.cell.tinted h3{color:var(--deep-ink)}
.cell.tinted h3 .ico{color:#8fb4ff}
.cell.tinted .sub{color:var(--deep-ink-2)}
.cell.tinted p{color:var(--deep-ink-2)}
.cell.tinted .tags{border-top-color:var(--deep-line)}
.cell.tinted .tag{border-color:var(--deep-line);color:var(--deep-ink-2)}
.tags{margin-top:auto;padding-top:24px;border-top:1px solid var(--line);display:flex;flex-wrap:wrap;gap:8px}
.cell .tags{margin-top:auto}
.tag{border:1px solid var(--line-2);border-radius:var(--r-chip);padding:5px 10px;font-size:.78rem;color:var(--ink-3);
  font-family:'Geist Mono',ui-monospace,monospace;letter-spacing:.01em}

/* ---------- attack paths (editorial band, no fake diagram) ---------- */
.paths{background:var(--paper-2);border-block:1px solid var(--line)}
.paths .h2{max-width:20ch}
.pathgrid{margin-top:clamp(40px,5vw,60px);display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(24px,3vw,44px)}
.pathitem{padding-top:22px;border-top:2px solid var(--accent)}
.pathitem h3{font-size:1.05rem;margin-bottom:10px}
.pathitem p{color:var(--ink-2);font-size:.95rem;line-height:1.55}
.note{margin-top:clamp(36px,4vw,52px);padding:20px 24px;border-radius:var(--r-panel);border:1px dashed var(--line-2);
  color:var(--ink-3);font-size:.92rem;max-width:70ch}

/* ---------- findings split ---------- */
.split{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:clamp(34px,5vw,72px);align-items:center}
.split .frame{border-radius:var(--r-media)}
.deflist{margin-top:clamp(44px,5vw,72px);display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:clamp(32px,4vw,64px)}
.deflist div{padding-block:24px;border-top:1px solid var(--line)}
.deflist h3{font-size:1.02rem;margin-bottom:7px}
.deflist p{color:var(--ink-2);font-size:.95rem;line-height:1.55;max-width:48ch}

/* ---------- deployment ---------- */
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(28px,3.6vw,56px);margin-top:clamp(40px,5vw,64px)}
.feat h3{font-size:1.06rem;display:flex;align-items:center;gap:10px;margin-bottom:10px}
.feat h3 .ico{font-size:1.16rem;color:var(--accent)}
.feat p{color:var(--ink-2);font-size:.95rem;line-height:1.55}
.pull{
  margin-top:clamp(48px,6vw,80px);border-radius:var(--r-panel);border:1px solid var(--accent-edge);
  background:var(--accent-soft);padding:clamp(30px,3.6vw,48px);display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:clamp(24px,3vw,44px);align-items:center;
}
.pull q{quotes:none;font-size:clamp(1.5rem,1.1rem + 1.4vw,2.1rem);letter-spacing:-.024em;line-height:1.12;font-weight:560;display:block}
.pull p{color:var(--ink-2);font-size:.99rem;line-height:1.6}

/* ---------- licensing: deliberately asymmetric, middle tier carries weight ---------- */
.tiers{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.18fr) minmax(0,1fr);
  gap:clamp(16px,1.8vw,22px);margin-top:clamp(40px,5vw,64px);align-items:stretch}
.tier{border-radius:var(--r-panel);border:1px solid var(--line);background:var(--card);
  padding:clamp(26px,2.8vw,36px);display:flex;flex-direction:column;box-shadow:var(--shadow-panel)}
.tier.lead{border-color:var(--accent);box-shadow:0 24px 60px -40px rgba(26,79,216,.55);background:var(--card)}
.tier .name{font-size:1.3rem;font-weight:560;letter-spacing:-.02em}
.tier .unit{margin-top:18px;padding-top:18px;border-top:1px solid var(--line);
  font-family:'Geist Mono',ui-monospace,monospace;font-size:.72rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3)}
.tier .who{margin-top:16px;color:var(--ink-2);font-size:.95rem;line-height:1.55;min-height:4.8em}
/* Every licence is identical in capability. With the modules explained in their
   own section, this panel only has to name them and point at that section. */

.tier ul{margin-top:22px;display:grid;gap:13px;flex:1;align-content:start}
.tier li{display:flex;gap:11px;align-items:flex-start;font-size:.94rem;color:var(--ink-2);line-height:1.45}
.tier li>span{min-width:0}
.tier li .ico{margin-top:.3em;font-size:.98rem;color:var(--accent)}
.tier .btn{margin-top:30px;width:100%}
.tier{position:relative}


/* ---------- the one deliberate colour block: closing CTA plus footer ---------- */
.deep{
  background:linear-gradient(168deg,var(--deep) 0%,var(--deep-2) 100%);
  color:var(--deep-ink);
}
.cta{padding-block:clamp(84px,10vw,140px);text-align:left}
.cta .h2{max-width:18ch}
.cta p{margin-top:22px;color:var(--deep-ink-2);font-size:clamp(1.02rem,.98rem + .3vw,1.16rem);max-width:56ch;line-height:1.6}
.cta .row{margin-top:38px;display:flex;flex-wrap:wrap;gap:12px}
.cta .contact{margin-top:26px;font-size:.92rem;color:var(--deep-ink-2)}
.cta .contact a{color:var(--deep-ink);text-decoration:underline;text-underline-offset:3px}

footer{border-top:1px solid var(--deep-line);padding-top:clamp(48px,5vw,72px);
  padding-bottom:calc(clamp(48px,5vw,72px) + env(safe-area-inset-bottom))}
/* brand plus five link columns; the Assessments column made it five, and a
   four-column template silently wrapped Company onto a second row. */
.fgrid{display:grid;grid-template-columns:minmax(0,1.3fr) repeat(5,minmax(0,1fr));gap:clamp(20px,2.2vw,34px)}
.fbrand p{margin-top:16px;color:var(--deep-ink-2);font-size:.92rem;line-height:1.55;max-width:34ch}
.fcol h4{margin:0 0 16px;font-size:.78rem;text-transform:uppercase;letter-spacing:.14em;
  font-family:'Geist Mono',ui-monospace,monospace;font-weight:500;color:var(--deep-ink-2)}
.fcol a{display:block;padding-block:6px;color:var(--deep-ink);text-decoration:none;font-size:.93rem;opacity:.86;transition:opacity .2s var(--ease)}
.fcol a:hover{opacity:1;text-decoration:underline;text-underline-offset:3px}
.fbot{margin-top:clamp(40px,5vw,64px);padding-top:26px;border-top:1px solid var(--deep-line);
  display:flex;flex-wrap:wrap;gap:16px 28px;align-items:center;color:var(--deep-ink-2);font-size:.87rem}
.fbot a{color:var(--deep-ink-2);text-decoration:none}
.fbot a:hover{color:var(--deep-ink)}
.fbot .spacer{margin-left:auto}
.deep .brand{color:var(--deep-ink)}
/* the footer carries the mark as the product does: full-colour emblem, and the
   X in the brand gradient rather than flat white */
.brand-full span{color:#fff}
.brand-full b{font-weight:inherit;background:linear-gradient(120deg,#5fd0ff,#2b8cff);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}


/* ---------- hero scope: name the four reads under the copy ---------- */

/* ---------- figures: every product shot carries a caption ---------- */
figure.shotfig{margin:0}
.shotfig figcaption,.simfig figcaption{margin-top:14px;color:var(--ink-3);font-size:.87rem;
  line-height:1.5;max-width:74ch}
.mx-zoom img{cursor:pointer}

/* ---------- the platform, as one figure ---------- */
.platfig{margin:clamp(30px,3.4vw,48px) 0 0}
.platfig svg{display:block;width:100%;height:auto;
  background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-media);padding:clamp(16px,2vw,28px)}
.platfig figcaption{margin-top:14px;color:var(--ink-3);font-size:.87rem;line-height:1.5;max-width:74ch}
.pf-line{stroke:var(--accent-edge);stroke-width:1.5}
#pfArrow path{fill:var(--accent-edge)}
.pf-out{stroke:var(--line-2)}
.pf-flow{stroke:var(--accent);stroke-width:2.2}
.pf-node circle{r:9;fill:var(--accent);stroke:#fff;stroke-width:3}
.pf-dot circle{r:5.5;fill:var(--ink-3)}
.pf-halo{fill:var(--accent-soft);opacity:.75}
/* three strands merging into one - what correlation does, drawn plainly */
.pf-core>circle{fill:#0f1c44;stroke:#5f96ff;stroke-width:2.2}
.pf-merge{stroke:#8fc2ff;stroke-width:2.2;stroke-linecap:round;fill:none}
.pf-core-dot{fill:#fff;stroke:none}
.pf-lbl text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.11em;
  fill:var(--ink)}
.pf-lbl text.pf-sub{font-family:'Geist',system-ui,sans-serif;font-size:13px;letter-spacing:0;
  fill:var(--ink-3)}
.pf-mid text{fill:var(--accent)}
.pf-mid text.pf-sub{fill:var(--ink-3)}

/* the four reads, as text rather than cards */
.reads{margin-top:clamp(30px,3.2vw,44px);display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,2.4vw,38px)}
.read{padding-top:18px;border-top:2px solid var(--accent)}
.rlab{font-size:1.02rem;font-weight:620;letter-spacing:-.015em}
.read p:not(.rlab):not(.rkeys){margin-top:9px;color:var(--ink-2);font-size:.93rem;line-height:1.55}
.rvendor{font-family:'Geist Mono',ui-monospace,monospace;font-size:.62rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--accent);border:1px solid var(--accent-edge);
  background:var(--accent-soft);border-radius:999px;padding:3px 8px;margin-left:9px;vertical-align:2px}
.rkeys{margin-top:12px;font-family:'Geist Mono',ui-monospace,monospace;font-size:.73rem;
  line-height:1.7;color:var(--ink-3)}

@media (prefers-reduced-motion:no-preference){
  .pf-flow path{animation:pfrun 3.6s linear infinite}
  .pf-flow path:nth-child(2){animation-delay:.9s}
  .pf-flow path:nth-child(3){animation-delay:1.8s}
  .pf-flow path:nth-child(4){animation-delay:2.7s}
  @keyframes pfrun{from{stroke-dashoffset:199}to{stroke-dashoffset:0}}
}

/* ---------- the escalation chain ---------- */
.chain{margin-top:clamp(48px,5vw,76px);padding-top:clamp(30px,3vw,44px);border-top:1px solid var(--line)}
.chain-h{font-size:clamp(1.5rem,1.1rem + 1.2vw,2rem);letter-spacing:-.024em;margin-top:6px}
.chain-lede{margin-top:14px;color:var(--ink-2);font-size:1rem;line-height:1.6;max-width:66ch}
/* The figures ran the full column edge to edge. A little air on each side reads
   calmer and costs nothing that matters - they are all still above 0.8 scale. */
.platfig svg,.simfig svg{max-width:985px;margin-inline:auto}
.lifefig svg{max-width:1015px;margin-inline:auto}
.chainwrap{max-width:1035px;margin-inline:auto}
.jfig{max-width:470px;margin-inline:auto}

/* ---------- graph nodes: one language, shared by every graph on the page ----------
   The glyph says what the object IS, the ring says how it is doing. That frees the
   edge to carry the finding, which is the only thing the reader has to compare. */
.gnode .gn-disc{fill:var(--card);stroke:var(--gn);stroke-width:2.6}
.gnode .gn-ico{fill:var(--gn)}
.gnode .gn-halo{fill:none;stroke:var(--gn);stroke-opacity:.4;stroke-width:1.6;stroke-dasharray:3 5}
.gn-blue{--gn:#2f7de0}
.gn-amber{--gn:#c9852a}
.gn-red{--gn:#d02246}
.gn-green{--gn:#12a565}
@media (prefers-reduced-motion:no-preference){
  .gn-halo{transform-box:fill-box;transform-origin:center;animation:gnPing 3.4s ease-in-out infinite}
  @keyframes gnPing{0%,100%{opacity:.55;transform:scale(1)}58%{opacity:1;transform:scale(1.1)}}
}

/* The four findings drawn as one route: the node is the object, the edge is the finding.
   A machine account is a property of its host, so it is an edge label - drawing it as its
   own node made the host reach itself. */
.chainwrap{margin:clamp(24px,2.8vw,36px) 0 0;padding:clamp(18px,2.4vw,34px);
  border-radius:var(--r-media);border:1px solid var(--line);
  background:var(--card)}
.chainmap{display:block;width:100%;height:auto}
.cm-route path{stroke:url(#cmRoute);stroke-width:3.4;fill:none;stroke-linecap:round}
#cmArrow path{fill:#8f6bff}
.cm-pulse{stroke:#fff;stroke-opacity:.85;stroke-width:3.4;fill:none;stroke-linecap:round;
  stroke-dasharray:18 302;display:none}
.cm-erel text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13.5px;letter-spacing:.05em;
  fill:var(--ink);text-anchor:middle}
.cm-erel text.cm-esub{font-family:'Geist',system-ui,sans-serif;font-size:13px;letter-spacing:0;
  fill:var(--ink-3)}
.cm-erel text.cut{fill:#b3103a}
.cm-nlbl text{font-family:'Geist Mono',ui-monospace,monospace;font-size:14px;letter-spacing:.03em;
  fill:var(--ink)}
.cm-nlbl text.cm-nsub{font-family:'Geist',system-ui,sans-serif;font-size:13px;letter-spacing:0;
  fill:var(--ink-3)}
.cm-nlbl text.cm-nsub.amber{fill:#a3690f}
.cm-nlbl text.cm-nsub.red{fill:#b3103a}
.cm-sev rect{fill:#eceef2}
.cm-sev rect.s-med{fill:#e6effc}
.cm-sev rect.s-high{fill:#fdf0dd}
.cm-sev rect.s-crit{fill:#fbe0e5}
.cm-sev text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.12em;
  fill:#4c4f57}
.cm-sev text.t-crit{fill:#b3103a}
.cm-break path{stroke:#d02246;stroke-width:2.8;stroke-linecap:round;fill:none}
.cm-break path.cm-lead{stroke-width:1.3;stroke-dasharray:3 4;stroke-opacity:.6}
.cm-break rect{fill:#fdf1f3;stroke:#e8a3b1;stroke-width:1.4}
.cm-break text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.06em;
  fill:#b3103a}
.cm-key text{font-family:'Geist',system-ui,sans-serif;font-size:13px;fill:var(--ink-3)}
.cm-key .k-blue{fill:#fff;stroke:#2f7de0;stroke-width:2.4}
.cm-key .k-amber{fill:#fff;stroke:#c9852a;stroke-width:2.4}
.cm-key .k-red{fill:#fff;stroke:#d02246;stroke-width:2.4}
.cm-key .k-cut{stroke:#d02246;stroke-width:2.2;stroke-linecap:round;fill:none}
@media (prefers-reduced-motion:no-preference){
  .cm-pulse{display:inline;animation:cmRun 5.2s linear infinite}
  @keyframes cmRun{from{stroke-dashoffset:320}to{stroke-dashoffset:0}}
  .cm-break path:not(.cm-lead){animation:cmCut 5.2s ease-in-out infinite}
  @keyframes cmCut{0%,58%,100%{opacity:.7}74%{opacity:1}}
}
.chain-steps{margin:clamp(20px,2.4vw,30px) 0 0;padding:0;list-style:none;
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(16px,1.8vw,24px);counter-reset:cs}
.chain-steps li{position:relative;padding-top:20px;border-top:2px solid var(--line-2)}
.chain-steps li:nth-child(1){border-top-color:#9aa3b5}
.chain-steps li:nth-child(2){border-top-color:#2f7de0}
.chain-steps li:nth-child(3){border-top-color:#e0952f}
.chain-steps li:nth-child(4){border-top-color:#e0455f}
.chain-steps h4{margin:10px 0 8px;font-size:1.02rem;letter-spacing:-.01em}
.chain-steps p{color:var(--ink-2);font-size:.93rem;line-height:1.55}
.sev{display:inline-block;border-radius:999px;padding:3px 10px;font-family:'Geist Mono',ui-monospace,monospace;
  font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;font-weight:600}
.sev-low{background:#eceef2;color:#5b6172}
.sev-med{background:#e6effc;color:#245ec4}
.sev-high{background:#fdf0dd;color:#a2610d}
.sev-crit{background:#fdE7ea;color:#b31f38}

/* ---------- asset discovery ---------- */
.discovery{background:var(--paper-2);border-block:1px solid var(--line)}
.radarstage{margin-top:clamp(30px,3.4vw,48px);display:grid;
  grid-template-columns:minmax(320px,1.30fr) minmax(0,1fr);gap:clamp(22px,2.4vw,38px);align-items:center}
.radarfig{margin:0}
.radarfig svg{display:block;width:100%;height:auto;text-rendering:geometricPrecision;
  shape-rendering:geometricPrecision}
.radarfig figcaption{margin-top:12px;color:var(--ink-3);font-size:.86rem;line-height:1.5}
.rd-field{fill:#0c1330}
.rd-zone .z-un{fill:rgba(255,84,112,.105)}
.rd-zone .z-dis{fill:rgba(143,107,255,.115)}
.rd-zone .z-stale{fill:rgba(224,165,58,.105)}
.rd-zone .z-ok{fill:rgba(63,185,132,.115)}
.rd-ring circle{fill:none;stroke:rgba(180,216,255,.58);stroke-width:1.4}
.rd-cross{stroke:rgba(156,202,255,.28);stroke-width:1.2;fill:none}
.rd-blip circle{stroke:none}
.rd-blip .b-ok{fill:#3fb984}
.rd-blip .b-stale{fill:#e0a53a}
.rd-blip .b-dis{fill:#9b7cff}
.rd-blip .b-un{fill:#ff5470}
.rd-hit{fill:#ff5470;stroke:#fff;stroke-width:2.4}
.rd-hit-halo{fill:none;stroke:#ff5470;stroke-width:2.1;stroke-dasharray:3 4}
.rd-lead{stroke-width:1.5;fill:none}
.rd-lead-in{stroke:rgba(153,201,255,.7)}
.rd-lead-out{stroke:#8e9ab4}
/* the readout is part of the instrument, so it is inked for the scope, not the page */
.rd-panel rect{fill:#0b1230;stroke:rgba(158,204,255,.58);stroke-width:1.1}
.rd-panel .rd-rule{stroke:rgba(158,204,255,.4);stroke-width:1;fill:none}
.rd-panel .rd-dot{fill:#ff5470}
.rd-panel text.rd-hd{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;
  letter-spacing:.16em;fill:#a9cdff}
.rd-panel text.rd-f{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;
  letter-spacing:.09em;fill:#9db6e4}
.rd-panel text.rd-v{font-family:'Geist',system-ui,sans-serif;font-size:14px;fill:#f6f9ff}
.rd-panel text.rd-v.rd-warn{fill:#ff8098;font-weight:560}
.rd-ringlbl rect{fill:#0c1330;stroke:rgba(158,204,255,.52);stroke-width:1.1}
.rd-ringlbl text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.12em;
  fill:#b9d7ff}

.rd-key{margin:0 0 clamp(22px,2.6vw,32px);padding:0;list-style:none;display:grid;gap:15px}
.rd-key li{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:12px;row-gap:2px}
.rd-key .k{grid-row:1;width:11px;height:11px;border-radius:50%;margin-top:7px}
.rd-key .rd-n{grid-column:2;font-size:1rem;color:var(--ink-2)}
.rd-key .rd-d{grid-column:2;color:var(--ink-3);font-size:.88rem;line-height:1.45}
.rd-key b{font-variant-numeric:tabular-nums;color:var(--ink);font-weight:660;font-size:1.16rem;
  margin-right:3px}
.rd-key .k-ok{background:#3fb984}
.rd-key .k-stale{background:#e0a53a}
.rd-key .k-dis{background:#8f6bff}
.rd-key .k-un{background:#ff5470}

.rd-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-panel);
  padding:clamp(20px,2.2vw,30px)}
.rd-flag{font-family:'Geist Mono',ui-monospace,monospace;font-size:.68rem;letter-spacing:.14em;
  text-transform:uppercase;color:#c0392f}
.rd-card h3{margin:8px 0 16px;font-family:'Geist Mono',ui-monospace,monospace;font-size:1.16rem;
  letter-spacing:.02em}
.rd-card dl{margin:0;display:grid;gap:13px}
.rd-card dt{font-family:'Geist Mono',ui-monospace,monospace;font-size:.68rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink-3)}
.rd-card dd{margin:4px 0 0;color:var(--ink-2);font-size:.94rem;line-height:1.5}
.rd-note{margin-top:20px;padding-top:18px;border-top:1px solid var(--line);
  display:flex;gap:11px;align-items:flex-start;color:var(--ink-2);font-size:.94rem;line-height:1.55}
.rd-note .ico{color:var(--accent);flex:none;font-size:1.05rem;margin-top:2px}

/* Nothing below is decoration: the beam is the scan, and a host is lit because the
   beam just reached it. Each blip's delay is its own bearing, so the order the scope
   fills in is the order a sweep would actually find things.

   The acquisition - contact, leader, window, fields - runs on ONE timeline with no
   per-element delay. Arrival is staggered inside each keyframe; departure is the same
   instant in all of them, so the window can never close out from under its own rows.
   With motion off, every marking is simply present: the picture is complete either way. */
@media (prefers-reduced-motion:no-preference){
  .rd-sweep{transform-box:view-box;transform-origin:250px 260px;animation:rdSpin 8s linear infinite}
  @keyframes rdSpin{to{transform:rotate(360deg)}}
  .rd-blip circle{animation:rdBlip 8s linear infinite backwards}
  @keyframes rdBlip{0%{opacity:0}1.5%{opacity:1}20%{opacity:.72}55%{opacity:0}100%{opacity:0}}
  .rd-hit{transform-box:fill-box;transform-origin:center;animation:rdHit 8s linear infinite}
  @keyframes rdHit{0%,4.125%{opacity:0;transform:scale(.4)}
    5.0%{opacity:1;transform:scale(1.7)}6.875%{transform:scale(1)}
    82.5%{opacity:1;transform:scale(1)}88.75%,100%{opacity:0;transform:scale(1)}}
  .rd-hit-halo{transform-box:fill-box;transform-origin:center;animation:rdHalo 8s ease-out infinite}
  @keyframes rdHalo{0%,4.125%{opacity:0;transform:scale(.5)}
    5.75%{opacity:1;transform:scale(1.4)}9.375%{opacity:.6;transform:scale(1)}
    82.5%{opacity:.6;transform:scale(1);animation-timing-function:linear}88.75%,100%{opacity:0;transform:scale(1)}}
  .rd-lead{stroke-dasharray:100}
  .rd-lead-in{animation:rdLeadA 8s ease-out infinite}
  .rd-lead-out{animation:rdLeadB 8s ease-out infinite}
  @keyframes rdLeadA{0%,6.25%{opacity:0;stroke-dashoffset:100}6.875%{opacity:1}10.625%{stroke-dashoffset:0}82.5%{opacity:1;stroke-dashoffset:0;animation-timing-function:linear}88.75%,100%{opacity:0;stroke-dashoffset:0}}
  @keyframes rdLeadB{0%,10.625%{opacity:0;stroke-dashoffset:100}11.25%{opacity:1}14.375%{stroke-dashoffset:0}82.5%{opacity:1;stroke-dashoffset:0;animation-timing-function:linear}88.75%,100%{opacity:0;stroke-dashoffset:0}}
  .rd-chrome{animation:rdChrome 8s linear infinite}
  @keyframes rdChrome{0%,14.375%{opacity:0}18.125%{opacity:1}82.5%{opacity:1}88.75%,100%{opacity:0}}
  /* the fields arrive one at a time, in the order a collector would read them */
  .rd-row.r1{animation:rdRow1 8s linear infinite}
  .rd-row.r2{animation:rdRow2 8s linear infinite}
  .rd-row.r3{animation:rdRow3 8s linear infinite}
  .rd-row.r4{animation:rdRow4 8s linear infinite}
  .rd-row.r5{animation:rdRow5 8s linear infinite}
  .rd-row.r6{animation:rdRow6 8s linear infinite}
  @keyframes rdRow1{0%,19.375%{opacity:0;transform:translateX(-10px)}23.125%{opacity:1;transform:translateX(0)}82.5%{opacity:1}88.75%,100%{opacity:0}}
  @keyframes rdRow2{0%,22.875%{opacity:0;transform:translateX(-10px)}26.625%{opacity:1;transform:translateX(0)}82.5%{opacity:1}88.75%,100%{opacity:0}}
  @keyframes rdRow3{0%,26.375%{opacity:0;transform:translateX(-10px)}30.125%{opacity:1;transform:translateX(0)}82.5%{opacity:1}88.75%,100%{opacity:0}}
  @keyframes rdRow4{0%,29.875%{opacity:0;transform:translateX(-10px)}33.625%{opacity:1;transform:translateX(0)}82.5%{opacity:1}88.75%,100%{opacity:0}}
  @keyframes rdRow5{0%,33.375%{opacity:0;transform:translateX(-10px)}37.125%{opacity:1;transform:translateX(0)}82.5%{opacity:1}88.75%,100%{opacity:0}}
  @keyframes rdRow6{0%,36.875%{opacity:0;transform:translateX(-10px)}40.625%{opacity:1;transform:translateX(0)}82.5%{opacity:1}88.75%,100%{opacity:0}}
}

/* ---------- attack simulation ---------- */
.simfig{margin:clamp(30px,3.4vw,48px) 0 0}
.simfig svg{display:block;width:100%;height:auto;
  background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-media);padding:clamp(14px,2vw,26px)}
.sim-lane text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.16em;
  fill:var(--ink-3)}
.sim-rule path{stroke:var(--line);stroke-width:1}
.sim-dead-line path{stroke:#c9d0e0;stroke-width:1.6;stroke-dasharray:5 6}
.sim-pulse{display:none}
.sim-dead circle{fill:var(--paper);stroke:#c1c9da;stroke-width:2}
.sim-x text{font-family:'Geist',system-ui,sans-serif;font-size:13px;fill:var(--ink-3)}
.sim-choke{fill:none;stroke:#d02246;stroke-width:2;stroke-dasharray:4 5}
/* an open gem outline - no fill, nothing inside it */
.sim-jewel .gem{fill:none;stroke:#12a565;stroke-width:2.6;stroke-linejoin:round;stroke-linecap:round}
/* A wash inside the stone so it reads as an object the route arrives AT, rather than an outline the
   route happens to end near. Kept faint: the diagram's weight belongs on the path and the choke point. */
.sim-jewel .gem-fill{fill:#12a565;fill-opacity:.10;stroke:none}
/* The facets carry the shape at this size. Thinner and lighter than the outline on purpose -- at equal
   weight they read as clutter and the stone stops looking cut. */
.sim-jewel .gem-facet{fill:none;stroke:#12a565;stroke-opacity:.45;stroke-width:1.2;stroke-linecap:round}
.sim-lbl text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.12em;
  fill:var(--ink)}
.sim-lbl text.sim-sub{font-family:'Geist',system-ui,sans-serif;font-size:13px;letter-spacing:0;
  fill:var(--ink-3)}
.sim-cut path{stroke:#d02246;stroke-width:1.4}
.sim-cut text{font-family:'Geist Mono',ui-monospace,monospace;font-size:13px;letter-spacing:.13em;
  fill:#b3103a}
.sim-key text{font-family:'Geist',system-ui,sans-serif;font-size:13px;fill:var(--ink-3)}
.sim-key .k-route{stroke:#8f6bff;stroke-width:4.4;stroke-linecap:round;fill:none}
.sim-key circle.k-dead{fill:var(--paper);stroke:#c1c9da;stroke-width:2}
.sim-key circle.k-choke{fill:none;stroke:#d02246;stroke-width:2;stroke-dasharray:3 3}
.sim-lbl text.sim-jw{fill:#0d7f4e}
@media (prefers-reduced-motion:no-preference){
  .sim-pulse{display:inline;animation:simrun 5s linear infinite}
  @keyframes simrun{from{stroke-dashoffset:274}to{stroke-dashoffset:0}}
  /* the dropped branches drift, so they read as considered-and-rejected rather than drawn-in */
  .sim-dead-line path{animation:simDrift 3.6s linear infinite}
  @keyframes simDrift{to{stroke-dashoffset:-22}}
  .sim-choke{transform-box:fill-box;transform-origin:center;
    animation:simchoke 4.4s ease-in-out infinite}
  @keyframes simchoke{0%,55%,100%{opacity:.55;transform:scale(1)}70%{opacity:1;transform:scale(1.14)}}
}

/* ---------- crown jewels: one asset, four inbound routes ---------- */
.jewels{background:var(--paper-2);border-block:1px solid var(--line)}
.jstage{margin-top:clamp(34px,3.6vw,52px);display:grid;
  grid-template-columns:minmax(300px,.95fr) minmax(0,1fr);gap:clamp(26px,3.4vw,54px);align-items:center}
.jfig{display:block;width:100%;height:auto}
.j-line path{stroke:#9db4e8;stroke-width:1.7}
#jArrow path{fill:#7f9ad8}
.j-flow{display:none}
.j-flow path{stroke-width:2.6}
.j-glow{opacity:.9}
.j-flow path{stroke:#12a565}
.j-name text{font-family:'Geist Mono',ui-monospace,monospace;font-size:16px;letter-spacing:.08em;
  fill:var(--ink)}
.j-name text.j-sub{font-family:'Geist',system-ui,sans-serif;font-size:14px;letter-spacing:0;
  fill:var(--ink-3)}
.j-lbl text{font-family:'Geist Mono',ui-monospace,monospace;font-size:14.5px;letter-spacing:.14em;
  fill:var(--ink-3)}
.j-lbl text.j-n{font-family:'Geist',system-ui,sans-serif;font-size:17px;letter-spacing:-.01em;
  font-weight:640;fill:var(--ink)}
.j-lbl text.j-sub{font-family:'Geist',system-ui,sans-serif;font-size:14px;letter-spacing:0;
  fill:var(--ink-3)}

.jfeed{margin:0;padding:0;list-style:none;display:grid;gap:clamp(13px,1.5vw,18px)}
.jfeed li{position:relative;padding:16px 18px 16px 20px;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-panel)}
.jfeed li::before{content:"";position:absolute;left:0;top:16px;bottom:16px;width:3px;
  border-radius:3px;background:var(--accent)}
.jlab{display:block;font-family:'Geist Mono',ui-monospace,monospace;font-size:.67rem;
  letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:6px}
.jfeed p{color:var(--ink-2);font-size:.94rem;line-height:1.55}
.jfeed b{color:var(--ink);font-weight:620}

.jnote{margin-top:clamp(26px,2.8vw,38px);display:flex;gap:12px;align-items:flex-start;
  padding:18px 20px;border-radius:var(--r-panel);background:var(--card);
  border:1px solid var(--accent-edge);color:var(--ink-2);font-size:.97rem;line-height:1.6}
.jnote .ico{color:var(--accent);flex:none;font-size:1.1rem;margin-top:2px}
.jnote strong{color:var(--ink)}

@media (prefers-reduced-motion:no-preference){
  /* each route arrives in turn, and its card lights up with it */
  .j-flow{display:inline}
  .j-flow path{animation:jrun 5.2s linear infinite}
  .j-flow path:nth-child(2){animation-delay:1.3s}
  .j-flow path:nth-child(3){animation-delay:2.6s}
  .j-flow path:nth-child(4){animation-delay:3.9s}
  @keyframes jrun{from{stroke-dashoffset:119}to{stroke-dashoffset:0}}
  .j-glow{animation:jglow 5.2s ease-in-out infinite}
  @keyframes jglow{0%,100%{opacity:.5}50%{opacity:1}}
  .jfeed li{animation:jlift 5.2s ease-in-out infinite}
  .jfeed .jf-2{animation-delay:1.3s}
  .jfeed .jf-3{animation-delay:2.6s}
  .jfeed .jf-4{animation-delay:3.9s}
  @keyframes jlift{0%,72%,100%{border-color:var(--line)}14%{border-color:var(--accent-edge)}}
}

/* ---------- the life of a finding: a swimlane, not a tree ---------- */
.lifefig{margin:clamp(44px,5vw,68px) 0 0}
.lf-title{font-family:'Geist Mono',ui-monospace,monospace;font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-3);margin-bottom:12px}
.lifefig svg{display:block;width:100%;height:auto;background:var(--card);
  border:1px solid var(--line);border-radius:var(--r-media);padding:clamp(14px,2vw,26px)}
.lifefig figcaption{margin-top:14px;color:var(--ink-3);font-size:.87rem;line-height:1.5;max-width:74ch}
.lf-lane rect{fill:rgba(20,22,27,.018)}
.lf-lane rect.alt{fill:rgba(43,140,255,.045)}
.lf-lanerule{stroke:var(--line);stroke-width:1;fill:none}
.lf-lanelbl text{font-family:'Geist Mono',ui-monospace,monospace;font-size:12.5px;letter-spacing:.13em;
  fill:var(--ink-2)}
.lf-lanelbl text.lf-lanesub{font-family:'Geist',system-ui,sans-serif;font-size:12.5px;letter-spacing:0;
  fill:var(--ink-3)}
.lf-stage text{font-family:'Geist Mono',ui-monospace,monospace;font-size:12.5px;letter-spacing:.15em;
  fill:var(--ink-3)}
.lf-edge path{stroke:#3d4550;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
#lfArrow path{fill:#3d4550}
.lf-back path{stroke:var(--accent);stroke-width:2;stroke-dasharray:6 5}
#lfArrowBack path.back{fill:var(--accent)}
.lf-backlbl{font-family:'Geist',system-ui,sans-serif;font-size:13px;fill:var(--accent);
  text-anchor:middle}
.lf-box rect{fill:#fff;stroke:#c3cbdb;stroke-width:1.6}
.lf-box rect.lf-done{fill:#e6f5ec;stroke:#12a565}
.lf-boxlbl text{font-family:'Geist',system-ui,sans-serif;font-size:13.5px;font-weight:600;fill:var(--ink)}
.lf-boxlbl text.lf-sub{font-size:12.5px;font-weight:400;fill:var(--ink-3)}
.lf-boxlbl text.lf-doneT{fill:#0d7f4e}
.lifereads{margin-top:clamp(26px,3vw,40px)}

/* ---------- reports ---------- */
.repwrap{margin-top:clamp(30px,3.4vw,44px);border:1px solid var(--line);border-radius:var(--r-panel);
  overflow:hidden;background:var(--card)}
.rephead{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  padding:16px clamp(18px,2vw,24px);border-bottom:1px solid var(--line);background:var(--paper-2);
  font-weight:620;font-size:.98rem}
.repmeta{font-family:'Geist Mono',ui-monospace,monospace;font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);font-weight:500}
.replist{margin:0;padding:0;list-style:none}
.replist li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:16px;align-items:center;
  padding:15px clamp(18px,2vw,24px);border-top:1px solid var(--line)}
.replist li:first-child{border-top:0}
.replist b{display:block;font-size:.97rem;font-weight:600}
.replist span:not(.rsev){display:block;color:var(--ink-3);font-size:.88rem;margin-top:3px}
.replist time{color:var(--ink-3);font-size:.84rem;white-space:nowrap;
  font-family:'Geist Mono',ui-monospace,monospace}
.rsev{border-radius:999px;padding:3px 10px;font-family:'Geist Mono',ui-monospace,monospace;
  font-size:.64rem;letter-spacing:.1em;text-transform:uppercase;font-weight:600;white-space:nowrap}
.rsev-crit{background:#fde7ea;color:#b31f38}
.rsev-high{background:#fdf0dd;color:#a2610d}
.rsev-med{background:#e6effc;color:#245ec4}
.rsev-low{background:#eceef2;color:#5b6172}
.rsev-ok{background:#e4f4ea;color:#1c7a45}

/* ---------- lightbox ---------- */
.mx-lb{position:fixed;inset:0;z-index:60;display:none;place-items:center;
  background:rgba(6,10,26,.86);padding:clamp(16px,3vw,48px)}
.mx-lb.open{display:grid}
.mx-lb img{max-width:100%;max-height:88vh;border-radius:10px;
  box-shadow:0 40px 90px -30px rgba(0,0,0,.8)}
.mx-lb-cap{margin-top:14px;color:rgba(232,240,255,.82);font-size:.9rem;text-align:center;max-width:78ch}
.mx-lb-x{position:absolute;top:clamp(12px,2vw,24px);right:clamp(12px,2vw,24px);width:42px;height:42px;
  border-radius:999px;border:1px solid rgba(210,226,255,.34);background:transparent;color:#fff;
  cursor:pointer;display:grid;place-items:center;font-size:20px;line-height:1}
.mx-lb-x:hover{border-color:rgba(210,226,255,.7)}
@media (prefers-reduced-motion:no-preference){
  .mx-lb.open img{animation:lbIn .18s var(--ease) both}
  @keyframes lbIn{from{opacity:0;transform:scale(.98)}to{opacity:1;transform:none}}
}

/* ---------- responsive collapse, declared per layout ---------- */
@media (max-width:1080px){
  .hero .wrap{grid-template-columns:1fr;gap:clamp(36px,6vw,56px)}
  .hero{min-height:0;padding-top:calc(68px + clamp(36px,6vw,60px));padding-bottom:clamp(44px,7vw,76px)}
  .hero h1{max-width:18ch}
  .split{grid-template-columns:1fr;gap:36px}
  .pull{grid-template-columns:1fr;gap:20px}
  .cell-lg,.cell-md,.cell-sm{grid-column:span 6}
  .tiers{grid-template-columns:1fr}
  .tier .who{min-height:0}
  .fgrid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .fbrand{grid-column:span 3}
}
@media (max-width:820px){
  .navlinks{display:none}
  .menubtn{display:grid}
  .deflist{grid-template-columns:1fr}
  .statgrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:28px}
  .stat{padding-left:0;border-left:0}
  .stat:nth-child(n+3){padding-top:26px;border-top:1px solid var(--line-2)}
  .compare{grid-template-columns:1fr}
  .pathgrid{grid-template-columns:1fr;gap:28px}
  .grid2{grid-template-columns:1fr;gap:32px}
}
@media (max-width:560px){
  body{font-size:16px}
  .nav-actions > .btn{display:none}
  .hero-cta{gap:18px}
  .btn-hero,.link-hero{width:100%}
  .btn-hero{justify-content:space-between;padding-right:8px}
  .wrap{padding-inline:20px}
  .statgrid{grid-template-columns:1fr;gap:22px}
  .stat:nth-child(n+2){padding-top:22px;border-top:1px solid var(--line-2)}
  .fgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .fbrand{grid-column:span 2}
  .hero-cta .btn,.cta .row .btn{width:100%}
}

@media (prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none;transition:none}
  .btn:hover,.btn:active{transform:none}
  *{animation-duration:.001ms !important;animation-iteration-count:1 !important;transition-duration:.001ms !important}
}

@media (max-width:1080px){
  .reads{grid-template-columns:repeat(2,minmax(0,1fr))}
  .chain-steps{grid-template-columns:repeat(2,minmax(0,1fr))}
  .radarstage{grid-template-columns:minmax(0,1fr);gap:26px}
  .radarfig svg{max-width:660px;margin-inline:auto}
  .jstage{grid-template-columns:minmax(0,1fr);gap:28px}
  .jfig{max-width:460px;margin-inline:auto}
  .lifereads{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* Both diagrams scale with the viewport, so on a narrow screen their labels
   drop to about 4px - illegible. Below this width the caption carries the point
   and the text blocks carry the detail; an unreadable diagram is worse than none. */
@media (max-width:820px){
  .platfig svg,.simfig svg,.lifefig svg{display:none}
  .platfig figcaption,.simfig figcaption,.lifefig figcaption{margin-top:0;padding-left:15px;
    border-left:3px solid var(--accent);color:var(--ink-2);font-size:.96rem;max-width:none}
  .lifefig{margin-top:clamp(30px,4vw,44px)}
  /* the ordered list below the map tells the same story in words */
  .chainwrap{display:none}
  /* and the four-item feed beside it carries every number on the asset */
  .jfig{display:none}
  /* the scope survives because its shape still reads; only the small text goes,
     and the key underneath already decodes every colour on it */
  .rd-ringlbl,.rd-panel,.rd-lead{display:none}
  .radarfig{overflow:hidden}
  .radarfig svg{width:163%;max-width:none;margin-inline:0}
}
@media (max-width:720px){
  .reads{grid-template-columns:minmax(0,1fr)}
  .chain-steps{grid-template-columns:minmax(0,1fr)}
  .replist li{grid-template-columns:auto minmax(0,1fr);row-gap:6px}
  .replist time{grid-column:2}
}

@media (prefers-reduced-transparency:reduce){
  .nav.stuck{backdrop-filter:none;-webkit-backdrop-filter:none;background:var(--deep)}
}

/* ---------- demo request page ---------- */
/* header is sticky with margin-bottom:-68px, so a page without a hero has to
   put that height back or the nav covers its first heading */
.subpage main{padding-top:68px;padding-bottom:0}
/* the section supplies the gap, so it is one number rather than three stacked */
.subpage main > .sec:first-of-type{--sec-pad-top:clamp(26px,3.4vw,48px)}
.subpage main > .sec:last-of-type{padding-bottom:clamp(44px,5.5vw,84px)}
.subpage footer{padding-block:34px}
.subpage .fbot{border-top:0;padding-top:0;margin-top:0}
.dstage{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.94fr);
  gap:clamp(32px,4.5vw,76px);align-items:start}
.dtitle{font-size:clamp(1.9rem,3.2vw,2.7rem)}
.dpoints{margin-top:clamp(28px,3.2vw,40px);display:grid;gap:20px}
.dpoints li{display:flex;gap:14px;align-items:flex-start}
.dpoints .ico{color:var(--accent);font-size:1.15rem;margin-top:3px}
.dpoints b{display:block;font-size:1rem;color:var(--ink)}
.dpoints span{display:block;margin-top:4px;color:var(--ink-2);font-size:.93rem;line-height:1.55}
.demoform{background:var(--card);border:1px solid var(--line);border-radius:var(--r-media);
  padding:clamp(24px,2.8vw,40px)}
.fh{font-size:1.12rem;font-weight:620;letter-spacing:-.012em;margin-bottom:22px}
.ff{margin-bottom:16px}
.ff label{display:block;font-size:.88rem;font-weight:560;color:var(--ink-2);margin-bottom:7px}
.ff .req{color:#c0392f;margin-left:3px}
/* the counterpart to .req - every other field is marked required, so the one
   that is not has to say so rather than leave it to be inferred */
.ff .opt{color:var(--ink-3);font-weight:400;margin-left:6px;font-size:.86em}
.ff input,.ff textarea{width:100%;font:inherit;font-size:.96rem;color:var(--ink);
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r-chip);
  padding:11px 13px;transition:border-color .15s ease,box-shadow .15s ease}
.ff textarea{resize:vertical;min-height:104px;line-height:1.5}
.ff input::placeholder,.ff textarea::placeholder{color:var(--ink-3);opacity:.75}
.ff input:focus,.ff textarea:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft)}
.ff input[aria-invalid="true"],.ff textarea[aria-invalid="true"]{border-color:#c0392f}
.fe{font-size:.84rem;color:#c0392f}
.fe:not(:empty){margin-top:6px}
/* reachable by a bot, out of view for a person: display:none is skipped by some */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.demobtn{width:100%;margin-top:8px}
.demobtn[disabled]{opacity:.6;cursor:progress}
.dform-note{margin-top:14px;color:var(--ink-3);font-size:.86rem;line-height:1.5}
.dform-msg{margin-top:14px;font-size:.93rem;line-height:1.5}
.dform-msg.ok{color:#0d7f4e;font-weight:560}
.dform-msg.bad{color:#c0392f}
@media (max-width:860px){.dstage{grid-template-columns:minmax(0,1fr);gap:32px}}

/* ---------- request received ---------- */
.tstage{max-width:60ch;margin-inline:auto;text-align:center}
.tmark{width:64px;height:64px;border-radius:50%;display:grid;place-items:center;margin:0 auto 26px;
  background:#e6f5ec;color:#0d7f4e;font-size:28px}
.tnote{margin-top:18px;color:var(--ink-3);font-size:.95rem;line-height:1.6}
.tnote a{color:var(--accent)}
.tback{margin-top:32px}

/* the confirmation takes the form's place, so nothing can be resubmitted */
.dsent{background:var(--card);border:1px solid var(--line);border-radius:var(--r-media);
  padding:clamp(30px,3.4vw,46px);text-align:center}
.dsent:focus{outline:none}
.dsent .tmark{margin-bottom:22px}
.dsent-h{font-size:1.35rem;font-weight:620;letter-spacing:-.015em;color:var(--ink)}
.dsent-p{margin-top:12px;color:var(--ink-2);line-height:1.6}
.dsent-n{margin-top:16px;color:var(--ink-3);font-size:.92rem;line-height:1.6}
.dsent-n a{color:var(--accent)}

/* Two pages side by side, so neither reads as a footnote of the other. */
/* One column of links does not need the full sheet. */
.nd-grid.slim{grid-template-columns:250px minmax(0,1fr)}
.nd-p.narrow{width:min(560px,calc(100vw - 48px))}
/* A tile for a page we have no screenshot of. Same height as a shot, so the two
   never read as different kinds of thing. */
.nd-tile .mark{height:112px;border-radius:0;border-bottom:1px solid var(--deep-line)}
.nd-tile .mark .ico{font-size:52px;color:#8fc2ff}

/* A subpage leads with its own name, so the line that used to be the heading
   sits under it as the deck: bigger than the lede, quieter than the name. */
.deck{margin-top:16px;max-width:54ch;font-weight:500;color:var(--ink-2);text-wrap:balance;
  font-size:clamp(1.2rem,1rem + 1vw,1.68rem);line-height:1.3;letter-spacing:-.012em}
.deck + .lede{margin-top:18px}

/* ---------- where a fragment link lands ----------
   The header is sticky, so every fragment has to clear it: scroll-padding-top
   does that once for the whole document. A section then cancels its own top
   padding with a negative scroll-margin, so the visitor arrives looking at the
   heading they clicked for rather than at 130px of blank padding.
   --sec-pad-top is the single source for both, which is why the subpage override
   sets the variable instead of setting padding-top directly. */
:root{--nav-h:68px;--anchor-air:36px;--sec-pad-top:clamp(72px,9vw,130px)}
html{scroll-padding-top:calc(var(--nav-h) + var(--anchor-air))}
.sec[id]{scroll-margin-top:calc(-1 * var(--sec-pad-top))}
.chain[id]{scroll-margin-top:calc(-1 * clamp(30px,3vw,44px))}
/* A reveal target is mid-transition when the browser computes the scroll, so it
   lands a couple of pixels out and differently depending on scroll history.
   Same specificity and same values as .rv.in, so nothing flashes when :target
   is lost. Never touch opacity or transform elsewhere for :target - .rv owns both. */
.rv:target,.rv:has(:target){opacity:1;transform:none;transition:none}

/* ---------- nav: a top-level item with no panel ----------
   Deployment and Licensing lead to one place each, so they are plain links.
   They sit outside .nd deliberately: nav.js iterates .nd and would otherwise
   set aria-expanded on a trigger that opens nothing. */
.navlink{display:inline-flex;align-items:center;height:34px;padding:0 12px;border-radius:999px;
  font-size:.93rem;font-weight:500;color:rgba(232,240,255,.85);text-decoration:none;
  transition:background .16s var(--ease),color .16s var(--ease)}
.navlink:hover{background:rgba(143,194,255,.13);color:#fff}
/* two page tiles and nothing else */
.nd-grid.duo{grid-template-columns:repeat(2,minmax(0,1fr))}
/* The four reads are named here but not linked: they are one row on the page, so
   four links would be four promises and one destination. */
.nd-lead{display:block}
.nd-note{margin:10px 2px 0;font-size:.84rem;line-height:1.55;color:#93a4cb}
.nd-note b{font-weight:500;color:#c8d8f5}

/* #findings is the only section whose heading lives in a .split column rather
   than a .sec-head, and align-items:center dropped it below every other
   section heading on arrival. The anchor lands on the section, so the column
   has to start at the top for the eyebrow to be the first ink like everywhere else. */
#findings .split{align-items:start}

/* ---------- topic landing pages ----------
   Prose measure, not the marketing grid: these pages are read, and an AI crawler
   quotes a passage from them rather than sending a click. */
/* The heading wants a short measure and the deck a long one, so they cannot
   share a cap: at 34ch the deck was running to seven lines. */
.topic .sec-head{max-width:none}
.topic h1{max-width:19ch}
.topic .deck{max-width:40ch}
.prose{max-width:74ch;margin-top:clamp(30px,3.6vw,52px)}
.prose h2{font-size:clamp(1.3rem,1.05rem + .9vw,1.65rem);letter-spacing:-.018em;
  margin:clamp(34px,3.6vw,52px) 0 14px}
.prose h2:first-child{margin-top:0}
.prose p{color:var(--ink-2);line-height:1.7;margin-bottom:15px}
.prose ul{margin:0 0 15px;padding-left:1.15em}
.prose li{color:var(--ink-2);line-height:1.65;margin-bottom:7px}
.prose li::marker{color:var(--accent)}
/* ---------- FAQ: disclosure rows ----------
   Filled rounded rows with the question on the left and a plus on the right.
   Native <details>, so it is keyboard operable with no JavaScript and every
   answer stays in the DOM while closed - find-in-page still reaches it, and the
   FAQPage JSON-LD is built from the same pair in content/topics.json, so the
   two cannot drift.
   The fill is --accent-soft rather than --card on purpose: the .topic-cta card
   directly below is --card, and the two must not read as one component twice. */
.faq{display:flex;flex-direction:column;gap:10px;margin:8px 0 0}
.faq details{
  background:var(--accent-soft);
  border:1px solid transparent;border-radius:var(--r-chip);
  transition:border-color .2s var(--ease),background-color .2s var(--ease);
}
.faq details:hover{border-color:var(--accent-edge)}
.faq details[open]{border-color:var(--accent-edge)}

.faq summary{
  position:relative;cursor:pointer;
  padding:15px 56px 15px 20px;
  font-size:.98rem;font-weight:560;color:var(--ink);line-height:1.45;
  list-style:none;                       /* Firefox */
}
.faq summary::-webkit-details-marker{display:none}   /* Safari */
.faq summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;
  border-radius:var(--r-chip)}

/* Two identical bars at one point. The second is turned 90deg to draw the plus;
   opening turns it back so it lies over the first and reads as a minus. */
.faq summary::before,
.faq summary::after{
  content:"";position:absolute;right:20px;top:50%;
  width:13px;height:1.6px;margin-top:-.8px;
  background:var(--accent);border-radius:2px;
}
.faq summary::after{transform:rotate(90deg);transition:transform .25s var(--ease)}
.faq details[open] summary::after{transform:rotate(0deg)}

/* the answer. Scoped tightly so it does not inherit .prose p spacing. */
.faq details > p{
  margin:0;padding:0 56px 17px 20px;
  color:var(--ink-2);line-height:1.7;text-wrap:pretty;
}
@media (prefers-reduced-motion:no-preference){
  .faq details[open] > p{animation:faqIn .26s var(--ease) both}
  @keyframes faqIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
}
@media (max-width:560px){
  .faq summary{padding:14px 46px 14px 16px;font-size:.94rem}
  .faq summary::before,.faq summary::after{right:16px}
  .faq details > p{padding:0 20px 15px 16px}
}
@media (prefers-reduced-motion:reduce){
  .faq details,.faq summary::after{transition:none}
}
/* the one call to action */
.topic-cta{margin-top:clamp(34px,3.8vw,52px);padding:clamp(24px,2.6vw,34px);
  border:1px solid var(--line);border-radius:var(--r-media);background:var(--card);
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:18px}
.topic-cta p{color:var(--ink-2);margin:0;max-width:52ch}

/* Platform carries a tile and two columns again, now that each read has a page. */
.nd-grid.trio{grid-template-columns:250px repeat(2,minmax(0,1fr))}

/* ---------- hero: one field, one button ----------
   A pill that holds the input and the button as one object, so it reads as a
   single control rather than two. The button keeps the same radius as the shell
   minus its inset, which is what stops a rounded button in a rounded well
   looking like two unrelated curves. */
/* Visually hidden but still announced. The placeholder is not a label, so the
   hero field keeps a real one for anyone using a screen reader. NOT .hp, which
   is the honeypot and is hidden from assistive technology on purpose. */
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.herocta{margin-top:clamp(26px,3vw,36px);max-width:452px}
.herocta-row{
  display:flex;align-items:center;gap:6px;
  padding:6px;border-radius:999px;
  /* a white wash, not a white box - enough to separate the field from the night
     sky behind it while the light placeholder and typed text stay legible */
  background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.24);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  transition:border-color .2s var(--ease),background-color .2s var(--ease);
}
/* The field takes no focus styling: no outline, no fill shift, nothing. A
   keyboard-only ring is not possible here - a text input always matches
   :focus-visible however focus arrived, so it fires on a mouse click too. The
   caret is the only arrival cue, which is what was asked for. */
.herocta input{
  flex:1 1 auto;min-width:0;
  background:none;border:0;outline:none;
  padding:11px 8px 11px 18px;
  font:inherit;font-size:.97rem;color:var(--deep-ink);
}
.herocta input::placeholder{color:rgba(233,239,252,.72)}
.herocta input:-webkit-autofill{-webkit-text-fill-color:var(--deep-ink);
  -webkit-box-shadow:0 0 0 40px #101a3c inset}
.herocta-btn{flex:none;border-radius:999px;padding:11px 22px;font-size:.95rem}
.herocta .fe{margin:9px 0 0 20px;color:#ffb4a8;font-size:.85rem;min-height:0}
.herocta input[aria-invalid="true"]{color:#ffd7d0}
@media (max-width:520px){
  .herocta{max-width:none}
  .herocta-row{flex-wrap:wrap;border-radius:var(--r-panel);padding:8px}
  .herocta input{flex:1 1 100%;padding:10px 14px}
  .herocta-btn{flex:1 1 100%;justify-content:center}
}

/* ---------- the request dialog ----------
   The same form module as /demo, in a modal. Native <dialog>, so focus is
   trapped and Escape closes it without a line of script. */
.ddlg{
  border:0;padding:0;background:none;
  width:min(560px,calc(100vw - 32px));max-height:calc(100vh - 48px);
  color:var(--ink);
}
.ddlg::backdrop{background:rgba(6,10,28,.62);backdrop-filter:blur(3px)}
.ddlg-in{
  position:relative;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-media);
  padding:clamp(26px,3.4vw,40px);
  box-shadow:0 40px 90px -34px rgba(4,10,34,.55);
  max-height:calc(100vh - 48px);overflow:auto;
}
.ddlg-h{margin:8px 0 0;font-size:clamp(1.4rem,1.1rem + 1.1vw,1.85rem);
  letter-spacing:-.02em;font-weight:560}
.ddlg .demoform{margin-top:22px}
.ddlg-x{
  position:absolute;top:14px;right:14px;
  display:grid;place-items:center;width:34px;height:34px;
  border:1px solid var(--line);border-radius:50%;
  background:var(--paper);color:var(--ink-2);cursor:pointer;
  transition:background-color .18s var(--ease),color .18s var(--ease);
}
.ddlg-x:hover{background:var(--paper-2);color:var(--ink)}
.ddlg-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.ddlg-x .ico{font-size:15px}
@media (prefers-reduced-motion:no-preference){
  .ddlg[open]{animation:ddlgIn .22s var(--ease) both}
  @keyframes ddlgIn{from{opacity:0;transform:translateY(8px) scale(.99)}to{opacity:1;transform:none}}
}

/* ---------- the LinkedIn mark ----------
   A small round white button, which is the one bright object in the footer bar
   and therefore reads as the thing to press. */
.social{
  display:grid;place-items:center;width:32px;height:32px;flex:none;
  border-radius:9px;
  background:#e2e4e9;border:1px solid #eef0f3;
  transition:background-color .18s var(--ease),border-color .18s var(--ease),
             color .18s var(--ease),transform .18s var(--ease);
}
/* .fbot a sets the footer link colour at (0,1,1) and out-specifies a bare
   .social at (0,1,0), so the glyph colour has to be stated at least as high or
   the mark inherits the muted link tone and disappears into its own chip. */
.fbot a.social{color:#20242f}
.fbot a.social:hover{color:#0b1230}
.social:hover{background:#f4f5f7;border-color:#fff;transform:translateY(-1px)}
.social:focus-visible{outline:2px solid var(--accent-bright);outline-offset:3px}
.social .ico{font-size:17px}

/* The dialog has to fit the screen without scrolling, so the four short fields
   sit two-up and the comment box spans both columns. Measured: 891px of content
   became 660px, which clears a 720px viewport with room over. */
.ddlg .demoform{display:grid;grid-template-columns:1fr 1fr;gap:0 16px;padding:clamp(20px,2.2vw,28px)}
.ddlg .ff{margin-bottom:12px}
.ddlg .ff-wide,
.ddlg .demobtn,
.ddlg .dform-note,
.ddlg .dform-msg{grid-column:1 / -1}
.ddlg .ff textarea{min-height:64px}
.ddlg .ddlg-h{margin-top:6px}
.ddlg .demobtn{margin-top:4px}
/* one column when there is not width for two, and tighter with it: five stacked
   fields need the space back that two columns were saving */
@media (max-width:560px){
  .ddlg .demoform{grid-template-columns:1fr;padding:18px}
  .ddlg-in{padding:22px 18px}
  .ddlg .ff{margin-bottom:9px}
  .ddlg .ff label{margin-bottom:5px}
  .ddlg .ff input,.ddlg .ff textarea{padding:9px 12px}
  .ddlg .ff textarea{min-height:56px}
  .ddlg-h{font-size:1.3rem}
  .ddlg .dform-note{font-size:.82rem}
}
