/* Inter, self-hosted. An @import here blocked first paint on a third-party
   round trip and handed every visitor's IP to Google; these are the same
   Google Fonts woff2 builds, served from our own origin. SIL OFL 1.1 -
   see assets/fonts/LICENSE-Inter.txt */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url("../fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================
   QUANTUMOO — design tokens
   Palette derived from the Quantumoo Introduction deck theme:
   dk1 #15171A · lt1 #FBFBFA · accent1 #2B4C7E · accent2 #7896C8
   accent3 #141E32 · orange #F0803C · tints #EEF2F7 / #E3E7EC
   ============================================================ */

:root {
  /* motion — expo / quart / spring easing set */
  --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
  --ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-fast: 0.24s;
  --dur: 0.6s;
  --dur-slow: 0.9s;

  /* geometry */
  /* two tiers: prose is measure-constrained, chrome runs wider and edge-aware */
  --w-content: 1320px;
  --shell-bleed: 280px;
  --w-shell: calc(var(--w-content) + var(--shell-bleed) * 2);
  --gutter: clamp(20px, 4vw, 64px);
  --gutter-shell: clamp(20px, 2.6vw, 46px);
  --maxw: var(--w-content);          /* alias — every existing .wrap keeps working */
  /* How far it is from the content column's edge out to the viewport edge, so
     a panel can bleed off the page without hard-coding a width. 100vw counts
     the scrollbar and the layout does not, so JS feeds the real width in;
     without JS it stays 0 and the plate is simply clipped at the edge, which
     is the same picture. */
  --sbw: 0px;
  --vw: calc(100vw - var(--sbw));
  /* gap either side of the wrap's BORDER box; the stage sits one gutter
     further in, so a bleed pulls --edge plus --gutter */
  --edge: calc((var(--vw) - min(var(--vw), var(--w-content))) / 2);
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-pill: 999px;
  --section-y: clamp(54px, 6.4vw, 100px);

  /* brand constants (theme-independent) */
  --brand: #7896c8;             /* deck accent2; accent1 is 2.2:1 on this ground */
  --on-brand: #15171a;          /* label colour on a brand fill */
  --navy: #2b4c7e;
  --sky: #7896c8;
  --ok: #2e7d4f;
  --warn: #d99a00;
  --bad: #c62828;

  /* phone screenshots: the device screen's own corner radius, measured from
     the source mockups corner radius fitted against the residual dark edge in the
     exported files (66px on 620px wide), plus a 3px margin so no antialiased
     fringe survives. Percentages, so it holds at any rendered size. */
  --phone-radius: 11.1% / 5.4%;

  --font: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Consolas, monospace;
}

/* ---------- dark (default) ---------- */
:root,
[data-theme="dark"] {
  --bg: #0e1014;
  --bg-2: #14171d;
  --surface: #171b22;
  --surface-2: #1d222b;
  --line: #262c36;
  --line-2: #333a46;
  --head: #ffffff;
  --body: #a7afbc;
  --dim: #828a96;              /* WCAG AA: 4.58:1 on --surface-2, the lightest dark ground */
  --brand-text: var(--brand);  /* 6.34:1 on --bg, passes as text unchanged */
  --btn-bg: #ffffff;
  --btn-fg: #0e1014;
  --link: var(--sky);
  --glow-a: rgba(43, 76, 126, 0.55);
  --glow-b: rgba(240, 128, 60, 0.28);   /* atmosphere, not accent - the warm
                                           counterpoint is what gives the field depth */
  --glow-c: rgba(120, 150, 200, 0.3);
  --shadow-lg: 0 30px 70px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 14px 40px rgba(0, 0, 0, 0.4);
  --grain-opacity: 0.055;
  --scheme: dark;
}

/* ---------- light ---------- */
[data-theme="light"] {
  --bg: #fbfbfa;
  --bg-2: #f4f5f7;
  --surface: #ffffff;
  --surface-2: #f1f4f8;
  --line: #e3e7ec;
  --line-2: #d3dae3;
  --head: #15171a;
  --body: #4a5058;
  --dim: #6a6f78;              /* WCAG AA: 4.58:1 on --surface-2, the darkest light ground */
  --brand: #2b4c7e;             /* deck accent1 */
  --on-brand: #ffffff;          /* label colour on a brand fill */
  --brand-text: var(--brand);  /* 8.32:1 on --bg; the navy needs no separate text tint */
  --btn-bg: #15171a;
  --btn-fg: #ffffff;
  --link: var(--navy);
  --glow-a: rgba(120, 150, 200, 0.42);
  --glow-b: rgba(240, 128, 60, 0.22);   /* see the dark block */
  --glow-c: rgba(43, 76, 126, 0.16);
  --shadow-lg: 0 30px 70px rgba(20, 30, 50, 0.14);
  --shadow-md: 0 14px 40px rgba(20, 30, 50, 0.1);
  --grain-opacity: 0.03;
  --scheme: light;
}

/* ============================================================
   base
   ============================================================ */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  position: relative;
  margin: 0;
  font-family: var(--font);
  font-optical-sizing: auto;
  background: var(--bg);
  color: var(--body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background var(--dur-fast) linear, color var(--dur-fast) linear;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }
ul { padding: 0; list-style: none; }

::selection { background: var(--brand); color: var(--on-brand); }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  border-radius: 4px;
}

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* chrome container — wider than the prose measure, and edge-aware */
.shell {
  width: 100%;
  max-width: var(--w-shell);
  margin-inline: auto;
  padding-inline: var(--gutter-shell);
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================
   type scale — fluid
   ============================================================ */

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--dim);
  display: inline-flex;
  align-items: center;
  gap: 9px;
}
.eyebrow::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 2px;
  background: var(--brand);
  flex: none;
}
.eyebrow.plain::before { display: none; }

.h1 {
  font-size: clamp(36px, 4.7vw, 66px);
  line-height: 1.06;
  letter-spacing: -0.035em;
  font-weight: 600;
  color: var(--head);
  text-wrap: balance;
}
.h2 {
  font-size: clamp(30px, 3.9vw, 52px);
  line-height: 1.08;
  letter-spacing: -0.028em;
  font-weight: 600;
  color: var(--head);
  text-wrap: balance;
}
.h3 {
  font-size: clamp(20px, 2vw, 26px);
  line-height: 1.25;
  letter-spacing: -0.02em;
  font-weight: 600;
  color: var(--head);
}
.lede {
  font-size: clamp(16px, 1.35vw, 19px);
  line-height: 1.62;
  color: var(--body);
}
.small { font-size: 14px; line-height: 1.6; color: var(--body); }
.tiny { font-size: 12.5px; line-height: 1.55; color: var(--dim); }
.mono { font-family: var(--mono); }

/* ============================================================
   buttons — dual-label vertical slide
   ============================================================ */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  padding-inline: 28px;
  border-radius: var(--r-pill);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  overflow: clip;
  isolation: isolate;
  transition: background var(--dur-fast) linear, color var(--dur-fast) linear,
              border-color var(--dur-fast) linear, transform var(--dur-fast) var(--ease-out-expo);
}
.btn:active { transform: scale(0.975); }

.btn .lbl { display: grid; overflow: clip; }
.btn .lbl span {
  text-align: center;
  grid-area: 1 / 1;
  transition: transform 0.7s var(--ease-spring), opacity 0.7s var(--ease-spring);
}
.btn .lbl span:nth-child(2) { transform: translateY(110%); opacity: 0; }
@media (hover: hover) {
  .btn:hover .lbl span:nth-child(1) { transform: translateY(-110%); opacity: 0; }
  .btn:hover .lbl span:nth-child(2) { transform: translateY(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .btn .lbl span:nth-child(2) { display: none; }
}

.btn-primary { background: var(--btn-bg); color: var(--btn-fg); }
.btn-primary:hover { background: var(--brand); color: var(--on-brand); }

.btn-ghost { border: 1px solid var(--line-2); color: var(--head); }
.btn-ghost:hover { border-color: var(--head); background: color-mix(in srgb, var(--head) 7%, transparent); }

.btn-sm { height: 38px; padding-inline: 18px; font-size: 14px; }

/* ============================================================
   grain + glow atmosphere
   ============================================================ */

.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
[data-theme="dark"] .grain { mix-blend-mode: soft-light; }
[data-theme="light"] .grain { mix-blend-mode: multiply; }

/* animated gradient mesh */
.mesh {
  /* Lives outside the hero now. The hero clips its overflow, so keeping the
     glow inside meant it stopped dead on the section boundary; spanning both
     lets the hero and the top of the products section read as one lit field. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: clamp(1000px, 132vh, 1600px);
  z-index: -1;
  pointer-events: none;
  /* the blobs are wider than the viewport by design; clip them here rather
     than letting the document grow sideways */
  overflow: hidden;
  filter: blur(70px);
  opacity: 0.9;
  mask-image: linear-gradient(to bottom, #000 46%, rgba(0,0,0,0.5) 76%, transparent 97%);
  -webkit-mask-image: linear-gradient(to bottom, #000 46%, rgba(0,0,0,0.5) 76%, transparent 97%);
}
.mesh i {
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
}
.mesh i:nth-child(1) {
  width: 48vw; height: 48vw; left: 4%; top: 2%;
  background: var(--glow-a);
  animation: drift1 22s var(--ease-in-out-quart) infinite alternate;
}
.mesh i:nth-child(2) {
  width: 36vw; height: 36vw; right: 6%; top: 14%;
  background: var(--glow-b);
  animation: drift2 27s var(--ease-in-out-quart) infinite alternate;
}
.mesh i:nth-child(3) {
  width: 40vw; height: 40vw; left: 32%; bottom: -8%;
  background: var(--glow-c);
  animation: drift3 31s var(--ease-in-out-quart) infinite alternate;
}
@keyframes drift1 { to { transform: translate3d(14%, 10%, 0) scale(1.18); } }
@keyframes drift2 { to { transform: translate3d(-16%, 14%, 0) scale(0.86); } }
@keyframes drift3 { to { transform: translate3d(10%, -14%, 0) scale(1.12); } }
@media (prefers-reduced-motion: reduce) {
  .mesh i:nth-child(1), .mesh i:nth-child(2), .mesh i:nth-child(3) { animation: none; }
}

/* ============================================================
   header
   ============================================================ */

.hdr {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 90;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  transition: background var(--dur-fast) linear, border-color var(--dur-fast) linear,
              backdrop-filter var(--dur-fast) linear;
  border-bottom: 1px solid transparent;
}
.hdr.stuck {
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  border-bottom-color: var(--line);
}
.hdr-in { display: flex; align-items: center; height: var(--nav-h); }

.brand { display: flex; align-items: center; gap: 10px; flex: none;
  margin-right: clamp(22px, 2.6vw, 44px); }
.brand svg { width: 25px; height: 25px; }
.brand svg path { fill: var(--head); transition: fill var(--dur-fast) linear; }
.brand b {
  font-size: 18px; font-weight: 600; letter-spacing: 0.015em; color: var(--head);
}

.nav { --nav-pad-x: 13px; display: flex; align-items: center; gap: 6px; margin-right: auto; }
.nav a {
  position: relative;
  padding: 8px var(--nav-pad-x);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--body);
  border-radius: var(--r-sm);
  transition: color var(--dur-fast) linear;
}
.nav a::after {
  content: "";
  position: absolute;
  left: var(--nav-pad-x); right: var(--nav-pad-x); bottom: 3px;
  height: 1.5px;
  background: var(--brand);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.42s var(--ease-out-expo);
}
.nav a:hover { color: var(--head); }
.nav a:hover::after { transform: scaleX(1); }

.hdr-tools { display: flex; align-items: center; gap: 14px; flex: none;
  margin-left: clamp(20px, 2vw, 36px); }
/* .btn goes full-width at <=560px; the header pill must never inherit that */
.hdr-tools .btn { width: auto; }

.theme-toggle {
  width: 38px; height: 38px;
  margin-right: 6px;
  display: grid; place-items: center;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  color: var(--head);
  transition: border-color var(--dur-fast) linear, transform var(--dur-fast) var(--ease-spring);
}
.theme-toggle:hover { border-color: var(--head); transform: rotate(-18deg); }
.theme-toggle .sun { display: none; }
[data-theme="light"] .theme-toggle .sun { display: block; }
[data-theme="light"] .theme-toggle .moon { display: none; }

.burger { display: none; width: 38px; height: 38px; margin-left: 2px; place-items: center; color: var(--head); }

/* ============================================================
   hero
   ============================================================ */

.hero {
  position: relative;
  min-height: min(84vh, 780px);
  display: flex;
  align-items: center;
  padding-top: calc(var(--top-h, 64px) + 48px);
  padding-bottom: 24px;
}
.hero .wrap { position: relative; z-index: 2; }

.hero-grid {
  display: grid;
  grid-template-columns: 1.14fr 0.86fr;
  gap: clamp(28px, 4vw, 60px);
  align-items: center;
}

.hero-copy { display: flex; flex-direction: column; gap: 26px; align-items: flex-start; }
.hero-copy .lede { max-width: 50ch; }
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px 8px 12px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--head) 6%, transparent);
  border: 1px solid var(--line);
  backdrop-filter: blur(10px);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--head);
  transition: background var(--dur-fast) linear;
}
.chip:hover { background: color-mix(in srgb, var(--head) 11%, transparent); }
.chip i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
  box-shadow: 0 0 0 0 var(--brand);
  animation: pulse 2.6s var(--ease-out-expo) infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand) 70%, transparent); }
  70% { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.chip .div { width: 1px; height: 12px; background: var(--line-2); }
.chip .sub { color: var(--dim); }

/* headline word reveal */
.reveal-line { display: block; overflow: clip; }
.js .reveal-line > span {
  display: block;
  transform: translateY(105%);
  transition: transform 1s var(--ease-out-expo);
}
.js .hero.in .reveal-line > span { transform: translateY(0); }
.hero.in .reveal-line:nth-child(2) > span { transition-delay: 0.09s; }
.hero.in .reveal-line:nth-child(3) > span { transition-delay: 0.18s; }
.hero.in .reveal-line:nth-child(4) > span { transition-delay: 0.27s; }
@media (prefers-reduced-motion: reduce) {
  .reveal-line > span { transform: none; }
}

/* hero visual stack */
.hero-visual {
  position: relative;
  perspective: 1400px;
}
.hero-shot {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--line-2);
  box-shadow: var(--shadow-lg);
  transform: rotateY(-7deg) rotateX(3deg) translateZ(0);
  transform-style: preserve-3d;
  transition: transform 0.9s var(--ease-out-expo);
}
.hero-visual:hover .hero-shot { transform: rotateY(-3deg) rotateX(1deg); }
.hero-float {
  position: absolute;
  left: -6%;
  bottom: -9%;
  width: 30%;
  border-radius: var(--phone-radius);
  overflow: hidden;
  border: 0;
  box-shadow: var(--shadow-lg);
  animation: bob 7s var(--ease-in-out-quart) infinite alternate;
}
@keyframes bob { to { transform: translateY(-16px); } }
@media (prefers-reduced-motion: reduce) { .hero-float { animation: none; } }

/* ============================================================
   sections + scroll reveal
   ============================================================ */

[id] { scroll-margin-top: calc(var(--top-h, 64px) + 26px); }
.sec { padding-block: var(--section-y); position: relative; }
.sec-head { display: flex; flex-direction: column; gap: 18px; max-width: 760px; }
.sec-head.center { align-items: center; text-align: center; margin-inline: auto; }

/* hidden only when JS is confirmed running — without it the page renders in full */
.js .rv { opacity: 0; transform: translateY(26px); }
.js .rv.in {
  opacity: 1;
  transform: none;
  transition: opacity 0.8s var(--ease-out-expo), transform 0.8s var(--ease-out-expo);
}
.js .rv.d1.in { transition-delay: 0.07s; }
.js .rv.d2.in { transition-delay: 0.14s; }
.js .rv.d3.in { transition-delay: 0.21s; }
.js .rv.d4.in { transition-delay: 0.28s; }
@media (prefers-reduced-motion: reduce) {
  .js .rv { opacity: 1; transform: none; }
}

/* ============================================================
   product card band — compact, icon-led
   ============================================================ */

.band {
  display: grid;
  /* auto-fill, not auto-fit: empty tracks are kept, so a partial final row
     leaves cards at their normal width rather than stretching one to fill.
     Adding a product is a markup change only — no CSS to touch. */
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 14px;
  margin-top: 44px;
}
.band a {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 22px 20px 24px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.45s var(--ease-out-expo), border-color 0.3s linear;
}
.band a::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(120% 90% at 50% 118%, var(--glow-a), transparent 62%);
  opacity: 0;
  transition: opacity 0.45s var(--ease-out-expo);
}
.band a:hover { transform: translateY(-6px); border-color: var(--line-2); }
.band a:hover::before { opacity: 1; }
.band .ico {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border-radius: 10px;
  background: color-mix(in srgb, var(--brand) 13%, transparent);
  color: var(--brand);
  margin-bottom: 2px;
}
.band .ico svg { width: 19px; height: 19px; }
.band .cat {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--brand); font-weight: 500;
}
.band .row { display: flex; align-items: baseline; gap: 9px; margin-top: -2px; }
.band .n { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; color: var(--dim); }
.band .t { font-size: 17px; font-weight: 600; color: var(--head); letter-spacing: -0.012em; }
.band .d { font-size: 12.5px; color: var(--dim); line-height: 1.45; }

/* ============================================================
   feature blocks — alternating, with stage panel
   ============================================================ */

/* the screenshot earns the wider column; .flip swaps the ratio too, or the
   image would land in the narrow track on alternating rows */
.feat { display: grid; grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
  gap: clamp(28px, 4.5vw, 72px); align-items: center; }
.feat.flip { grid-template-columns: minmax(0, 1.28fr) minmax(0, 0.72fr); }
.feat-first { margin-top: clamp(44px, 5vw, 72px); }
.feat + .feat { margin-top: clamp(52px, 5.5vw, 88px); }
.feat.flip .feat-copy { order: 2; }
.feat-copy { display: flex; flex-direction: column; gap: 20px; align-items: flex-start; }
.feat-copy .lede { max-width: 46ch; }

.feat-points { display: flex; flex-direction: column; gap: 14px; margin-top: 2px; }
.feat-points li { display: flex; gap: 13px; align-items: flex-start; }
.feat-points svg { flex: none; margin-top: 3px; color: var(--brand); }
.feat-points b { color: var(--head); font-weight: 600; }
.feat-points span { font-size: 15px; line-height: 1.58; }

.stage {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.stage img {
  width: 100%;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
}

/* caption sits below the screenshot — it never covers the thing it describes */
.stage-cap {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-left: 15px;
  border-left: 2px solid var(--brand);
}
.stage-cap b { color: var(--head); font-size: 15px; font-weight: 600; line-height: 1.35; }
.stage-cap span { font-size: 13.5px; color: var(--dim); line-height: 1.5; }
.js .stage .stage-cap { opacity: 0; transform: translateY(8px); }
.js .stage.in .stage-cap {
  opacity: 1; transform: none;
  transition: opacity 0.6s var(--ease-out-expo) 0.15s, transform 0.6s var(--ease-out-expo) 0.15s;
}

/* portrait screenshots: a phone shot is never stretched to panel width */
.stage.tall { align-items: center; }
.stage.tall img {
  width: var(--phone-w); max-width: var(--phone-w);
  border-radius: var(--phone-radius);
  border: 0;
}
/* The phone is centred, so a full-width caption starts well left of it. Both
   now read one width, or they drift apart the moment either cap changes: the
   image was height-capped to 600px and rendering 291px wide, while the caption
   was using the 330px width cap. */
.stage.tall { --phone-w: min(300px, 74%); }
.stage.tall .stage-cap { align-self: center; width: var(--phone-w); }
.wide-stage .stage.tall { padding-block: clamp(34px, 4.4vw, 60px); }
.wide-stage .stage.tall img { max-width: min(300px, 30%); }

/* A portrait phone in a half-width feature panel is far taller than the text
   beside it. Its width is the single constraint now -- capping the height
   instead is what let the image and its caption end up different widths. */
.feat .stage.tall { --phone-w: min(300px, 100%); }
.feat .stage.tall img { height: auto; }

/* stacked module sections: closer than a full section gap, but not touching */
.sec.stack { padding-top: clamp(36px, 4.5vw, 64px); }

/* ============================================================
   stats — count up
   ============================================================ */

.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.stat {
  padding: 30px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
  overflow: hidden;
  transition: transform 0.45s var(--ease-out-expo), border-color 0.3s linear,
              background 0.3s linear;
}
.stat:hover { transform: translateY(-5px); border-color: var(--line-2); background: var(--surface-2); }
.stat::after {
  content: "";
  position: absolute; left: 0; top: 0; height: 2px; width: 100%;
  background: linear-gradient(90deg, var(--brand), transparent);
  transform: scaleX(0); transform-origin: left;
  transition: transform 1s var(--ease-out-expo);
}
.stat.in::after { transform: scaleX(1); }
.stat .v {
  font-size: clamp(30px, 3.4vw, 44px);
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--head);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat .l { font-size: 13.5px; line-height: 1.5; color: var(--body); }

/* ============================================================
   industries — tabs
   ============================================================ */

.tabs { display: flex; gap: 10px; justify-content: center; margin: 36px 0 40px; flex-wrap: wrap; }
.tab {
  padding: 11px 24px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--body);
  transition: all var(--dur-fast) linear;
}
.tab:hover { color: var(--head); border-color: var(--line-2); }
.tab[aria-selected="true"] { background: var(--btn-bg); color: var(--btn-fg); border-color: var(--btn-bg); }

.panel { display: none; }
.panel.on { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 4vw, 60px); align-items: center; animation: fade 0.55s var(--ease-out-expo); }
@keyframes fade { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.panel .metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.panel .metric {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 24px;
  display: flex; flex-direction: column; gap: 6px;
  transition: transform 0.45s var(--ease-out-expo), border-color 0.3s linear;
}
.panel .metric:hover { transform: translateY(-4px); border-color: var(--line-2); }
.panel .metric b { font-size: 28px; font-weight: 600; letter-spacing: -0.028em; color: var(--head); line-height: 1; }
.panel .metric span { font-size: 12.5px; color: var(--dim); line-height: 1.45; }

/* ============================================================
   case cards
   ============================================================ */

.cases { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 48px; }
.case {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 34px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  isolation: isolate;
  transition: transform 0.5s var(--ease-out-expo), border-color 0.3s linear;
}
.case::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(80% 60% at 100% 0%, var(--glow-a), transparent 60%);
  opacity: 0; transition: opacity 0.5s var(--ease-out-expo);
}
.case:hover { transform: translateY(-6px); border-color: var(--line-2); }
.case:hover::before { opacity: 1; }
.case.feature { grid-column: 1 / -1; border-color: var(--line-2); }
.case.feature::before { opacity: 0.7; }
.case .tag { margin-bottom: 16px; }
.case h3 { max-width: 52ch; }
.case p { margin-top: 14px; font-size: 15px; line-height: 1.62; color: var(--body); max-width: 68ch; }
.case .kpis { display: flex; gap: 34px; margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--line); }
.case .kpis div { display: flex; flex-direction: column; gap: 4px; }
.case .kpis b { font-size: 23px; font-weight: 600; letter-spacing: -0.026em; color: var(--head); }
.case .kpis span { font-size: 12px; color: var(--dim); }
.case .go {
  position: absolute; top: 30px; right: 30px;
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--btn-fg); background: var(--btn-bg);
  padding: 7px 13px; border-radius: var(--r-pill);
  transition: gap var(--dur-fast) var(--ease-out-expo);
}
.case:hover .go { gap: 12px; }

/* ============================================================
   CTA + footer
   ============================================================ */

.cta-box {
  position: relative;
  border-radius: var(--r-lg);
  padding: clamp(44px, 6vw, 90px) clamp(24px, 4vw, 64px);
  text-align: center;
  overflow: hidden;
  isolation: isolate;
  background: var(--surface-2);
  border: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center; gap: 22px;
}
.cta-box::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(70% 120% at 50% 0%, var(--glow-a), transparent 65%);
}
.cta-box .lede { max-width: 56ch; }
.cta-box a.mono { transition: color var(--dur-fast) linear; }
.cta-box a.mono:hover { color: var(--head) !important; }

.ftr { border-top: 1px solid var(--line); padding-block: 54px 40px; }
.ftr-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 44px; }
.ftr h4 {
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--dim); font-weight: 500; margin-bottom: 14px;
}
.ftr li + li { margin-top: 10px; }
.ftr li a { font-size: 14px; color: var(--body); transition: color var(--dur-fast) linear; }
.ftr li a:hover { color: var(--head); }
.ftr-bottom {
  display: flex; justify-content: space-between; align-items: center; gap: 20px;
  margin-top: 46px; padding-top: 24px; border-top: 1px solid var(--line); flex-wrap: wrap;
}

/* ============================================================
   CoCare page specifics
   ============================================================ */

.hero-cocare { min-height: auto; padding-top: calc(var(--top-h, 64px) + 62px); text-align: center; }
.hero-cocare .hero-copy { align-items: center; text-align: center; }
.hero-cocare .lede { max-width: 62ch; }

.wide-stage { margin-top: clamp(34px, 5vw, 60px); }
.wide-stage .stage { padding: clamp(24px, 3.4vw, 54px); }

.play {
  position: absolute; left: 50%; top: calc(50% - 30px);
  width: 78px; height: 78px; border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, 0.95);
  color: #0e1014;
  transform: translate(-50%, -50%);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.35);
  transition: transform 0.4s var(--ease-spring), background var(--dur-fast) linear;
}
.play:hover { transform: translate(-50%, -50%) scale(1.09); background: #fff; }
.play::after {
  content: ""; position: absolute; inset: -10px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.45);
  animation: halo 2.6s var(--ease-out-expo) infinite;
}
@keyframes halo {
  0% { transform: scale(0.94); opacity: 0.9; }
  100% { transform: scale(1.22); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .play::after { animation: none; } }

/* aria chat card */
.aria-card {
  position: absolute; left: 4%; top: 50%; transform: translateY(-50%);
  width: 58%; max-width: 280px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 17px;
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; gap: 11px;
  animation: bob 8s var(--ease-in-out-quart) infinite alternate;
}
.aria-card .bub {
  background: var(--surface-2); border-radius: 10px; padding: 10px 12px;
  font-size: 11.5px; line-height: 1.5;
}
.aria-card .tri {
  border: 1px solid color-mix(in srgb, var(--brand) 40%, transparent);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  border-radius: 10px; padding: 10px 12px;
}
.aria-card .tri b { display: block; font-size: 11.5px; color: var(--head); }
.aria-card .tri span { font-size: 10.5px; color: var(--dim); }
@media (prefers-reduced-motion: reduce) { .panel.on, .aria-card { animation: none; } }

/* timeline */
.timeline { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; margin-top: 46px; }
.timeline li { padding-right: 22px; position: relative; }
.timeline .dot-row { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.timeline .dot { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.timeline .bar { flex: 1; height: 1px; background: var(--line-2); }
.timeline .t { font-family: var(--mono); font-size: 15px; font-weight: 600; color: var(--head); display: block; }
.timeline .w { font-size: 13.5px; line-height: 1.55; color: var(--dim); margin-top: 6px; display: block; }

/* faq */
.faq { max-width: 920px; margin-inline: auto; margin-top: 44px; }
.faq details { border-top: 1px solid var(--line); }
.faq details:last-of-type { border-bottom: 1px solid var(--line); }
.faq summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 24px 0;
  font-size: 18px; font-weight: 500; color: var(--head); line-height: 1.4;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary svg { flex: none; color: var(--dim); transition: transform 0.4s var(--ease-out-expo); }
.faq details[open] summary svg { transform: rotate(180deg); }
.faq .a { padding-bottom: 26px; font-size: 15.5px; line-height: 1.7; color: var(--body); max-width: 78ch; }

/* guard grid */
.guards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 46px; }
.guard {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 26px;
  display: flex; flex-direction: column; gap: 9px;
  transition: transform 0.45s var(--ease-out-expo), border-color 0.3s linear;
}
.guard:hover { transform: translateY(-5px); border-color: var(--line-2); }
.guard b { font-size: 16px; font-weight: 600; color: var(--head); line-height: 1.35; }
.guard span { font-size: 14px; line-height: 1.58; color: var(--body); }

/* ============================================================
   responsive
   ============================================================ */

@media (max-width: 1080px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .guards { grid-template-columns: repeat(2, 1fr); }
  .layer { grid-template-columns: 40px 1fr; }
  .layer .wh { grid-column: 2; }
  .timeline { grid-template-columns: repeat(2, 1fr); row-gap: 28px; }
}

@media (max-width: 1180px) {

}

@media (max-width: 860px) {
  .nav { display: none; }
  .burger { display: grid; }
  .hero { min-height: auto; padding-top: calc(var(--top-h, 64px) + 34px); }
  .hero-visual { margin-top: 12px; }
  .hero-shot { transform: none; }
  .case.feature { grid-column: auto; }
  .subnav .wrap { gap: 18px; overflow-x: auto; }
  .ftr-grid { gap: 32px; }
}

@media (max-width: 560px) {
  .stats { grid-template-columns: 1fr 1fr; }
  /* two ~150px prose columns is unreadable; numbers survive it, sentences do not */
  .guards, .panel .metrics { grid-template-columns: 1fr; }
  .timeline { grid-template-columns: 1fr; }
  .case .kpis { gap: 22px; flex-wrap: wrap; }
  .btn { width: 100%; }
  .hero-cta { width: 100%; }
}

/* ============================================================
   depth sections — added detail, same air.
   The site is the fullest source; the deck is a subset of it.
   ============================================================ */

/* three-up principles */
.beliefs { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 3.4vw, 56px); margin-top: 56px; }
.belief { display: flex; flex-direction: column; gap: 14px; padding-top: 26px; border-top: 1px solid var(--line); }
.belief .no { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; color: var(--brand); }
.belief b { font-size: clamp(19px, 1.7vw, 23px); font-weight: 600; color: var(--head); line-height: 1.28; letter-spacing: -0.018em; }
.belief span { font-size: 15px; line-height: 1.62; color: var(--body); }

/* story — horizontal milestone rail */
.story { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-top: 56px; }
.milestone { display: flex; flex-direction: column; gap: 12px; }
.milestone .mark { display: flex; align-items: center; gap: 10px; }
.milestone .mark i { width: 9px; height: 9px; border-radius: 50%; background: var(--brand); flex: none; }
.milestone .mark hr { flex: 1; height: 1px; border: 0; background: var(--line-2); margin: 0; }
.milestone .k { font-family: var(--mono); font-size: 11px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--dim); }
.milestone b { font-size: 17px; font-weight: 600; color: var(--head); line-height: 1.35; letter-spacing: -0.012em; }
.milestone span { font-size: 14px; line-height: 1.6; color: var(--body); }

/* team */
/* the team, photography-led. The bios are in the DOM under each portrait and
   readable with JavaScript off; with it, they collapse and one opens at a time
   in a panel below the row, so the grid stays clean and the page stays short. */
.team {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  /* A portrait is never drawn wider than the smallest source photo (183px),
     so no face is scaled past the pixels behind it. At six columns the cap
     never binds — the column is already ~182px. It engages only in the three-
     and two-column layouts, which widen the column as the viewport narrows:
     at 1080px an uncapped column stretched the 183px portrait to 315px (0.58x)
     and the softness showed beside the 520px photos. Items align to the start
     of the column so the row stays flush with the section heading. */
  justify-items: start;
  gap: clamp(14px, 1.6vw, 26px);
  margin-top: clamp(40px, 4.5vw, 64px);
}
.person {
  margin: 0; padding: 0; text-align: left; background: none; border: 0;
  display: flex; flex-direction: column; gap: 12px;
  width: 100%; max-width: 183px;
  cursor: default;
}
.js .person { cursor: pointer; }
.person img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  object-position: center top;
  border-radius: var(--r-md);
  background: var(--surface);
  transition: transform 0.5s var(--ease-out-expo), box-shadow 0.5s var(--ease-out-expo),
              outline-color 0.3s linear;
  outline: 2px solid transparent;
  outline-offset: 3px;
}
.js .person:hover img { transform: translateY(-5px); box-shadow: 0 20px 40px rgba(20,30,50,0.16); }
[data-theme="dark"] .js .person:hover img { box-shadow: 0 20px 40px rgba(0,0,0,0.5); }
.person[aria-expanded="true"] img { outline-color: var(--brand); }
.pname { font-size: 15.5px; font-weight: 600; color: var(--head); letter-spacing: -0.012em; }
.person .role {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--dim); line-height: 1.4;
}
/* without JS this is simply the bio, set small under each portrait */
.bio { display: flex; flex-direction: column; gap: 8px; }
.bio-t { font-size: 13px; line-height: 1.55; color: var(--body); }
.bio-c { font-size: 11.5px; line-height: 1.5; color: var(--dim); }
.js .bio { display: none; }

.team-detail { display: none; }
.js .team-detail.open {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: clamp(20px, 3vw, 56px);
  margin-top: clamp(26px, 3vw, 44px);
  padding-top: clamp(24px, 2.6vw, 36px);
  border-top: 1px solid var(--line-2);
  animation: teamDetail 0.5s var(--ease-out-expo);
}
@keyframes teamDetail { from { opacity: 0; transform: translateY(8px); } }
.team-detail .d-name { font-size: clamp(20px, 2vw, 26px); font-weight: 600; color: var(--head); letter-spacing: -0.018em; }
.team-detail .d-role {
  display: block; margin-top: 6px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--brand-text);
}
.team-detail .d-bio { font-size: 15px; line-height: 1.65; color: var(--body); }
.team-detail .d-cred { display: block; margin-top: 12px; font-size: 12.5px; line-height: 1.55; color: var(--dim); }
@media (prefers-reduced-motion: reduce) {
  .person img { transition: none; }
  .js .team-detail.open { animation: none; }
}
@media (max-width: 720px) {
  .js .team-detail.open { grid-template-columns: 1fr; }
}

/* generous section — used where the page needs to breathe hardest */
.sec.airy { padding-block: clamp(96px, 13vw, 190px); }

@media (max-width: 1080px) {
  .beliefs { grid-template-columns: repeat(2, 1fr); }
  .team { grid-template-columns: repeat(3, 1fr); }
  .story { grid-template-columns: repeat(2, 1fr); row-gap: 34px; }
}
@media (max-width: 640px) {
  .beliefs, .story { grid-template-columns: 1fr; }
  .team { grid-template-columns: repeat(2, 1fr); }
}

/* video sitting in a stage panel, same treatment as a screenshot */
.stage video {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-lg);
  background: #05070b;
}
.stage.has-video { position: relative; }
.stage.has-video.playing .play { opacity: 0; pointer-events: none; }
.stage.has-video .play { transition: opacity 0.3s var(--ease-out-expo), transform 0.4s var(--ease-spring); }

/* ============================================================
   play table — DYNAMES: what runs, on what trigger, gated by whom
   ============================================================ */

.playtable {
  margin-top: 48px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--surface);
}
.playtable-head,
.playrow {
  display: grid;
  grid-template-columns: 1.15fr 0.8fr 1.2fr 1.05fr 1.25fr;
  gap: 24px;
  padding: 18px 26px;
  align-items: baseline;
}
.playtable-head {
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.playtable-head span {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  font-weight: 500;
}
.playrow { border-top: 1px solid var(--line); transition: background 0.3s linear; }
.playrow:first-of-type { border-top: 0; }
.playrow:hover { background: var(--surface-2); }
.playrow span { font-size: 14px; line-height: 1.55; color: var(--body); }
.playrow .pt-name { font-weight: 600; color: var(--head); }
.playrow .pt-sector {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}
.playrow .mono { font-size: 12.5px; color: var(--dim); }
.playrow .pt-gate {
  position: relative;
  padding-left: 18px;
  color: var(--head);
}
.playrow .pt-gate::before {
  content: "";
  position: absolute;
  left: 0; top: 7px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--brand);
}
/* a play with no gate is the exception, so it reads differently */
.playrow .pt-gate.pt-open { color: var(--dim); }
.playrow .pt-gate.pt-open::before { background: var(--ok); }

/* industry pack figures */
.packstat {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  margin-top: 44px;
}
.packstat > div {
  padding: 26px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  display: flex; flex-direction: column; gap: 7px;
  transition: transform 0.45s var(--ease-out-expo), border-color 0.3s linear;
}
.packstat > div:hover { transform: translateY(-4px); border-color: var(--line-2); }
.packstat b {
  font-size: clamp(26px, 2.8vw, 34px); font-weight: 600;
  letter-spacing: -0.028em; color: var(--head); line-height: 1;
}
.packstat span { font-size: 13.5px; line-height: 1.5; color: var(--body); }

@media (max-width: 900px) {
  .playtable-head { display: none; }
  .playrow .pt-sector { order: -1; }
  .playrow {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 20px 22px;
  }
  .playrow .pt-name { font-size: 16px; margin-bottom: 2px; }
}

/* ============================================================
   founder quote — the positioning in one sentence
   ============================================================ */

.quote {
  /* the opening mark has line-height .4, so its ink overflows the box upward;
     inside the story section that landed on the lede. This is its clearance. */
  margin: clamp(46px, 5vw, 78px) 0 clamp(40px, 4.4vw, 64px);
  max-width: 1000px;
  margin-inline: auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 34px;
}
.quote blockquote {
  margin: 0;
  font-size: clamp(22px, 2.7vw, 36px);
  line-height: 1.34;
  letter-spacing: -0.022em;
  font-weight: 500;
  color: var(--head);
  text-wrap: balance;
  position: relative;
}
.quote blockquote::before {
  content: "\201C";
  display: block;
  font-size: clamp(52px, 6vw, 78px);
  line-height: 0.4;
  color: var(--brand);
  margin-bottom: 26px;
}
/* The opening mark is an ornament, not something to read aloud — some screen
   readers announce CSS generated content. The alt-text syntax silences it, but
   it is Safari 17.4+, so it is guarded: older browsers keep the glyph rather
   than dropping the whole declaration. */
@supports (content: "x" / "") {
  .quote blockquote::before { content: "\201C" / ""; }
}

.quote figcaption { display: flex; align-items: center; gap: 14px; }
.quote figcaption img {
  width: 48px; height: 48px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--line);
}
.quote figcaption div { display: flex; flex-direction: column; gap: 2px; text-align: left; }
.quote figcaption b { font-size: 15px; font-weight: 600; color: var(--head); }
.quote figcaption span { font-size: 13.5px; color: var(--dim); }

/* ============================================================
   top stack — nav row and mega drawer
   (the row and the drawer move as one fixed block)
   ============================================================ */

:root {
  --nav-h: 64px;   /* the row's declared height, owned by CSS */
  --top-h: 64px;   /* the measured stack offset, overwritten by JS */
}

.topstack {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 95;
}

.hdr {
  position: static;          /* it lives inside .topstack now */
  display: block;            /* the drawer stacks under the row, it is not a flex sibling */
  height: auto;
  border-bottom: 1px solid transparent;
  background: transparent;
  transition: background var(--dur-fast) linear, border-color var(--dur-fast) linear;
}
.topstack.stuck .hdr {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  border-bottom-color: var(--line);
}
/* with the drawer down the row goes opaque and the drawer owns the bottom rule */
.topstack.menu-open .hdr {
  background: var(--bg);
  backdrop-filter: none;
  border-bottom-color: transparent;
}
.topstack.menu-open .hdr > .hdr-in { border-bottom: 1px solid var(--line); }

/* ---------- roll-up nav links — two-layer label ---------- */
/* padding lives on `.nav a`, which outranks this selector */
.nav-roll { position: relative; border-radius: var(--r-sm); }
.nav-roll .roll {
  position: relative;
  display: block;
  overflow: hidden;
  /* both layers must be exactly one line tall, or the duplicate shows through */
  white-space: nowrap;
  line-height: 1.45;
  height: 1.45em;
}
.nav-roll .roll span {
  display: block;
  font-size: 14.5px;
  line-height: inherit;
  font-weight: 500;
  white-space: nowrap;
  color: var(--body);
  transition: transform 0.34s var(--ease-out-expo), color var(--dur-fast) linear;
}
.nav-roll .roll span:last-child {
  position: absolute;
  inset: 0 0 auto 0;
  transform: translateY(110%);
  color: var(--head);
}
.nav-roll:hover .roll span:first-child,
.nav-roll[aria-expanded="true"] .roll span:first-child { transform: translateY(-110%); }
.nav-roll:hover .roll span:last-child,
.nav-roll[aria-expanded="true"] .roll span:last-child { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .nav-roll .roll span { transition: none; }
  .nav-roll .roll span:last-child { display: none; }
  .nav-roll:hover .roll span:first-child { transform: none; color: var(--head); }
}
.nav-roll .caret {
  width: 12px; height: 12px;
  margin-left: 5px;
  transition: transform 0.3s var(--ease-out-expo);
  color: var(--dim);
}
.nav-roll[aria-expanded="true"] .caret { transform: rotate(180deg); }
.nav .nav-roll { display: inline-flex; align-items: center; flex: none; }

/* ---------- mega menu drawer ---------- */
.mega {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.55s var(--ease-out-expo);
  background: var(--bg);
  border-bottom: 1px solid transparent;
}
.mega.open { grid-template-rows: 1fr; border-bottom-color: var(--line); }
.mega > .mega-clip { overflow: hidden; min-height: 0; }
.mega .mega-in {
  display: grid;
  --mega-col: 264px;
  grid-template-columns:
    minmax(0, calc(var(--mega-col) * 1.16))   /* Flagship — two-line descriptions */
    minmax(0, var(--mega-col))                /* Products */
    minmax(0, calc(var(--mega-col) * 0.82))   /* Platform — short labels */
    minmax(240px, 400px);                     /* Featured */
  /* the tracks are content-sized, so spread the slack evenly between them
     instead of letting it pool into one gap before the Featured card */
  justify-content: space-between;
  align-items: start;
  column-gap: clamp(30px, 3vw, 64px);
  row-gap: 0;
  padding-block: 36px 44px;
}
.mega-col { display: flex; flex-direction: column; min-width: 0; }
.mega-col > .lbl {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 18px;
}
.mega-col ul { display: flex; flex-direction: column; gap: 18px; }
.mega-col a { display: block; }
.mega-col .big, .mega-col .sm, .mega-col .desc { display: block; }
.mega-col .big { font-size: clamp(19px, 1.7vw, 23px); font-weight: 600; color: var(--head); letter-spacing: -0.016em; }
.mega-col .sm { font-size: 14.5px; font-weight: 500; color: var(--head); }
.mega-col .desc { font-size: 12.5px; line-height: 1.5; color: var(--dim); margin-top: 3px; }
.mega-col a:hover .big, .mega-col a:hover .sm { color: var(--brand-text); }  /* was opacity .55, which measured 3.95:1 in light */
.mega-col a .big, .mega-col a .sm { transition: color var(--dur-fast) linear; }
.mega-col .tagnew {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--btn-fg); background: var(--btn-bg);
  padding: 2px 7px; border-radius: 4px; margin-left: 7px; vertical-align: 2px;
}
.mega-col a.mega-more {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  margin-top: auto; padding-top: 24px;
  font-size: 14px; color: var(--head);
}
.mega-more svg { display: block; flex: none; transition: transform 0.3s var(--ease-out-expo); }
.mega-more:hover svg { transform: translateX(4px); }

/* featured panel, pinned to the shell's right edge */
.mega-feat {
  justify-self: end;
  width: min(400px, 100%);
  background: var(--surface-2);
  border-radius: var(--r-md);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.mega-feat .lbl { font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--dim); }
.mega-feat img { width: 100%; border-radius: var(--r-sm); }
.mega-feat b { font-size: 15px; font-weight: 600; color: var(--head); line-height: 1.35; }
.mega-feat span { font-size: 12.5px; line-height: 1.5; color: var(--dim); }

/* scrim behind an open drawer */
.nav-scrim {
  position: fixed;
  inset: 0;
  z-index: 94;
  background: rgba(0,0,0,.20);
  backdrop-filter: blur(24px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s var(--ease-out-expo), visibility 0.4s;
  -webkit-mask-image: linear-gradient(#000, #000, transparent);
  mask-image: linear-gradient(#000, #000, transparent);
}
.nav-scrim.on { opacity: 1; visibility: visible; }

/* ============================================================
   top stack — responsive
   the nav CSS is the last block in this file, so its breakpoints
   have to live here or the base rules win on specificity ties
   ============================================================ */

@media (max-width: 1180px) {
  .mega .mega-in { grid-template-columns: 1.1fr 1fr 0.85fr; gap: 34px; }
  .mega-feat { display: none; }              /* the columns matter more than the promo */
}

@media (max-width: 1400px) {
  /* track 4's 240px floor is breached at ~1210px and the grid overflows the shell */
  .mega .mega-in { --mega-col: 232px; column-gap: 30px; }
}

@media (max-width: 1000px) {
  .nav { --nav-pad-x: 10px; gap: 2px; }
}

@media (max-width: 860px) {
  .mega, .nav-scrim { display: none; }       /* no trigger once the nav collapses */
}

/* ============================================================
   contact dialog
   native <dialog> so focus trapping, Escape and inert
   background come from the platform rather than from us
   ============================================================ */

.cmodal {
  width: min(1020px, calc(100vw - 2 * var(--gutter-shell)));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--body);
  overflow: hidden;
}
.cmodal::backdrop {
  background: color-mix(in srgb, #05070a 62%, transparent);
  backdrop-filter: blur(6px);
}
.cmodal[open] { animation: cmodal-in 0.42s var(--ease-out-expo); }
.cmodal[open]::backdrop { animation: cmodal-fade 0.42s var(--ease-out-expo); }
@keyframes cmodal-in { from { opacity: 0; transform: translateY(14px) scale(0.985); } }
@keyframes cmodal-fade { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .cmodal[open], .cmodal[open]::backdrop { animation: none; }
}

.cmodal-in {
  display: grid;
  grid-template-columns: 0.86fr 1.14fr;
  max-height: calc(100vh - 48px);
}

.cmodal-x {
  position: absolute;
  top: 14px; right: 14px;
  z-index: 2;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  color: var(--dim);
  background: var(--surface);
  border: 1px solid var(--line);
  transition: color var(--dur-fast) linear, border-color var(--dur-fast) linear;
}
.cmodal-x:hover { color: var(--head); border-color: var(--line-2); }

/* ---------- left panel ---------- */
.cmodal-aside {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 38px 34px;
  background: var(--surface-2);
  border-right: 1px solid var(--line);
  overflow-y: auto;
}
.cmodal-aside .lede { font-size: 14.5px; line-height: 1.62; }
.cmodal-pts { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.cmodal-pts li { display: flex; gap: 11px; align-items: flex-start; }
.cmodal-pts svg { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--brand); }
.cmodal-pts span { font-size: 14px; line-height: 1.55; color: var(--body); }
.cmodal-alt { margin-top: auto; padding-top: 18px; font-size: 13px; color: var(--dim); }
.cmodal-alt a { color: var(--head); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- form ---------- */
.cmodal-form { padding: 38px 34px; overflow-y: auto; }
#contact-form { display: flex; flex-direction: column; gap: 15px; }
.cf-row { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; }
.cf { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cf label { font-size: 12.5px; font-weight: 500; color: var(--head); }
.cf-opt { font-weight: 400; color: var(--dim); }

.cf input, .cf textarea, .cf select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--head);
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 10px 12px;
  transition: border-color var(--dur-fast) linear, box-shadow var(--dur-fast) linear;
}
.cf textarea { resize: vertical; min-height: 76px; line-height: 1.55; }
.cf input:focus-visible, .cf textarea:focus-visible, .cf select:focus-visible {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}
/* the select keeps its own arrow so it does not depend on a background image */
.cf-sel { position: relative; display: block; }
.cf-sel select { appearance: none; padding-right: 36px; }
.cf-sel svg {
  position: absolute; right: 12px; top: 50%;
  width: 15px; height: 15px;
  margin-top: -7px;
  color: var(--dim);
  pointer-events: none;
}

.cf-err { display: none; font-size: 12px; color: #d9483b; }
.cf.invalid .cf-err { display: block; }
.cf.invalid input, .cf.invalid textarea, .cf.invalid select { border-color: #d9483b; }
[data-theme="dark"] .cf-err { color: #ff8a7a; }
[data-theme="dark"] .cf.invalid input,
[data-theme="dark"] .cf.invalid textarea,
[data-theme="dark"] .cf.invalid select { border-color: #ff8a7a; }

.cf-check { display: flex; gap: 10px; align-items: flex-start; margin-top: 3px; }
.cf-check input { margin-top: 2px; width: 15px; height: 15px; flex: none; accent-color: var(--brand); }
.cf-check span { font-size: 12.5px; line-height: 1.5; color: var(--dim); }

/* honeypot: off-screen rather than display:none, so bots that skip
   hidden fields still fill it in */
.cf-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.cf-note { font-size: 12px; line-height: 1.5; color: var(--dim); }
.cf-actions { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 3px; }
.cf-actions .btn { flex: none; }
.cf-status { font-size: 13px; line-height: 1.5; color: var(--dim); }
.cf-status.ok { color: var(--head); }
.cf-status.bad { color: #d9483b; }
[data-theme="dark"] .cf-status.bad { color: #ff8a7a; }
#contact-form.sending { opacity: 0.6; pointer-events: none; }

/* the success panel replaces the form body rather than sitting under it */
.cf-done { display: flex; flex-direction: column; gap: 14px; padding: 12px 0; }
.cf-done h3 { font-size: 21px; font-weight: 600; color: var(--head); letter-spacing: -0.015em; }
.cf-done p { font-size: 14.5px; line-height: 1.62; color: var(--body); }

@media (max-width: 860px) {
  .cmodal { width: 100vw; max-width: 100vw; max-height: 100dvh; height: 100dvh; border-radius: 0; border: 0; }
  .cmodal-in { grid-template-columns: 1fr; max-height: 100dvh; overflow-y: auto; }
  .cmodal-aside { border-right: 0; border-bottom: 1px solid var(--line); padding: 30px 22px 26px; overflow: visible; }
  .cmodal-aside .lede { font-size: 14px; }
  .cmodal-alt { margin-top: 4px; }
  .cmodal-form { padding: 26px 22px 34px; overflow: visible; }
}
@media (max-width: 560px) {
  .cf-row { grid-template-columns: 1fr; }
  .cf-actions .btn { width: 100%; }
}

/* every industry panel used to end in twenty metrics and no way out */
/* a sector can be served by more than one product */
.panel-gos { display: flex; flex-wrap: wrap; gap: 10px 32px; margin-top: 28px; }
.panel-gos .panel-go { margin-top: 0; }

.panel-go {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 28px;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--head);
}
.panel-go svg { flex: none; color: var(--brand); transition: transform 0.3s var(--ease-out-expo); }
.panel-go:hover svg { transform: translateX(4px); }

/* capability pills — used by the platform section and the company section */
.badges { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 30px; }
.badges span {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
  border: 1px solid var(--line);
  padding: 8px 14px;
  border-radius: var(--r-pill);
  transition: color var(--dur-fast) linear, border-color var(--dur-fast) linear;
}
.badges span:hover { color: var(--head); border-color: var(--line-2); }

/* ============================================================
   the platform, drawn as an elevation

   Read from the ground up: 01 is the plane everything rests on,
   02 is the router the whole stack necks down through, 03 and 04
   are the two engines it dispatches BETWEEN (not steps above it),
   and 05 is the surface people touch. The connectors carry the
   meaning, so they are the strongest graphic here.
   ============================================================ */

.arch {
  --arch-line: color-mix(in srgb, var(--dim) 55%, transparent);
  --join-h: 58px;
  --join-fork-h: 74px;
  max-width: 1000px;
  margin: 56px auto 0;
}

.arch-stack { display: flex; flex-direction: column; }

/* ---------- a layer ---------- */
.ly {
  position: relative;
  display: flex;
  gap: 18px;
  padding: 22px 26px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  transition: transform 0.5s var(--ease-out-expo), border-color 0.3s linear,
              box-shadow 0.5s var(--ease-out-expo);
}
.ly-txt { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.ly-n {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim);
}
.ly h3 {
  font-family: var(--mono); font-size: 13.5px; letter-spacing: 0.07em;
  text-transform: uppercase; font-weight: 600; color: var(--head); line-height: 1.35;
}
.ly p { font-size: 14px; line-height: 1.6; color: var(--body); }
.ly-ico {
  width: 40px; height: 40px; flex: none;
  display: grid; place-items: center;
  border-radius: 11px;
  background: color-mix(in srgb, var(--brand) 13%, transparent);
  color: var(--brand);
}
.ly-ico svg { width: 20px; height: 20px; }

/* elevation says where in the stack a layer sits */
.ly-base {
  /* The ground plane. It reads as the foundation through the stacked sheets
     below it, not through a different colour -- tinting it made 01 look like
     a different kind of thing from the four layers above. */
  box-shadow: 0 6px 0 -1px var(--surface), 0 7px 0 -1px var(--line),
              0 13px 0 -2px var(--surface), 0 14px 0 -2px var(--line);
}
.ly-router {
  width: min(72%, 620px);
  margin-inline: auto;
  box-shadow: var(--shadow-md);
}
.ly-router .ly-ico {
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand) 16%, transparent);
}
.ly-app { box-shadow: var(--shadow-lg); }
/* 03 and 04 carry consecutive numbers but are NOT consecutive steps: 02 routes
   to one or the other. The numbering alone reads as a sequence, so the tier
   says out loud what the fork is already drawing. */
.engines { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 18px; }
.engines-tier {
  grid-column: 1 / -1;
  text-align: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}
.ly-engine { box-shadow: var(--shadow-md); }

@media (hover: hover) {
  /* looking at one layer quietens the rest */
  .arch-stack:hover .ly { opacity: 0.5; }
  .arch-stack .ly:hover { opacity: 1; transform: translateY(-3px); border-color: var(--line-2); }
}

/* ---------- the connectors ---------- */
/* overflow:hidden is the guarantee — a pulse can never leave the connector it
   belongs to and ride up over a layer's text. --travel is how far it actually
   runs, which is NOT always the join's full height: the fork draws its centre
   line only below the rail, and the merge only above it. */
.join {
  position: relative;
  height: var(--join-h);
  flex: none;
  overflow: hidden;
  --travel: var(--join-h);
}
.join-fork { height: var(--join-fork-h); --travel: calc(var(--join-fork-h) / 2); }
.join-merge { --travel: calc(var(--join-h) / 2); }
/* the centre stem */
.join::before {
  content: "";
  position: absolute; left: 50%; width: 1px;
  background: var(--arch-line);
}
.join-stem::before { top: 0; bottom: 0; }
/* the fork: stem rises to a rail, then two legs rise to the engines */
.join-fork::before { top: 50%; bottom: 0; }
.join-fork::after {
  content: "";
  position: absolute; left: 25%; right: 25%; top: 0; height: 50%;
  border-left: 1px solid var(--arch-line);
  border-right: 1px solid var(--arch-line);
  border-bottom: 1px solid var(--arch-line);
}
/* the merge: two legs drop from a rail, and one stem rises into 05 */
.join-merge::before { top: 0; height: 50%; }
.join-merge::after {
  content: "";
  position: absolute; left: 25%; right: 25%; bottom: 0; height: 50%;
  border-left: 1px solid var(--arch-line);
  border-right: 1px solid var(--arch-line);
  border-top: 1px solid var(--arch-line);
}

/* the routing rule, written on the branch it describes */
.join-lab {
  position: absolute; top: 10px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--dim); white-space: nowrap;
  /* the label sits on the leg it annotates, so it knocks the line out
     behind itself the way a dimension label does on a drawing */
  padding: 2px 8px;
  background: var(--bg-2);
  z-index: 2;          /* ::after draws the rail last, so lift the label over it */
}
.join-lab-l { left: 25%; transform: translateX(-50%); }
.join-lab-r { left: 75%; transform: translateX(-50%); }

/* ---------- the signal travelling up the stack ----------

   One signal, not three. The three segments share a single duration and a
   single timeline, and each is given the slice of it that matches its own
   length, so the light crosses the whole stack at ONE constant speed and
   hands off cleanly between segments. Segment lengths are 58 / 37 / 29px
   plus the 34px trail: 92 / 71 / 63 of 226 total, hence 40.7% and 72.1%.
   Timing is linear -- an easing curve would make it accelerate and brake,
   which is what made it look erratic.
   ---------------------------------------------------------- */

.join i {
  position: absolute;
  left: 50%;
  margin-left: -1px;
  width: 2px;
  height: 34px;
  /* a tapered trail rather than a droplet: no hard edge to read as an object */
  background: linear-gradient(to top,
      transparent,
      color-mix(in srgb, var(--brand) 30%, transparent) 40%,
      color-mix(in srgb, var(--brand) 85%, transparent));
  border-radius: 2px;
  opacity: 0;
}
.js .arch-stack.lit .join-stem i  { animation: arch-seg1 3.8s linear infinite; }
.js .arch-stack.lit .join-fork i  { animation: arch-seg2 3.8s linear infinite; }
.js .arch-stack.lit .join-merge i { animation: arch-seg3 3.8s linear infinite; }

.join-stem i { bottom: 0; }
.join-fork i { bottom: 0; }
.join-merge i { bottom: 50%; }

@keyframes arch-seg1 {
  0%     { transform: translateY(100%); opacity: 0; }
  4%     { opacity: 1; }
  35%    { opacity: 1; }
  40.7%  { transform: translateY(calc(-1 * var(--travel))); opacity: 0; }
  100%   { transform: translateY(calc(-1 * var(--travel))); opacity: 0; }
}
@keyframes arch-seg2 {
  0%     { transform: translateY(100%); opacity: 0; }
  40.7%  { transform: translateY(100%); opacity: 0; }
  45%    { opacity: 1; }
  67%    { opacity: 1; }
  72.1%  { transform: translateY(calc(-1 * var(--travel))); opacity: 0; }
  100%   { transform: translateY(calc(-1 * var(--travel))); opacity: 0; }
}
@keyframes arch-seg3 {
  0%     { transform: translateY(100%); opacity: 0; }
  72.1%  { transform: translateY(100%); opacity: 0; }
  76%    { opacity: 1; }
  95%    { opacity: 1; }
  100%   { transform: translateY(calc(-1 * var(--travel))); opacity: 0; }
}

/* ---------- reach: a baseplate, not a storey ---------- */
.arch-reach {
  display: flex; gap: 18px; align-items: flex-start;
  max-width: 640px;
  margin: 34px auto 0;
  padding-top: 26px;
  border-top: 1px dashed var(--line-2);
}
.arch + .badges { margin-top: 40px; }
.arch-reach .ly-ico {
  background: none;
  border: 1px solid var(--line-2);
  color: var(--dim);
}
.arch-reach b { display: block; margin-top: 3px; font-size: 15px; font-weight: 600; color: var(--head); }
.arch-reach .rc { display: block; margin-top: 5px; font-size: 13.5px; line-height: 1.55; color: var(--dim); }

@media (prefers-reduced-motion: reduce) {
  /* the animations now sit on .join-stem i etc, which outranks .join i --
     match that specificity or reduced motion is silently ignored */
  .js .arch-stack.lit .join-stem i,
  .js .arch-stack.lit .join-fork i,
  .js .arch-stack.lit .join-merge i { animation: none; opacity: 0; }
  .ly { transition: none; }
}

/* below the fold of a phone the fork becomes an indented bracket */
@media (max-width: 860px) {
  .arch { --join-h: 40px; }
  .ly { padding: 18px 20px; gap: 14px; }
  .ly-router { width: auto; }
  .engines { grid-template-columns: 1fr; gap: 0; }
  .engines .ly-engine + .ly-engine { margin-top: var(--join-h); }
  /* one column, so the fork collapses to a plain stem */
  .join-fork::after, .join-merge::after { display: none; }
  .join-fork::before { top: 0; bottom: 0; }
  .join-merge::before { top: 0; height: 100%; }
  .join-lab { display: none; }
}


/* ============================================================
   product screenshots

   Copy beside the image, vertically centred against it, with the
   shot at its own aspect so nothing is cropped. Stacking the copy
   above a full-measure image was correct for one row and ruinous
   for five: it made the section 7157px, half the page.
   ============================================================ */

.feat { align-items: center; }

#products .feat .stage:not(.tall) img {
  width: 100%;
  height: auto;
  border-radius: var(--r-lg);
  box-shadow: 0 26px 56px rgba(20, 30, 50, 0.15);
}
[data-theme="dark"] #products .feat .stage img {
  box-shadow: 0 26px 56px rgba(0, 0, 0, 0.5);
}
#products .feat .stage:not(.tall) .stage-cap { margin-top: 20px; }

@media (min-width: 1000px) {
  #products .wrap { max-width: 1500px; }
  #products .feat {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
    gap: clamp(48px, 6vw, 112px);
  }
  #products .feat.flip { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); }
  /* the copy is a compact block floating beside the shot, not a full column */
  #products .feat .feat-copy { max-width: 460px; }
  #products .feat.flip .feat-copy { margin-left: auto; }
  /* the Explore button reads as the block's close, centred under the copy
     rather than hanging off its left edge */
  #products .feat .feat-copy > .btn { align-self: center; }
}

/* ============================================================
   product section hierarchy

   The section title and all five product titles were the same
   .h2, so the opener had nothing to distinguish it from the five
   headings repeating underneath — and repetition wins. It now
   sits a step above them, and the product headings a step below,
   which puts three clear levels on the page: page h1, section,
   product.
   ============================================================ */

#products > .wrap > .sec-head { align-items: center; text-align: center; margin-inline: auto; }
#products > .wrap > .sec-head .h2 {
  font-size: clamp(34px, 4.4vw, 60px);
  letter-spacing: -0.032em;
  max-width: 20ch;
}
#products > .wrap > .sec-head .lede { max-width: 68ch; margin-inline: auto; }

#products .feat-copy .h2 {
  font-size: clamp(26px, 2.9vw, 40px);
  letter-spacing: -0.024em;
}

@media (min-width: 1000px) {
  #products .feat-first { margin-top: clamp(48px, 5vw, 76px); }
}

/* ============================================================
   hero scale
   The hero ran to the 1320px prose measure while the product
   rows run to 1500, so it read smaller than the section under
   it. Wider container, bigger headline, bigger screenshots.
   ============================================================ */

.hero .wrap { max-width: 1500px; }
/* the four reveal lines are a composition; 'operating systems for' is the
   longest and must stay on one line at every width, which caps the scale */
.hero .h1 { font-size: clamp(38px, 4.7vw, 72px); letter-spacing: -0.038em; }

@media (min-width: 1000px) {
  .hero-grid { grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr); gap: clamp(30px, 3.4vw, 56px); }
  .hero .lede, .hero .tiny { max-width: 52ch; }
}

/* ============================================================
   the 861-999px gap
   The grids collapsed at 860 while the desktop rules only begin
   at 1000, so tablets and landscape phones fell through to the
   untuned base two-column rule: a 483px screenshot beside a
   cramped column of copy. They now stack right up to the point
   the desktop layout takes over.
   ============================================================ */

@media (max-width: 999px) {
  /* .feat.flip is (0,2,0) and beat a bare .feat, so flipped rows -- CoCare and
     ORB -- stayed two-column on a phone while the others collapsed. It has to
     be named explicitly to be overridden. */
  .hero-grid, .feat, .feat.flip, .panel.on, .cases, .ftr-grid { grid-template-columns: 1fr; }
  .feat.flip .feat-copy { order: 0; }
  #products .feat .feat-copy { max-width: none; }
  /* .hero-float is offset by a percentage of .hero-visual, which quadruples in
     width the moment the hero stacks. -6% of a full-width column overshoots the
     gutter and body's overflow-x:hidden shears the phone's left edge off, so the
     stacked offset has to start where the stack starts, not 140px later. */
  .hero-float { width: 26%; left: -3%; }
}

/* a full-bleed button under a left-aligned headline reads as a banner, not a
   call to action; size it to its label instead */
@media (max-width: 560px) {
  .hero-cta .btn, .cta-box .btn { width: auto; }
}


/* ============================================================
   legal prose - one readable column, not a wall
   ============================================================ */
.prose { max-width: 68ch; margin-top: clamp(34px, 4vw, 52px); }
.prose .upd { display: block; padding-bottom: 22px; border-bottom: 1px solid var(--line); }
.prose h2 {
  font-size: clamp(18px, 1.5vw, 21px); font-weight: 600; color: var(--head);
  letter-spacing: -0.01em; margin-top: 38px; margin-bottom: 12px;
}
.prose p { font-size: 15.5px; line-height: 1.72; color: var(--body); margin-bottom: 14px; }
.prose a { color: var(--head); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--brand); }

/* the demonstration-data note lives with the screenshots rather than in the
   footer - quiet enough not to compete, close enough to be the caption it is */
.shot-note {
  margin-top: 14px; text-align: right;
  font-size: 11.5px; line-height: 1.5; color: var(--dim);
}
.shot-note-sec { text-align: left; margin-top: clamp(30px, 3.4vw, 48px); }
@media (max-width: 999px) { .shot-note { text-align: left; } }


/* ============================================================
   hero hub - what the company does, without showing one product
   ============================================================ */
.hub {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(10px, 1.6vw, 24px);
}
.hub-side { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.hub-lab {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--dim); margin-bottom: 2px;
}
.hub-side ul { list-style: none; display: flex; flex-direction: column; gap: 8px; }
.hub-side li {
  position: relative; font-size: 12.5px; line-height: 1.3;
  padding: 9px 12px; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: var(--surface); color: var(--head);
}
.hub-in { text-align: right; }
/* a stub from each chip toward the core, so it reads as one system */
.hub-in li::after, .hub-out li::before {
  content: ""; position: absolute; top: 50%;
  width: clamp(6px, 1.3vw, 20px); height: 1px; background: var(--line-2);
}
.hub-in li::after { left: 100%; }
.hub-out li::before { right: 100%; }
.hub-core {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 3px; max-width: 220px;
  padding: clamp(18px, 2.4vw, 28px) clamp(14px, 1.8vw, 22px);
  border: 1px solid var(--line-2); border-radius: var(--r-md);
  background: var(--surface);
}
.hub-mark svg { display: block; width: 28px; height: 28px; fill: var(--head); }
.hub-core b { font-size: 16px; font-weight: 600; color: var(--head); letter-spacing: -0.012em; }
.hub-gov {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--brand-text);
}
.hub-sub { font-size: 11px; line-height: 1.45; color: var(--dim); margin-top: 5px; }

@media (max-width: 760px) {
  .hub { grid-template-columns: 1fr; justify-items: center; gap: 16px; }
  .hub-side { align-items: center; text-align: center; }
  .hub-in { text-align: center; }
  .hub-side ul { flex-direction: row; flex-wrap: wrap; justify-content: center; }
  .hub-in li::after, .hub-out li::before { display: none; }
  .hub-core { max-width: none; }
}

/* ============================================================
   platform - three rows, the middle one is ours
   ============================================================ */
.plat { display: flex; flex-direction: column; gap: 12px; margin-top: clamp(34px, 4vw, 52px); }
.plat-row {
  display: grid; grid-template-columns: auto minmax(0, 210px) minmax(0, 1fr);
  align-items: center; gap: clamp(12px, 2.2vw, 32px);
  padding: clamp(18px, 2.2vw, 26px) clamp(18px, 2.4vw, 30px);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
}
.plat-core { border-color: var(--brand); position: relative; }
.plat-core::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--brand); opacity: 0.05; pointer-events: none;
}
.plat-n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; color: var(--dim); }
.plat-core .plat-n { color: var(--brand-text); }
.plat-row b { font-size: clamp(15px, 1.5vw, 18px); font-weight: 600; color: var(--head); }
.plat-items { font-size: 13.5px; line-height: 1.5; color: var(--body); }
.plat-diff {
  list-style: none; display: flex; flex-wrap: wrap; justify-content: center;
  gap: 10px; margin-top: clamp(24px, 3vw, 36px);
}
.plat-diff li {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--dim); padding: 8px 14px; border: 1px solid var(--line); border-radius: 999px;
}
@media (max-width: 760px) {
  .plat-row { grid-template-columns: auto 1fr; row-gap: 6px; }
  .plat-items { grid-column: 1 / -1; }
}


/* the dropdown is now one product list; two columns keeps it short */
/* the dropdown used to be four tracks - Flagship, Products, Platform, Featured.
   It is one product list now, so the container must stop being that grid or the
   list is squeezed into the first 306px track and every description wraps. */
.mega .mega-in.mega-in-solo { display: block; }
.mega-only { max-width: 880px; }
/* two columns keeps the panel short; the row gap has to stay generous or the
   name of the next product sits straight under the previous description */
.mega-only > ul {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 64px; row-gap: 26px;
}
@media (max-width: 700px) { .mega-only > ul { grid-template-columns: 1fr; } }


/* ============================================================
   product pages - what it does, and the case study under it
   ============================================================ */
.wid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 28px); margin-top: clamp(34px, 4vw, 52px);
}
.wid-item {
  display: flex; flex-direction: column; gap: 8px;
  padding: clamp(22px, 2.4vw, 30px);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
}
.wid-n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; color: var(--brand-text); }
.wid-item b { font-size: clamp(16px, 1.5vw, 18px); font-weight: 600; color: var(--head); letter-spacing: -0.012em; }
.wid-item > span:last-child { font-size: 14px; line-height: 1.6; color: var(--body); }

.cs-list { display: flex; flex-direction: column; gap: clamp(18px, 2.2vw, 28px); margin-top: clamp(34px, 4vw, 52px); }
.cs {
  padding: clamp(24px, 3vw, 40px);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
}
.cs-head { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.cs-client {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--dim);
}
.cs > .lede { max-width: 68ch; }
.cs-out {
  display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 56px);
  margin-top: clamp(20px, 2.4vw, 30px);
  padding-top: clamp(20px, 2.4vw, 30px); border-top: 1px solid var(--line);
}
.cs-metric { display: flex; flex-direction: column; gap: 4px; }
.cs-metric b {
  font-size: clamp(30px, 3.6vw, 46px); font-weight: 600;
  color: var(--head); letter-spacing: -0.028em; line-height: 1;
}
.cs-metric span {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--dim);
}
.cs-more { margin-top: clamp(18px, 2.2vw, 26px); border-top: 1px solid var(--line); padding-top: 16px; }
.cs-more > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  cursor: pointer; list-style: none; font-size: 14.5px; font-weight: 600; color: var(--head);
}
.cs-more > summary::-webkit-details-marker { display: none; }
.cs-more > summary svg { flex: none; transition: transform 0.25s ease; color: var(--dim); }
.cs-more[open] > summary svg { transform: rotate(180deg); }
.cs-more p { font-size: 15px; line-height: 1.72; color: var(--body); margin-top: 14px; max-width: 72ch; }

@media (max-width: 860px) { .wid { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .cs-more > summary svg { transition: none; } }


/* ============================================================
   the hero carries only copy now; the glow behind it is the visual
   ============================================================ */
.hero-solo { grid-template-columns: minmax(0, 1fr); }
.hero-solo .h1 { max-width: 24ch; }   /* two lines; the 15ch cap was forcing three */
.hero-solo .hero-copy .lede { max-width: 54ch; }

/* ============================================================
   platform stack - industry knowledge in, applications out,
   with the platform itself carrying the middle
   ============================================================ */
.stackd {
  display: flex; flex-direction: column; align-items: stretch;
  max-width: 940px; margin: clamp(36px, 4.4vw, 60px) auto 0;
}
.tier {
  display: flex; flex-direction: column; gap: 14px;
  padding: clamp(20px, 2.4vw, 28px) clamp(20px, 2.6vw, 32px);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface);
}
.tier-core {
  border-color: var(--brand); position: relative;
  box-shadow: 0 18px 40px -28px rgba(43, 76, 126, 0.5);
}
.tier-core::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--brand); opacity: 0.045; pointer-events: none;
}
.tier-head { display: flex; align-items: baseline; gap: 14px; }
.tier-n { font-family: var(--mono); font-size: 11px; letter-spacing: 0.13em; color: var(--dim); }
.tier-core .tier-n { color: var(--brand-text); }
.tier-head b { font-size: clamp(16px, 1.6vw, 19px); font-weight: 600; color: var(--head); letter-spacing: -0.014em; }
.tier-chips { display: flex; flex-wrap: wrap; gap: 8px; position: relative; }
.tier-chips > span, .tier-chips > a {
  font-size: 13px; line-height: 1.2; padding: 9px 14px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); color: var(--body);
}
.tier-core .tier-chips > span { border-color: var(--line-2); color: var(--head); background: var(--surface); }
.tier-chips-app > a {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: 0.08em;
  color: var(--head); text-decoration: none;
  transition: border-color 0.18s ease, color 0.18s ease;
}
.tier-chips-app > a:hover { border-color: var(--brand); color: var(--brand-text); }
.tier-foot { font-size: 13px; line-height: 1.55; color: var(--dim); margin-top: 2px; position: relative; }
.tier-flow {
  display: block; width: 1px; height: clamp(26px, 3vw, 42px);
  margin: 0 auto; background: var(--line-2); position: relative;
}
.tier-flow svg {
  position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%);
  width: 15px; height: 15px; color: var(--line-2); background: var(--bg);
}
@media (prefers-reduced-motion: reduce) { .tier-chips-app > a { transition: none; } }
@media (max-width: 860px) { .hero-solo .h1 { max-width: none; } }
@media (max-width: 640px) { .tier-head { flex-direction: column; align-items: flex-start; gap: 4px; } }

/* ============================================================
   platform stack - flow arrows between the tiers
   Replaces the old 1px --line-2 rule (1.33:1 in light = invisible)
   whose chevron inherited that 1px width and collapsed to 1x15.
   The arrow now spans the whole gap, edge to edge, so it reads as
   a connection out of one tier and into the next.
   ============================================================ */
.tier-flow {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  width: auto;
  height: auto;
  margin: 0;
  padding: 0;
  background: none;
  position: relative;
}
.tier-flow svg {
  grid-column: 2;
  justify-self: center;
  position: static;
  inset: auto;
  transform: none;
  display: block;
  width: 20px;
  height: 46px;
  background: none;
  color: var(--brand-text);   /* 5.55:1 light, 7.12:1 dark */
  overflow: visible;
}
.tier-flow-label {
  grid-column: 3;
  justify-self: start;
  margin-left: 12px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);           /* 4.88:1 light, 5.46:1 dark */
  white-space: nowrap;
}
@media (max-width: 640px) {
  .tier-flow svg { width: 17px; height: 39px; }
  .tier-flow-label { margin-left: 9px; font-size: 10px; letter-spacing: 0.08em; }
}

/* the hero is copy only now - no tall visual to reserve height for - so it is
   centred, and min-height comes down from min(84vh,780px), which was leaving
   roughly 750px of empty band under 375px of content on a tall screen */
.hero-solo .hero-copy { align-items: center; text-align: center; }
.hero-solo .hero-cta { justify-content: center; }
.hero-solo .hero-copy .lede { margin-inline: auto; }
.hero-lean { min-height: min(64vh, 620px); }


/* direction marker inside a case-study figure. The arrow is decorative and
   hidden from assistive tech; the meaning it carries is restored by an
   sr-only word in the label, so it still reads as "20% reduction in food waste". */
.cs-dir {
  font-style: normal; font-size: 0.62em; line-height: 1;
  margin-left: 0.06em; vertical-align: 0.08em; color: var(--brand-text);
}


/* "Get started" is the only --dim text painted over the .cta-box glow, where it
   measured 3.30:1 light / 3.49:1 dark. --body on the same grounds is 6.01-7.39:1.
   Pre-dates the recolour: --glow-a was never part of it. */
.cta-box .eyebrow { color: var(--body); }

/* Turnstile renders a fixed 300x65 frame of its own. Give it the form's rhythm
   and let it shrink with the panel instead of overflowing on a narrow screen. */
.cf-verify { min-height: 65px; }
.cf-verify iframe { max-width: 100%; }
