/* =====================================================================
   NanoLeap — site design system  (assets/site.css)
   Shared by every page. Page-only CSS lives in each page's <style>,
   prefixed with the body class (.pg-index, .pg-oddsforge, …).
   Canonical markup for every component: tools/COMPONENTS.md
   ---------------------------------------------------------------------
   01 Fonts          06 Buttons            11 Flow diagram
   02 Tokens         07 Nav + mobile menu  12 Pins + legend
   03 Reset + base   08 Page hero          13 Stat row
   04 Layout         09 Cards + chips      14 Screen frame
   05 Type           10 Comparison pair    15 Closing CTA band
                                           16 Footer
                                           17 Motion utilities
                                           18 Live visuals
                                           19 Figure frame
   ===================================================================== */

/* ---------- 01 Fonts (self-hosted) ---------- */
@font-face{font-family:"Inter";src:url(fonts/Inter-latin.woff2) format("woff2");font-weight:100 900;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";src:url(fonts/Inter-latin-ext.woff2) format("woff2");font-weight:100 900;font-style:normal;font-display:swap;
  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}
@font-face{font-family:"Space Grotesk";src:url(fonts/SpaceGrotesk-Regular.woff) format("woff");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Space Grotesk";src:url(fonts/SpaceGrotesk-Medium.woff) format("woff");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Space Grotesk";src:url(fonts/SpaceGrotesk-SemiBold.woff) format("woff");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Space Grotesk";src:url(fonts/SpaceGrotesk-Bold.woff) format("woff");font-weight:700;font-style:normal;font-display:swap}

/* ---------- 02 Tokens ---------- */
:root{
  /* brand colour */
  --ink:#15151A;          /* text, headings */
  --ink-2:#4B505B;        /* secondary text (never lighter for body copy) */
  --ink-3:#8C919B;        /* footnotes, column labels only */
  --ink-4:#B9BDC5;        /* disabled, hairline marks */
  --line:#E7E9ED;         /* hairlines, card borders */
  --line-2:#D9DCE2;       /* stronger borders (secondary buttons, inputs) */
  --bg:#FFFFFF;
  --bg-2:#F5F6F8;         /* alt section, muted cards */
  --bg-3:#EEF0F3;         /* muted footers inside muted cards */
  --neon:#22FF86;         /* buttons, pins, accents on dark */
  --green:#00DE64;        /* marks: squares, lines, connectors */
  --green-ink:#0A8A47;    /* green used as text on white */
  --green-tint:#F2FFF8;   /* "after"/success surfaces */
  --green-line:#CFF3DF;
  --green-soft:#E6FBEF;
  --red:#C2261D;
  --red-tint:#FDECEB;
  --night:#0E0E11;        /* dark bookends: hero, CTA band */
  --night-2:#15151A;      /* dark cards */
  --night-3:#0B0B0E;      /* footer */
  --on-night:#FFFFFF;
  --on-night-2:#B4B8C1;
  --on-night-3:#8A8E98;

  /* type */
  --font-display:"Space Grotesk",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-body:"Inter",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace; /* mock-screen code only */

  /* layout */
  /* one container for the nav, hero, every section and the footer (owner, 2026-10-14): 1200px up to
     a 1440px screen, then fluid to a hard max of 1600px (reached at about 1940px), centred beyond */
  --wrap:clamp(1200px,80vw + 48px,1600px);
  --gutter:clamp(20px,5vw,120px);
  --nav-h:72px;
  /* section rhythm: grows with the screen's width and its height, so a short laptop screen (1366×768)
     isn't mostly padding: about 96px at 1280×720, 100 at 1366×768, 112 at 1440×900, 128 at 1920×1080,
     160 at 2560×1440; 80px on phones and tablets */
  --section-y:clamp(80px,min(5vw + 40px,9.1vh + 30px),168px);
  --section-y-tight:clamp(56px,min(3.4vw + 28px,6vh + 22px),112px);
  /* section head → the content below it */
  --head-gap:clamp(36px,min(3.2vw,4.6vh) + 16px,72px);
  /* a section head inside a .split column → the list, legend or ticks under it in the same column */
  --head-gap-tight:clamp(28px,min(2.4vw,3.4vh) + 8px,44px);
  /* gutters (cohesion pass, 2026-10-15): two tokens for every shared grid, split and pair.
     --gap-card: between cards in a grid of three or more (grid--3/--4, the footer, stat and legend rows)
     --gap-cols: between two content columns (split, grid--2, the compare pair) */
  --gap-card:24px;
  --gap-cols:clamp(28px,2.78vw,40px);
  --grid-gap:var(--gap-card);   /* legacy name, still read by .grid and the footer */

  /* large-screen ramp: a length that is 1px up to a 1600px screen and grows to 1.125px at 2560px.
     Multiply a px number by it to follow the site's text ramp: font-size:calc(15 * var(--ramp))
     is 15px up to 1600 and 16.9px at 2560 (body text 17 → 19, card text 16 → 18). */
  --ramp:1px;

  /* type scale. Text: 12.5 / 13.5 / 15 / 16 / 17. Use these, never a raw size, in shared and page CSS. */
  --fs-label:12.5px;      /* .label, column/group labels, captions inside a mock */
  --fs-xs:13.5px;         /* .text-xs: meta lines, row labels, sub-lines */
  --fs-sm:15px;           /* .small: lists, legend text, stat labels, captions */
  --fs-card:16px;         /* card and step text */
  --fs-body:17px;         /* body copy, h4 (16px on phones) */
  --fs-lead:clamp(18px,.45vw + 14px,21px);
  --fs-eyebrow:13px;
  --fs-badge:10.5px;
  --fs-card-title:21px;   /* h3, .card__title, .steps__title, .compare__title (20 on phones) */
  --fs-h2:clamp(30px,2.6vw + 10px,52px);
  --fs-cta-title:clamp(36px,3.4vw + 8px,62px);   /* closing headlines (the CTA band's own size; Company's closer) */
  --eyebrow-gap:22px;     /* eyebrow → h2 in a section head */
  --lead-gap:20px;        /* h2 → lead in a section head */
  --pad-card:clamp(24px,2.2vw,32px);

  /* status colours (badges): amber for waiting / in review / queued */
  --amber:#F5B947;
  --amber-ink:#8A5A00;    /* amber as text on its tint (5.4:1) */
  --amber-tint:#FFF4DC;
  --green-deep:#07773D;   /* green text on --green-soft (5.3:1; --green-ink is 4.1:1 there) */

  /* spacing scale (4-based) */
  --s-1:4px;--s-2:8px;--s-3:12px;--s-4:16px;--s-5:24px;--s-6:32px;--s-7:48px;--s-8:64px;--s-9:96px;--s-10:128px;

  /* radii */
  --r-xs:5px;--r-sm:8px;--r-md:12px;--r-lg:16px;--r-xl:20px;--r-pill:999px;

  /* shadows — zero-blur stacks (no gaussian blur, as in the decks) */
  --shadow-1:0 1px 0 0 rgba(21,21,26,.035),0 2px 0 -1px rgba(21,21,26,.03);
  /* each layer sits lower and narrower (negative spread), so the stack tapers like a soft shadow */
  --shadow-2:0 1px 0 0 rgba(21,21,26,.04),0 3px 0 -1px rgba(21,21,26,.026),0 7px 0 -3px rgba(21,21,26,.022),0 12px 0 -5px rgba(21,21,26,.019),0 18px 0 -8px rgba(21,21,26,.016),0 26px 0 -12px rgba(21,21,26,.013),0 36px 0 -17px rgba(21,21,26,.01);
  --shadow-3:0 1px 0 0 rgba(21,21,26,.045),0 4px 0 -2px rgba(21,21,26,.03),0 9px 0 -4px rgba(21,21,26,.026),0 16px 0 -7px rgba(21,21,26,.022),0 25px 0 -11px rgba(21,21,26,.018),0 36px 0 -16px rgba(21,21,26,.014),0 50px 0 -22px rgba(21,21,26,.011),0 66px 0 -30px rgba(21,21,26,.008);

  /* motion */
  --ease:cubic-bezier(.2,.7,.2,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
  --dur:.8s;

  /* context (light by default) — components read these, never raw colours */
  --fg:var(--ink);
  --fg-2:var(--ink-2);
  --fg-3:var(--ink-3);
  --rule:var(--line);
  --surface:#FFFFFF;
  --surface-2:var(--bg-2);
  --card-line:#E3E6EA;
  --accent:var(--green-ink);
  --mark:var(--green);
  --focus:var(--green-ink);
  /* status badges (light): background / text per meaning */
  --b-muted:var(--bg-3);--b-muted-fg:var(--ink-2);
  --b-done:var(--green-soft);--b-done-fg:var(--green-deep);
  --b-wait:var(--amber-tint);--b-wait-fg:var(--amber-ink);
  --b-fail:var(--red-tint);--b-fail-fg:var(--red);
  --b-live:var(--neon);--b-live-fg:var(--ink);
  --b-type:var(--ink);--b-type-fg:#FFFFFF;
  --b-line:var(--line-2);
}
/* phones and large screens: the type tokens follow the screen (the components read only the tokens,
   so nothing depends on rule order) */
@media (max-width:720px){:root{--fs-body:16px;--fs-eyebrow:12px;--fs-card-title:20px}}
@media (min-width:1600px){
  :root{
    --ramp:clamp(1px,1px + (100vw - 1600px) * .00013021,1.125px);
    --gap-card:clamp(24px,.833vw + 10.67px,32px);
    --gap-cols:clamp(40px,1.667vw + 13.33px,56px);
    --fs-label:clamp(12.5px,.104vw + 10.83px,13.5px);
    --fs-xs:calc(13.5 * var(--ramp));
    --fs-sm:calc(15 * var(--ramp));
    --fs-card:calc(16 * var(--ramp));
    --fs-body:calc(17 * var(--ramp));
    --fs-lead:clamp(21px,.3125vw + 16px,24px);
    --fs-eyebrow:clamp(13px,.104vw + 11.33px,14px);
    --fs-badge:calc(10.5 * var(--ramp));
    --fs-card-title:clamp(21px,.417vw + 14.33px,25px);
    --fs-h2:clamp(52px,1.25vw + 32px,64px);
    --fs-cta-title:clamp(62px,1.25vw + 42px,74px);
    --eyebrow-gap:clamp(22px,.417vw + 15.33px,26px);
    --lead-gap:clamp(20px,.417vw + 13.33px,24px);
    --pad-card:clamp(32px,.833vw + 18.67px,40px);
  }
}
/* dark context: anything inside these adapts automatically */
.on-dark,.section--dark,.page-hero,.cta-band,.site-footer,.site-menu{
  --fg:var(--on-night);
  --fg-2:var(--on-night-2);
  --fg-3:var(--on-night-3);
  --rule:rgba(255,255,255,.09);
  --surface:var(--night-2);
  --surface-2:#1B1B21;
  --card-line:rgba(255,255,255,.08);
  --accent:var(--neon);
  --mark:var(--neon);
  --focus:var(--neon);
  --b-muted:rgba(255,255,255,.08);--b-muted-fg:var(--on-night-2);
  --b-done:rgba(34,255,134,.12);--b-done-fg:var(--neon);
  --b-wait:rgba(245,185,71,.15);--b-wait-fg:#F6C35C;
  --b-fail:rgba(255,107,94,.15);--b-fail-fg:#FF8A80;
  --b-live:var(--neon);--b-live-fg:var(--ink);
  --b-type:#FFFFFF;--b-type-fg:var(--ink);
  --b-line:rgba(255,255,255,.2);
  color:var(--fg-2);
}
.on-light{
  --fg:var(--ink);--fg-2:var(--ink-2);--fg-3:var(--ink-3);--rule:var(--line);--surface:#FFFFFF;--surface-2:var(--bg-2);
  --card-line:#E3E6EA;--accent:var(--green-ink);--mark:var(--green);--focus:var(--green-ink);color:var(--fg-2);
  --b-muted:var(--bg-3);--b-muted-fg:var(--ink-2);--b-done:var(--green-soft);--b-done-fg:var(--green-deep);
  --b-wait:var(--amber-tint);--b-wait-fg:var(--amber-ink);--b-fail:var(--red-tint);--b-fail-fg:var(--red);
  --b-live:var(--neon);--b-live-fg:var(--ink);--b-type:var(--ink);--b-type-fg:#FFFFFF;--b-line:var(--line-2);
}

/* ---------- 03 Reset + base ---------- */
*,*::before,*::after{box-sizing:border-box}
*{margin:0;padding:0}
html{overflow-x:clip;-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-padding-top:calc(var(--nav-h) + 24px);scroll-behavior:smooth}
body{
  min-height:100vh;background:var(--bg);color:var(--fg-2);
  font-family:var(--font-body);font-size:var(--fs-body);font-weight:400;line-height:1.6;letter-spacing:-.006em;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility;
  overflow-x:clip;
}
img,svg,video,canvas,picture{display:block;max-width:100%}
img,video{height:auto}
svg{overflow:visible}
input,button,textarea,select{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
a{color:inherit;text-decoration:none}
ul[class],ol[class],.site-footer ul,.site-menu ul{list-style:none}
strong,b{font-weight:600;color:var(--fg)}
::selection{background:var(--neon);color:var(--ink)}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px;border-radius:4px}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.skip-link{position:fixed;left:16px;top:-60px;z-index:300;background:var(--neon);color:var(--ink);font:500 15px/1 var(--font-display);padding:12px 16px;border-radius:var(--r-sm);transition:top .2s}
.skip-link:focus{top:12px}
.prose-link,p a:not([class]){color:var(--fg);text-decoration:underline;text-decoration-color:var(--mark);text-decoration-thickness:1.5px;text-underline-offset:3px;transition:text-decoration-color .2s}
.prose-link:hover,p a:not([class]):hover{text-decoration-color:currentColor}

/* ---------- 04 Layout ---------- */
.wrap{width:100%;max-width:calc(var(--wrap) + var(--gutter) * 2);margin-inline:auto;padding-inline:var(--gutter)}
.wrap--narrow{max-width:calc(var(--wrap) * .7334 + var(--gutter) * 2)}   /* 880px at the 1200px container */

.section{position:relative;padding-block:var(--section-y);background:var(--bg)}
.section--tight{padding-block:var(--section-y)}   /* retired (cohesion pass): one rhythm for every section; kept as an alias */
.section--flush-top{padding-top:0}
.section--flush-bottom{padding-bottom:0}
.section--alt{background:var(--bg-2)}
.section--dark{background:var(--night)}
.section--ruled{border-top:1px solid var(--rule)}

/* card grids: --gap-card between cards; a two-up grid uses --gap-cols across (rows keep --gap-card),
   like every other two-column layout, so it lines up with a split section head above it */
.grid{display:grid;gap:var(--grid-gap)}
.grid--2{--grid-gap:var(--gap-card) var(--gap-cols);grid-template-columns:repeat(2,minmax(0,1fr))}
.grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid--4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:1023px){.grid--3,.grid--4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:720px){.grid--2,.grid--3,.grid--4{grid-template-columns:minmax(0,1fr)}}

/* text + visual, side by side; stacks under 960px. Two ratios only: 5:7 (text : visual, the default;
   split--reverse puts the visual on the left and keeps it the wide column) and 1:1 (split--even).
   Top rule (owner, 2026-10-15): both columns start at the top, so the eyebrow's top is level with the
   visual's top in every split on every page. Don't pad or margin the top of either column, and don't
   centre a visual inside a taller wrapper. split--center (opt-in, rare) centres the two columns on each
   other instead; split--top is the old name for the default. The gutter is --gap-cols. */
.split{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:var(--gap-cols);align-items:start}
.split--center{align-items:center}
.split--even{grid-template-columns:repeat(2,minmax(0,1fr))}
.split--wide{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}   /* retired 4:8; now the default 5:7 */
.split--reverse,.split--reverse.split--wide{grid-template-columns:minmax(0,7fr) minmax(0,5fr)}
.split--reverse.split--even{grid-template-columns:repeat(2,minmax(0,1fr))}
.split--reverse>:first-child{order:2}
.split--top{align-items:start}   /* the default now; kept as an alias */
@media (max-width:959px){.split,.split--even,.split--wide,.split--reverse,.split--reverse.split--wide{grid-template-columns:minmax(0,1fr);gap:max(40px,var(--gap-cols))}.split--reverse>:first-child{order:0}}

/* ---------- 05 Type ---------- */
h1,h2,h3,h4,.t-display,.t-h1,.t-h2,.t-h3{font-family:var(--font-display);font-weight:500;color:var(--fg);text-wrap:balance;font-feature-settings:"kern" 1}
/* Section, card and step headings fill their width (owner, 2026-10-15: "sentences should keep going"):
   "pretty" runs each line as far as it can and only keeps a lone word off the last line, where "balance"
   shortens the first line to even the two out and leaves width unused. Only the hero h1 balances. */
h2,h3,h4,.t-h2,.t-h3{text-wrap:pretty}
.t-display{font-size:clamp(42px,5.4vw + 6px,88px);line-height:1.02;letter-spacing:-.035em}
h1,.t-h1{font-size:clamp(38px,4vw + 8px,68px);line-height:1.04;letter-spacing:-.032em}
h2,.t-h2{font-size:var(--fs-h2);line-height:1.08;letter-spacing:-.028em}
h3,.t-h3{font-size:var(--fs-card-title);line-height:1.25;letter-spacing:-.014em}
h4,.t-h4{font-family:var(--font-body);font-size:var(--fs-body);font-weight:600;line-height:1.35;letter-spacing:-.01em}
p,li,dd{text-wrap:pretty}
.lead{font-size:var(--fs-lead);line-height:1.5;color:var(--fg-2);letter-spacing:-.01em;max-width:none}   /* runs the width of its column (owner, 2026-10-15) */
.text-sm,.small{font-size:var(--fs-sm);line-height:1.55}
.text-xs{font-size:var(--fs-xs);line-height:1.5}
.text-fg{color:var(--fg)}
.text-accent{color:var(--accent)}
.tnum{font-feature-settings:"tnum" 1}
.t-keep{white-space:nowrap}   /* keep a phrase on one line where it fits (e.g. the end of a headline) */
@media (min-width:720px){.t-keep-wide{white-space:nowrap}}   /* the same from 720px, for a phrase too long to bind with &nbsp; on a phone */
/* Large screens (1600 → 2560px): every size above is a token, and the tokens grow with the container
   (§02, the 1600px block under :root), so eyebrows, leads, section-head gaps, card and step text scale
   with the h2 whatever the rule order. Section heads and leads run the full width of their column (no ch caps). */

/* kicker / eyebrow — Space Grotesk caps with the deck's green square */
.eyebrow{display:inline-flex;align-items:center;gap:12px;font-family:var(--font-display);font-size:var(--fs-eyebrow);font-weight:500;line-height:1;letter-spacing:.16em;text-transform:uppercase;color:var(--fg-2)}
.eyebrow::before{content:"";flex:none;width:9px;height:9px;background:var(--mark)}
.eyebrow--plain::before{display:none}
.eyebrow--accent{color:var(--accent)}
/* Label rule (owner, 2026-10-15): a label with the green square is always .eyebrow (never a page-built
   copy of it), and an eyebrow directly above a heading is block-level with the one --eyebrow-gap below
   it, in a section head or not, so the dot, the gap to the h2 and the padding are identical in every
   section. Card labels (.card__eyebrow) keep their own, tighter gap. */
:where(.eyebrow):has(+ :is(h1,h2,h3)){display:flex;width:fit-content;margin-bottom:var(--eyebrow-gap)}
@media (max-width:720px){.eyebrow{gap:10px}.eyebrow::before{width:8px;height:8px}}

/* column / group label (no marker) */
.label{font-family:var(--font-display);font-size:var(--fs-label);font-weight:600;line-height:1.2;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3)}

/* section header: eyebrow → h2 → lead, always stacked, on the full container width (owner,
   2026-10-15: no "half and half" heads, no narrow column of text beside empty space, "headlines and
   sub-headings take the full width"). The h2 and the lead both run the full width of the container (or
   of their .split column) and wrap "pretty": each line runs as far as it can, and only a lone last word
   is kept off; they break only when they genuinely run out of room. Keep a phrase together with &nbsp;
   where a break would read oddly (a number and its unit, a product name). Gaps: --eyebrow-gap (eyebrow → h2) and --lead-gap (h2 → lead),
   the same in every section on every page. */
.section-head{max-width:none;margin-bottom:var(--head-gap)}
.section-head h2{max-width:none;text-wrap:pretty}
.split .section-head{margin-bottom:var(--head-gap-tight)}   /* text beside a visual: the list under the head stays close */
.section-head .eyebrow{margin-bottom:var(--eyebrow-gap)}
/* block-level, so the eyebrow's box starts at the very top of its column (an inline eyebrow sits ~9px
   down its line box) and lines up with the visual beside it */
.section-head .eyebrow,.page-hero .eyebrow{display:flex;width:fit-content}
.section-head--center .eyebrow{margin-inline:auto}
.section-head .lead{margin-top:var(--lead-gap);max-width:none;text-wrap:pretty}
.section-head--center{margin-inline:auto;text-align:center}
.section-head--center .lead{margin-inline:auto}
/* section-head--split is retired (owner, 2026-10-15): it now renders as the stacked head above, so old
   markup (eyebrow, h2, then the lead or a div with the lead and a .btn-row) reads eyebrow → h2 → lead.
   Don't use it in new markup. */
.section-head--split{max-width:none}
/* eyebrow + badge on one line (e.g. "Website testing  [New]") */
.section-head__kicker{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-bottom:var(--eyebrow-gap)}
.section-head .section-head__kicker .eyebrow{margin-bottom:0}
/* a link or button under the lead */
.section-head .btn-row{margin-top:28px}
/* no gap below (the head is the whole section, e.g. a closing strip) */
.section-head--flush{margin-bottom:0}

/* number in a circle (legends, stages): Inter + tabular figures, only here */
.num-dot{flex:none;display:inline-grid;place-items:center;width:30px;height:30px;border-radius:50%;background:var(--neon);color:var(--ink);font-family:var(--font-body);font-size:14.5px;font-weight:600;line-height:1;font-feature-settings:"tnum" 1}
.num-dot--ink{background:var(--ink);color:#fff}

/* ---------- 06 Buttons ---------- */
.btn{
  --btn-h:48px;
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;
  height:var(--btn-h);padding:0 22px;border:1px solid transparent;border-radius:10px;
  background:var(--neon);color:var(--ink);
  font-family:var(--font-display);font-size:16px;font-weight:500;line-height:1;letter-spacing:-.005em;white-space:nowrap;
  cursor:pointer;user-select:none;-webkit-tap-highlight-color:transparent;
  transition:background-color .2s var(--ease),border-color .2s var(--ease),color .2s var(--ease),transform .2s var(--ease);
}
.btn:hover{background:#5BFFA6}
.btn:active{transform:translateY(1px)}
/* primary on white needs an edge: neon is nearly as light as the page */
.btn:not(.btn--secondary):not(.btn--ghost):not(.btn--ink){box-shadow:inset 0 0 0 1px rgba(0,150,70,.16)}
.on-dark .btn,.section--dark .btn,.page-hero .btn,.cta-band .btn,.site-menu .btn,.site-nav .btn{box-shadow:none}
.btn--secondary{background:transparent;color:var(--fg);border-color:var(--line-2)}
.btn--secondary:hover{background:rgba(21,21,26,.035);border-color:var(--ink-3)}
.on-dark .btn--secondary,.section--dark .btn--secondary,.page-hero .btn--secondary,.cta-band .btn--secondary,.site-menu .btn--secondary{border-color:rgba(255,255,255,.22)}
.on-dark .btn--secondary:hover,.section--dark .btn--secondary:hover,.page-hero .btn--secondary:hover,.cta-band .btn--secondary:hover,.site-menu .btn--secondary:hover{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.5)}
.btn--ink{background:var(--ink);color:#fff}
.btn--ink:hover{background:#2A2A31}
.btn--ghost{--btn-h:auto;height:auto;min-height:44px;padding:6px 0;background:none;color:var(--fg);border-radius:4px}
.btn--ghost:hover{background:none;color:var(--accent)}
.btn--sm{--btn-h:40px;padding:0 16px;font-size:15px;border-radius:9px}
.btn--lg{--btn-h:56px;padding:0 28px;font-size:17px;border-radius:12px}
.btn--block{display:flex;width:100%}
.btn--arrow::after{
  content:"";flex:none;width:16px;height:16px;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8h10M8.5 3.5 13 8l-4.5 4.5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8h10M8.5 3.5 13 8l-4.5 4.5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  transition:transform .25s var(--ease-out);
}
.btn--arrow:hover::after{transform:translateX(3px)}
.btn-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px 14px}
.btn-row:has(>.btn--ghost+.btn--ghost){column-gap:34px}   /* two text links side by side */
@media (max-width:480px){.btn-row--stack{flex-direction:column;align-items:stretch}.btn-row--stack .btn{width:100%}}

/* ---------- 07 Nav + mobile menu ---------- */
.site-nav{
  --nav-fg:#FFFFFF;--nav-fg-2:rgba(255,255,255,.74);--nav-bg:rgba(14,14,17,0);--nav-line:rgba(255,255,255,0);--logo-mark:var(--neon);--focus:var(--neon);
  position:fixed;inset:0 0 auto;z-index:100;height:var(--nav-h);
  background:var(--nav-bg);border-bottom:1px solid var(--nav-line);color:var(--nav-fg);
  transition:background-color .35s var(--ease),border-color .35s var(--ease),color .35s var(--ease);
}
.site-nav.is-scrolled{--nav-bg:rgba(14,14,17,.82);--nav-line:rgba(255,255,255,.07);-webkit-backdrop-filter:saturate(1.6) blur(18px);backdrop-filter:saturate(1.6) blur(18px)}
.site-nav.is-light{--nav-fg:var(--ink);--nav-fg-2:var(--ink-2);--logo-mark:var(--green);--focus:var(--green-ink)}
.site-nav.is-light.is-scrolled{--nav-bg:rgba(255,255,255,.86);--nav-line:rgba(21,21,26,.08)}
/* without JavaScript the nav can't follow the page's light and dark regions: keep it solid dark, so its white
   text stays legible over any section */
html:not(.js) .site-nav{--nav-bg:rgba(14,14,17,.94);--nav-line:rgba(255,255,255,.07)}
.site-nav__inner{height:100%;display:flex;align-items:center;gap:20px}   /* the last link sits ~36px from Book a demo */
.site-nav__logo{display:flex;align-items:center;flex:none;min-height:44px;color:var(--nav-fg);border-radius:4px}
.logo{display:block;height:22px;width:auto;aspect-ratio:3250/601;overflow:hidden}
/* the nav logo is a size up from the footer's (owner, 2026-10-14): 27px, 25px on phones, growing
   gently to 30px with the container on large screens */
.site-nav__logo .logo{height:clamp(27px,.31vw + 22.5px,30px)}
@media (max-width:480px){.site-nav__logo .logo{height:25px}}

/* top-level items: plain links and dropdown triggers share one look */
.site-nav__links{height:100%;margin-left:auto}
.site-nav__list{display:flex;align-items:center;gap:4px;height:100%}
.site-nav__item{position:relative;display:flex;align-items:center;height:100%}
.site-nav__link,.site-nav__trigger{
  position:relative;display:inline-flex;align-items:center;gap:7px;height:40px;padding:0 13px;border-radius:9px;
  font-family:var(--font-display);font-size:15px;font-weight:500;line-height:1;letter-spacing:-.003em;white-space:nowrap;
  color:var(--nav-fg-2);cursor:pointer;transition:color .2s var(--ease),background-color .2s var(--ease)
}
.site-nav__link:hover,.site-nav__trigger:hover,.site-nav__item.is-open>.site-nav__trigger{color:var(--nav-fg);background:color-mix(in srgb,var(--nav-fg) 7%,transparent)}
.site-nav__link[aria-current="page"],.site-nav__item.is-current>.site-nav__trigger{color:var(--nav-fg)}
/* current page: the green rule under the label (not under the caret) */
.site-nav__link::after,.site-nav__trigger::after{content:"";position:absolute;left:13px;right:var(--rule-r,13px);bottom:3px;height:2px;background:var(--logo-mark);transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease-out)}
.site-nav__trigger{--rule-r:31px}
.site-nav__link[aria-current="page"]::after,.site-nav__item.is-current>.site-nav__trigger::after{transform:scaleX(1)}
.site-nav__caret{flex:none;width:11px;height:11px;margin-right:-2px;opacity:.7;background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  transition:transform .3s var(--ease-out),opacity .2s var(--ease)}
.site-nav__item.is-open .site-nav__caret{transform:rotate(180deg);opacity:1}

/* dropdown panel: always a white card, over the dark hero and on light pages */
.site-nav__panel{
  --focus:var(--green-ink);
  position:absolute;top:calc(100% - 6px);left:50%;z-index:2;
  width:max-content;min-width:320px;max-width:min(440px,calc(100vw - 32px));padding:8px;
  background:#fff;color:var(--ink);border:1px solid rgba(21,21,26,.09);border-radius:16px;box-shadow:var(--shadow-3);
  opacity:0;visibility:hidden;transform:translate(-50%,8px) scale(.985);transform-origin:50% 0;
  transition:opacity .16s var(--ease),transform .24s var(--ease-out),visibility 0s linear .24s;
}
.site-nav__panel::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:16px}   /* hover bridge from the trigger */
.site-nav__item.is-open>.site-nav__panel{opacity:1;visibility:visible;transform:translate(-50%,0);transition:opacity .2s var(--ease),transform .34s var(--ease-out),visibility 0s}
html:not(.js) .site-nav__item:hover>.site-nav__panel,html:not(.js) .site-nav__item:focus-within>.site-nav__panel{opacity:1;visibility:visible;transform:translate(-50%,0)}
.site-nav__menu{display:flex;flex-direction:column;gap:2px}
.site-nav__opt{display:grid;grid-template-columns:38px minmax(0,1fr);align-items:center;gap:1px 14px;padding:10px 16px 10px 10px;border-radius:10px;color:var(--ink);transition:background-color .15s var(--ease)}
.site-nav__opt:hover,.site-nav__opt:focus-visible{background:var(--bg-2)}
.site-nav__opt:focus-visible{outline-offset:-2px}
.site-nav__opt[aria-current="page"]{background:var(--green-tint)}
.site-nav__ico{grid-row:span 2;display:grid;place-items:center;width:38px;height:38px;border-radius:10px;background:var(--bg-2);box-shadow:inset 0 0 0 1px var(--line);transition:background-color .15s var(--ease)}
.site-nav__opt:hover .site-nav__ico,.site-nav__opt:focus-visible .site-nav__ico,.site-nav__opt[aria-current="page"] .site-nav__ico{background:#fff}
.site-nav__ico svg{width:26px;height:26px;fill:none;stroke:var(--ink);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.site-nav__ico svg .ac{stroke:var(--green)}
.site-nav__ico svg .acf{fill:var(--green);stroke:none}
.site-nav__ico svg.is-mark{width:19px;height:19px;stroke:none;--logo-mark:var(--green)}
.site-nav__opt-name{display:flex;align-items:center;gap:8px;font-family:var(--font-display);font-size:15.5px;font-weight:500;line-height:1.3;letter-spacing:-.01em;color:var(--ink)}
.site-nav__opt-text{font-size:13.5px;line-height:1.4;color:var(--ink-2)}

.site-nav__actions{display:flex;align-items:center;gap:8px;margin-left:4px}
.site-nav__toggle{display:none;position:relative;flex:none;width:44px;height:44px;border-radius:10px;color:var(--nav-fg);border:1px solid color-mix(in srgb,var(--nav-fg) 22%,transparent)}
.site-nav__toggle i{position:absolute;left:13px;right:13px;height:1.5px;background:currentColor;border-radius:1px;transition:transform .3s var(--ease-out),top .3s var(--ease-out)}
.site-nav__toggle i:first-of-type{top:17px}
.site-nav__toggle i:last-of-type{top:25px}
.site-nav__toggle[aria-expanded="true"] i:first-of-type{top:21px;transform:rotate(45deg)}
.site-nav__toggle[aria-expanded="true"] i:last-of-type{top:21px;transform:rotate(-45deg)}
@media (min-width:1600px){.site-nav__link,.site-nav__trigger{font-size:clamp(15px,.21vw + 11.6px,17px)}.site-nav__actions .btn--sm{--btn-h:clamp(40px,.42vw + 33.3px,44px);font-size:clamp(15px,.21vw + 11.6px,17px)}}
@media (max-width:1079px) and (min-width:960px){.site-nav__inner{gap:14px}.site-nav__link,.site-nav__trigger{padding:0 10px}.site-nav__link::after,.site-nav__trigger::after{left:10px}.site-nav__link{--rule-r:10px}.site-nav__trigger{--rule-r:28px}}
@media (max-width:959px){
  :root{--nav-h:64px}
  .site-nav__links{display:none}
  .site-nav__actions{margin-left:auto}
  .site-nav__toggle{display:block}
}
/* touch: the header button and the menu toggle are 44px targets; on narrow phones the header keeps its
   right margin (the toggle's edge sits on the gutter), and under 350px the header's Book a demo hides
   (it stays in the menu) */
@media (max-width:959px){.site-nav__actions .btn--sm{--btn-h:44px;border-radius:10px}}
@media (max-width:400px){.site-nav__inner{gap:12px}.site-nav__actions .btn{padding:0 14px}}
@media (max-width:349px){.site-nav__actions .btn{display:none}}
html.menu-open,body.menu-open{overflow:hidden}
body.menu-open .site-nav,body.menu-open .site-nav.is-light,body.menu-open .site-nav.is-light.is-scrolled{--nav-fg:#FFFFFF;--nav-fg-2:rgba(255,255,255,.74);--nav-bg:var(--night);--nav-line:rgba(255,255,255,.07);--logo-mark:var(--neon);--focus:var(--neon)}

/* mobile menu: grouped sections with large tap targets */
.site-menu{
  position:fixed;inset:var(--nav-h) 0 0;z-index:99;background:var(--night);
  display:flex;flex-direction:column;overflow-y:auto;overscroll-behavior:contain;
  opacity:0;visibility:hidden;transform:translateY(-8px);
  transition:opacity .3s var(--ease),transform .4s var(--ease-out),visibility 0s linear .4s;
}
.site-menu.is-open{opacity:1;visibility:visible;transform:none;transition:opacity .3s var(--ease),transform .4s var(--ease-out),visibility 0s}
.site-menu__inner{display:flex;flex-direction:column;min-height:100%}
.site-menu__nav{display:flex;flex-direction:column;gap:22px;padding-top:18px}
.site-menu__label{margin-bottom:4px;font-family:var(--font-display);font-size:12px;font-weight:600;line-height:1.2;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-2)}
.site-menu__item{position:relative;display:flex;flex-direction:column;justify-content:center;gap:2px;min-height:56px;padding:10px 40px 10px 0;border-bottom:1px solid var(--rule);color:var(--fg)}
.site-menu__item strong{font-family:var(--font-display);font-size:18px;font-weight:500;line-height:1.25;letter-spacing:-.016em;color:var(--fg)}
.site-menu__item span{font-size:14.5px;line-height:1.4;color:var(--fg-2)}
.site-menu__item[aria-current="page"] strong{color:var(--neon)}
.site-menu__item::after{content:"";position:absolute;right:2px;top:50%;width:18px;height:18px;margin-top:-9px;background:var(--fg-3);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8h10M8.5 3.5 13 8l-4.5 4.5' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8h10M8.5 3.5 13 8l-4.5 4.5' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat}
.site-menu__item:active{background:rgba(255,255,255,.03)}
.site-menu__foot{margin-top:auto;padding:24px 0 calc(20px + env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:14px}
.site-menu__foot p{font-size:15px;color:var(--fg-2)}
.site-menu__foot a:not(.btn){color:var(--fg)}
@media (min-width:960px){.site-menu{display:none}}

/* ---------- 08 Page hero (dark bookend) ---------- */
/* One hero shell for every page (owner, 2026-10-14): the dark hero fills the first screen, the copy
   sits on the left and a box on the right, inside the container, holds the page's visual (home: the
   hero-scale figure; OddsForge: the app window; Agent Testing: the lobby wall; iGaming Agents: the team
   table; Company: the mark; AI Platform and 404: the live field).
   Anchor rule (owner, 2026-10-15): the hero is never centred on its own copy. The copy block starts at
   one fixed offset below the nav, --hero-pt, which depends only on the screen's size, so the eyebrow
   sits at exactly the same y on every page at every viewport and moving between pages is seamless.
   The visual box starts at the same y (its top is level with the eyebrow's top) and is the same height
   on every page, --hero-aside-h (it only grows if a page's copy is taller). On desktop both are tuned
   so the tallest copy (iGaming Agents, Agent Testing) sits as the old centred layout placed it, with
   about 44% of the free height above and 56% below: eyebrow at about y 142 at 1280×720, 195 at
   1440×900, 249 at 1920×1080 and 355 at 2560×1440. A shorter copy (Company, 404) just ends higher.
   Fold rule: on every desktop screen from 1280×720 up, the trust line (.page-hero__meta) sits fully
   above the fold. Never add a page-level padding, margin or flex spacer that moves the copy. */
.page-hero{
  --hero-pt:56px;--hero-pb:56px;
  --hero-gap:48px;--hero-aside-w:100%;--hero-aside-h:340px;--live-h:var(--hero-aside-h);
  position:relative;overflow:hidden;background:var(--night);min-height:100svh;display:flex;flex-direction:column;
  padding-top:calc(var(--nav-h) + var(--hero-pt));padding-bottom:var(--hero-pb)}
@media (min-width:721px){.page-hero{--hero-pt:clamp(48px,13vh - 36px,104px);--hero-pb:clamp(40px,8vh,96px)}}
/* the split (share of the two columns, after the gap): 55 copy / 45 visual from 960px, an even
   50 / 50 from 1280px (the copy column sets the headline's size, see .page-hero__title).
   Desktop anchor: --hero-pt grows with the screen's height (70px below the nav at 720px tall, 123 at
   900, 177 at 1080, 283 at 1440); the box is 32vh + 275px (505px at 720 tall, 563 at 900, 621 at
   1080, 736 at 1440). */
@media (min-width:960px){.page-hero{--hero-pt:clamp(40px,29.6vh - 143px,300px);--hero-gap:clamp(40px,4vw,64px);--hero-aside-w:calc((100% - var(--hero-gap)) * .45);--hero-aside-h:clamp(420px,32vh + 275px,920px)}}
@media (min-width:1280px){.page-hero{--hero-aside-w:calc((100% - var(--hero-gap)) * .5)}}
.page-hero .wrap{position:relative;z-index:1}

.page-hero__content{max-width:880px}
.page-hero .eyebrow{margin-bottom:clamp(18px,3vh,28px)}
.page-hero__title{color:var(--fg);font-size:clamp(40px,min(4.4vw + 10px,8.6vh),72px);line-height:1.02;letter-spacing:-.035em}
/* desktop: the headline never outgrows its column (9.4% of the copy column's width), so each page's
   headline keeps the same number of lines at every desktop size instead of gaining a short extra
   line at 1440 or 2560 */
@media (min-width:960px){
  .page-hero__content{container-type:inline-size}
  .page-hero__title{font-size:min(clamp(40px,min(4.4vw + 10px,8.6vh),72px),9.4cqi)}
}
.page-hero__lead{margin-top:clamp(18px,3vh,28px);max-width:56ch;font-size:clamp(18px,.5vw + 14px,21px);line-height:1.55;color:var(--fg-2);text-wrap:balance}
.page-hero .btn-row{margin-top:clamp(26px,4.4vh,40px)}
.page-hero__meta{margin-top:clamp(36px,min(7vw,7.4vh),96px);display:flex;flex-wrap:wrap;align-items:baseline;gap:12px 32px;font-family:var(--font-display);font-size:13px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--fg-3)}
@media (max-width:720px){.page-hero .eyebrow{margin-bottom:28px}.page-hero__lead{margin-top:24px}.page-hero .btn-row{margin-top:36px}.page-hero__meta{margin-top:48px}}
.page-hero__meta a{display:inline-flex;align-items:center;min-height:44px;color:var(--fg-2);text-decoration:underline;text-decoration-color:rgba(34,255,134,.55);text-decoration-thickness:1.5px;text-underline-offset:5px;transition:color .2s var(--ease),text-decoration-color .2s var(--ease)}
.page-hero__meta a:hover{color:var(--fg);text-decoration-color:var(--neon)}
@media (max-width:720px){
  .page-hero__meta{flex-direction:column;align-items:flex-start;gap:14px}
  .page-hero .btn-row{display:grid;grid-template-columns:minmax(0,max-content)}   /* stacked buttons share one width */
}
/* short screens (small phones, landscape phones): a tighter hero, so the buttons and the trust line stay on
   the first screen */
@media (max-width:400px){.page-hero__title{font-size:clamp(30px,9.4vw,40px)}}
@media (max-height:450px),(max-width:720px) and (max-height:760px),(max-width:360px){
  .page-hero{--hero-pt:28px}
  .page-hero .eyebrow{margin-bottom:16px}
  .page-hero__title{font-size:clamp(30px,min(9.4vw,8.6vh + 4px),40px)}
  .page-hero__lead{margin-top:14px;font-size:17px;line-height:1.5}
  .page-hero .btn-row{margin-top:22px}
  .page-hero .btn--lg{--btn-h:50px}
  .page-hero__meta{margin-top:26px}
}
/* landscape phones and the smallest phones: tighter still */
@media (max-height:450px),(max-width:720px) and (max-height:600px){
  .page-hero{--hero-pt:18px}
  .page-hero .eyebrow{margin-bottom:12px}
  .page-hero__lead{margin-top:10px}
  .page-hero .btn-row{margin-top:16px}
  .page-hero .btn--lg{--btn-h:46px}
  .page-hero__meta{margin-top:18px}
}

/* copy on the left, the visual box on the right (owner, 2026-10-15). The box sits inside the
   container: its right edge is the container's right edge (the same edge as the nav's Book a demo and
   the footer), and nothing in it runs on into the page margin. Desktop: the box is --hero-aside-w wide
   (45% of the width after the gap, an even 50% from 1280px), its top level with the eyebrow's top
   and --hero-aside-h tall on every page (the anchor rule above). Every visual is centred in its box
   and fades softly at the box's edges (no hard box edge, no crop). Under 960px the box moves below
   the trust line and is --hero-aside-h tall. */
.page-hero__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,var(--hero-aside-w));gap:var(--hero-gap);align-items:start}
.page-hero .page-hero__grid .page-hero__content{max-width:none}
.page-hero__aside{position:relative;min-width:0;height:var(--hero-aside-h)}
/* desktop: the box's top is the eyebrow's top; it is --hero-aside-h tall on every page and only grows
   if the copy beside it is taller (it never overhangs the copy above or below) */
@media (min-width:960px){
  .page-hero .page-hero__aside{align-self:stretch;height:auto;min-height:var(--hero-aside-h);margin-block:0}
}
@media (max-width:959px){
  .page-hero__grid{grid-template-columns:minmax(0,1fr)}
  .page-hero .page-hero__grid .page-hero__content{max-width:640px}
  .page-hero__aside{width:100%;max-width:none}   /* under the copy, the box spans the container (no lopsided gap on tablets) */
  /* under the copy the decorative boxes go: the bare field (no figure in it) and the home page's drawing. The
     heroes that lose their box (home, platform) drop the full-screen height and end on the same space the next
     section opens with, so the copy sits evenly between the nav and the section below */
  .page-hero__aside[data-live="field"]:not(:has([data-figure])),.pg-home .page-hero__aside{display:none}
  .pg-home .page-hero,.pg-platform .page-hero{min-height:0;padding-bottom:var(--section-y)}
}

/* Large screens (1600px and up): the hero grows with the container instead of floating small in
   the middle: the headline, lead, buttons, trust line and the box all scale with the viewport. */
@media (min-width:1600px){
  .page-hero{--hero-gap:clamp(64px,3.33vw + 10.7px,96px)}   /* --hero-pt and the box height stay on the anchor rule above */
  .page-hero .eyebrow{font-size:clamp(13px,.21vw + 9.6px,15px);margin-bottom:clamp(28px,1.25vw + 8px,40px)}
  .page-hero .page-hero__title{font-size:min(clamp(40px,min(2.917vw + 25.3px,8.6vh),100px),9.4cqi)}
  .page-hero .page-hero__lead{margin-top:clamp(28px,1.25vw + 8px,40px);font-size:clamp(21px,.625vw + 11px,27px)}
  .page-hero .btn-row{margin-top:clamp(40px,1.67vw + 13.3px,56px);gap:clamp(12px,.42vw + 5.3px,16px)}
  .page-hero .btn--lg{--btn-h:clamp(56px,1.25vw + 36px,68px);padding:0 clamp(28px,.625vw + 18px,34px);font-size:clamp(17px,.3125vw + 12px,20px);border-radius:clamp(12px,.21vw + 8.7px,14px)}
  .page-hero__meta{margin-top:clamp(64px,min(4vw,7.4vh),104px);font-size:clamp(13px,.21vw + 9.6px,15px);column-gap:clamp(32px,1.25vw + 12px,44px)}
  .page-hero__meta .aws-mark{--aws-w:clamp(38px,.625vw + 28px,44px);font-size:clamp(12px,.21vw + 8.6px,14px)}
}

/* brand particle field (+ / | ■) — rendered by site.js into <svg data-field> */
.brand-field{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0;opacity:0;transition:opacity 1.4s var(--ease)}
.brand-field.is-drawn{opacity:1}
@media (max-width:720px){.brand-field.is-drawn{opacity:.4}}

/* "Powered by AWS" mark (owner, 2026-10-15: NanoLeap holds no AWS programme status; never claim one).
   It reads "Powered by", then the AWS logo, which reads as the word "AWS" (a screen reader hears
   "Powered by AWS" from the sr-only text). Inline, the logo's letters sit on the words' baseline: the
   letters end 52% of the way down the logo and the smile hangs below like a descender (vertical-align
   lowers the logo by the 48% under its letters, 0.289 × its width). The logo's letters follow the context:
   near-white on dark, AWS ink on light; the smile stays AWS orange. Size the logo with --aws-w.
   aws-mark--lg is the prominent version for a card (the home page's trust card): the words as a small caps
   label above the left edge of a larger logo, so it still reads "Powered by AWS". Markup: COMPONENTS.md §4. */
.aws-mark{--aws-w:38px;display:inline-block;color:var(--fg-3);font-family:var(--font-display);font-size:12px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;line-height:1;white-space:nowrap}
.aws-mark svg{display:inline-block;width:var(--aws-w);height:auto;aspect-ratio:304/182;margin-left:.9em;vertical-align:calc(var(--aws-w) * -.289);color:#232F3E}
:is(.on-dark,.section--dark,.page-hero,.cta-band,.site-footer,.site-menu) .aws-mark svg{color:#EDEDED}
.on-light .aws-mark svg{color:#232F3E}
.aws-mark--lg{--aws-w:clamp(112px,2.5vw + 92px,136px);display:inline-flex;flex-direction:column;align-items:flex-start;gap:12px;font-size:calc(14 * var(--ramp));letter-spacing:.16em;color:var(--fg-2)}
.aws-mark--lg svg{margin-left:calc(var(--aws-w) * -.046);vertical-align:top}   /* the label lines up with the "a" */

/* ---------- 09 Cards + chips ---------- */
/* Elevation rule (cohesion pass, 2026-10-15): content cards are flat (a hairline, no shadow). Only a
   card you can click is raised: a.card / .card--link with card--raised gets the soft shadow, and every
   clickable card lifts on hover (a darker edge and a soft shadow). card--raised on a static card (a div, li or article) is
   ignored. Product windows (.screen, .flow__screen) keep their floating shadow: they are pictures of
   software, not cards. */
.card{--card-pad:var(--pad-card);position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--card-line);border-radius:var(--r-lg);padding:var(--card-pad)}
:is(a.card,.card--link).card--raised{box-shadow:var(--shadow-2)}
.card--muted{background:var(--surface-2);border-color:transparent}
.card--accent{border-top:0;padding-top:calc(var(--card-pad) + 1px)}
.card--accent::before{content:"";position:absolute;left:-1px;right:-1px;top:0;height:3px;border-radius:var(--r-lg) var(--r-lg) 0 0;background:var(--green)}
.card__eyebrow{margin-bottom:18px}
/* Card text rule (owner, 2026-10-15): text in a card runs the card's full width. No max-width on a
   card's title, text or list (shared or page CSS), and titles wrap "pretty" (fill each line, no lone
   last word) rather than "balance" (which breaks early and leaves a short, ragged block). */
.card__title{font-family:var(--font-display);font-size:var(--fs-card-title);font-weight:500;line-height:1.25;letter-spacing:-.014em;color:var(--fg);text-wrap:pretty}
.card__text{margin-top:10px;max-width:none;font-size:var(--fs-card);line-height:1.55;color:var(--fg-2)}
.card__list{margin-top:18px;display:flex;flex-direction:column;gap:8px}
.card__list li{position:relative;padding-left:20px;font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2)}
.card__list li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:7px;background:var(--mark)}
.card__foot{margin-top:auto;padding-top:24px}
.card__foot--ruled{margin-top:28px;padding-top:18px;border-top:1px solid var(--rule)}
:is(a.card,.card--link){cursor:pointer;transition:border-color .25s var(--ease),box-shadow .3s var(--ease)}
:is(a.card,.card--link):hover{border-color:var(--ink-4);box-shadow:var(--shadow-2)}   /* the lift: a darker edge and a soft shadow */
:is(a.card,.card--link).card--raised:hover{box-shadow:var(--shadow-3)}
:is(.on-dark,.section--dark) :is(a.card,.card--link):hover{border-color:rgba(255,255,255,.22);box-shadow:none}
:is(a.card,.card--link) .btn--ghost{pointer-events:none}
:is(a.card,.card--link):hover .btn--arrow::after{transform:translateX(3px)}

/* Status badges: one language on every page and in every mock (cohesion pass, 2026-10-15).
   10.5px Space Grotesk 700 caps, 20px tall, radius 5. Pick the variant by meaning:
     badge--done   Done · Approved · Pass · Published · Live on site     (green)
     badge--wait   Waiting · In review · Queued · Needs approval        (amber)
     badge--fail   Fail · Blocked · Over limit                          (red tint)
     badge--live   Live · New · Running now (one per view, like neon)   (neon)
     badge--type   a product or content type: Bet builder, Price boost  (ink)
     badge (none) / badge--muted   neutral metadata: Lobby, VIP, Draft  (grey)
   They switch to their dark versions inside any dark context (.on-dark, dark sections, hero, CTA band)
   and back with .on-light. badge--dot adds a status dot; badge--sm (18px) is for dense mock tiles only.
   Legacy names still work: badge--green = done, badge--neon = live, badge--ink = type. */
.badge{display:inline-flex;align-items:center;gap:6px;height:calc(20 * var(--ramp));padding:0 7px;border-radius:var(--r-xs);background:var(--b-muted);color:var(--b-muted-fg);font-family:var(--font-display);font-size:var(--fs-badge);font-weight:700;line-height:1;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;vertical-align:middle}
.badge--muted{background:var(--b-muted);color:var(--b-muted-fg)}
.badge--done,.badge--green{background:var(--b-done);color:var(--b-done-fg)}
.badge--wait{background:var(--b-wait);color:var(--b-wait-fg)}
.badge--fail{background:var(--b-fail);color:var(--b-fail-fg)}
.badge--live,.badge--neon{background:var(--b-live);color:var(--b-live-fg)}
.badge--type,.badge--ink{background:var(--b-type);color:var(--b-type-fg)}
.badge--outline{background:transparent;box-shadow:inset 0 0 0 1px var(--b-line);color:var(--b-muted-fg)}
.badge--dot::before{content:"";flex:none;width:6px;height:6px;margin-left:-1px;border-radius:50%;background:currentColor}
.badge--sm{height:18px;padding:0 6px;gap:5px;font-size:9.5px;letter-spacing:.09em}
.badge--sm.badge--dot::before{width:5px;height:5px}

/* small bullet list with the deck's green squares */
.ticks{display:flex;flex-direction:column;gap:10px}
.ticks li{position:relative;padding-left:22px;line-height:1.5}
.ticks li::before{content:"";position:absolute;left:0;top:.6em;width:8px;height:8px;background:var(--mark)}
.ticks b,.ticks strong{color:var(--fg)}

/* ---------- 10 Comparison pair (before / after) ---------- */
/* Desktop (960px up): the pair is one grid and each card a subgrid of its rows, so the heads, every
   row and the footers line up across both cards at every width, whatever wraps. Each card spans
   --compare-span rows (24: a head, up to 22 rows, a foot); unused rows are empty and take no height.
   The head is row 1, .compare__rows (itself a subgrid) or .compare__body fills the middle, and the
   foot is the last row. compare--inline keeps its cards as size containers instead (its one-line
   rows already line up, and its rows and page CSS query the card's width; a size container can't be
   a subgrid). Under 960px the cards stack and lay out on their own. */
.compare{--compare-span:24;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 var(--gap-cols);align-items:stretch}
@media (max-width:959px){.compare{grid-template-columns:minmax(0,1fr);row-gap:var(--gap-card)}}
.compare__card{position:relative;display:flex;flex-direction:column;border-radius:var(--r-xl);overflow:hidden;background:#fff;border:1px solid #DDE1E6;color:var(--ink-2)}
@supports (grid-template-rows:subgrid){
  @media (min-width:960px){
    .compare:not(.compare--inline)>.compare__card{container-type:normal;display:grid;grid-row:span var(--compare-span);grid-template-rows:subgrid;grid-template-columns:minmax(0,1fr)}
    .compare:not(.compare--inline)>.compare__card>.compare__head{grid-row:1}
    .compare:not(.compare--inline)>.compare__card>.compare__rows{grid-row:2 / -2;display:grid;grid-template-rows:subgrid}
    .compare:not(.compare--inline)>.compare__card>.compare__body{grid-row:2 / -2}
    .compare:not(.compare--inline)>.compare__card>.compare__foot{grid-row:-2 / -1}
  }
}
.compare__card--before{background:var(--bg-2);border-color:#E6E8EC}
.compare__card--after::before{content:"";position:absolute;inset:0 0 auto;height:4px;background:var(--green);z-index:1}   /* flat, like every content card: the green rule marks it */
.compare__head{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:6px 16px;padding:22px 24px 18px;border-bottom:1px solid var(--line)}
.compare__title{display:flex;align-items:center;gap:10px;font-family:var(--font-display);font-size:var(--fs-card-title);font-weight:600;line-height:1.2;letter-spacing:-.012em;color:var(--ink)}
.compare__title::before{content:"";width:11px;height:11px;border-radius:2px;background:var(--ink)}
.compare__card--after .compare__title::before{background:var(--green)}
.compare__meta{font-size:var(--fs-xs);color:var(--ink-2)}
.compare__body{flex:1;display:flex;flex-direction:column}
.compare__rows{display:flex;flex-direction:column}
.compare__row{display:flex;flex-direction:column;justify-content:center;gap:7px;min-height:52px;padding:12px 24px;border-top:1px solid var(--line);font-size:var(--fs-sm);line-height:1.35}
.compare__row:first-child{border-top:0}
.compare__row-label{font-size:var(--fs-xs);color:var(--ink-2)}
@media (max-width:720px){.compare__row-label b{font-size:var(--fs-sm)}}
/* one-line rows when the content is short (label | value). Every row shares one label column,
   so the values line up row to row; set --compare-label on .compare to change its width.
   When a card gets too narrow for one line, rows fall back to the two-line layout. */
.compare__card{container-type:inline-size}
.compare--inline .compare__row{display:grid;grid-template-columns:var(--compare-label,10.5rem) minmax(0,1fr);align-items:center;gap:6px 20px}
.compare--inline .compare__row-label{font-size:var(--fs-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@container (max-width:520px){
  .compare--inline .compare__row{display:flex;flex-direction:column;align-items:stretch;justify-content:center;gap:7px}
  .compare--inline .compare__row-label{font-size:var(--fs-xs)}
  /* both cards are the same width, so both heads stack together and stay the same height */
  .compare--inline .compare__head{flex-direction:column;align-items:flex-start;gap:4px}
}
.compare__card>.compare__foot{flex-grow:1}   /* inline or stacked cards: the foot fills down to the card's bottom edge, so both feet start level */
.compare__row-label b{font-weight:500;color:var(--ink)}
.compare__row-value{display:flex;align-items:center;gap:10px;min-width:0;min-height:32px;color:var(--ink)}
.compare__row-value .grow{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.compare__gap{flex:1;display:flex;align-items:center;height:32px;padding:0 12px;border:1.5px dashed #C3C8CF;border-radius:7px;font-size:var(--fs-xs);color:#6E747F;white-space:nowrap}
.compare__gap--sm{flex:none;height:26px;padding:0 9px;font-size:var(--fs-label);border-radius:6px}   /* compact: inside tiles, or a short row */
.compare__price{flex:none;margin-left:auto;min-width:46px;padding:4px 8px;border-radius:7px;background:var(--ink);color:#fff;font-family:var(--font-display);font-size:14px;font-weight:600;text-align:center;font-feature-settings:"tnum" 1}
.compare__card--after .compare__price{background:var(--neon);color:var(--ink)}
.compare__foot{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 14px;padding:18px 24px 20px;border-top:1px solid var(--line);background:var(--bg-3)}
.compare__card--after .compare__foot{background:var(--green-tint);border-top-color:var(--green-line)}
.compare__stat{font-family:var(--font-display);font-size:clamp(28px,2.4vw,36px);font-weight:600;line-height:1;letter-spacing:-.03em;color:var(--ink)}
.compare__card--after .compare__stat{color:var(--green-ink)}
.compare__foot-label{font-size:var(--fs-sm);color:var(--ink-2)}
@media (max-width:560px){
  .compare__row,.compare--inline .compare__row{padding:12px 18px}
  .compare--inline .compare__row{grid-template-columns:minmax(0,1fr)}
  .compare__head,.compare__foot{padding-inline:18px}
}

/* ---------- 11 Flow diagram (in → stages → out) ---------- */
.flow{--flow-gap:clamp(48px,6vw,96px);position:relative;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.2fr) minmax(0,1fr);gap:var(--flow-gap);align-items:center}
.flow__col,.flow__core{position:relative;z-index:1;min-width:0}
.flow__col .label,.flow__core .label{display:block;margin-bottom:16px}
.flow__core .label{text-align:center}
/* desktop: the three column labels share one baseline row; items and screen centre on each other below it */
@media (min-width:960px){
  .flow{grid-template-rows:auto auto auto;row-gap:0;align-items:start}
  .flow__col,.flow__core{display:grid;grid-row:1/span 3;grid-template-rows:subgrid}
  .flow__col>.label,.flow__core>.label{grid-row:1;align-self:end}
  .flow__col>.flow__items{grid-row:2;align-self:center}
  .flow__core>.flow__screen{grid-row:2;align-self:center}
  .flow__core>.flow__caption{grid-row:3}
}
.flow__items{display:flex;flex-direction:column;gap:10px}
.flow__item{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:2px 14px;padding:13px 16px;background:var(--surface);border:1px solid #E1E4E9;border-radius:var(--r-md);box-shadow:var(--shadow-1)}
.flow__item>b{font-family:var(--font-body);font-size:13px;font-weight:600;color:var(--accent);font-feature-settings:"tnum" 1}
.flow__item strong{display:block;font-size:var(--fs-sm);font-weight:600;line-height:1.3;color:var(--fg)}
.flow__item span:not(.badge){display:block;font-size:var(--fs-xs);line-height:1.4;color:var(--fg-2)}
.flow__item--out{grid-template-columns:minmax(0,1fr)}
.flow__item--out .badge{margin-bottom:6px;justify-self:start}
.flow__screen{position:relative;background:#fff;border:1px solid #DFE2E7;border-radius:var(--r-lg);box-shadow:var(--shadow-3);overflow:hidden}
.flow__stages{position:relative;display:flex;flex-direction:column;padding:14px 18px 18px}
.flow__stages::before{content:"";position:absolute;left:calc(18px + 12px + 17px);top:40px;bottom:40px;width:2px;background:var(--green);transform-origin:top;transition:transform 1.2s var(--ease-out)}
html.js .flow:not(.is-in) .flow__stages::before{transform:scaleY(0)}
.flow__stage{position:relative;display:grid;grid-template-columns:36px minmax(0,1fr);align-items:center;gap:0 16px;padding:10px 12px;border-radius:var(--r-md);transition:background-color .5s var(--ease)}
.flow__stage>b{position:relative;z-index:1;grid-row:span 2;width:36px;height:36px;border-radius:50%;display:grid;place-items:center;background:var(--ink);color:#fff;font-family:var(--font-body);font-size:15px;font-weight:600;font-feature-settings:"tnum" 1;box-shadow:0 0 0 4px #fff;transition:background-color .5s var(--ease),color .5s var(--ease),box-shadow .5s var(--ease)}
.flow__stage strong{display:block;font-size:var(--fs-card);font-weight:600;line-height:1.3;color:var(--ink)}
.flow__stage span:not(.badge){display:block;font-size:var(--fs-xs);line-height:1.4;color:var(--ink-2)}
.flow__stage.is-active{background:var(--green-tint)}
.flow__stage.is-active>b{background:var(--neon);color:var(--ink);box-shadow:0 0 0 4px var(--green-tint),0 0 0 5.5px rgba(0,222,100,.45)}
.flow__caption{margin-top:18px;text-align:center;font-size:var(--fs-sm);color:var(--fg-2)}
.flow__wires{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:0;overflow:visible}
.flow__wires path{fill:none;stroke:var(--green);stroke-width:1.5;stroke-linecap:round}
.flow__wires circle{fill:var(--green);stroke:var(--bg);stroke-width:2.5}
.section--alt .flow__wires circle{stroke:var(--bg-2)}
@media (max-width:959px){
  .flow{grid-template-columns:minmax(0,1fr);gap:56px}
  .flow__wires{display:none}
  .flow__core::before,.flow__col--out::before{content:"";position:absolute;left:50%;top:-44px;width:2px;height:32px;background:var(--green);transform:translateX(-1px)}
  .flow__core::after,.flow__col--out::after{content:"";position:absolute;left:50%;top:-20px;width:8px;height:8px;border-right:2px solid var(--green);border-bottom:2px solid var(--green);transform:translate(-4.5px,0) rotate(45deg)}
}

/* ---------- 12 Pins + legend ---------- */
.pinned{position:relative}
.screen .pin,.pinned .pin{
  position:absolute;left:var(--x,50%);top:var(--y,50%);z-index:3;
  width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;
  display:grid;place-items:center;background:var(--neon);color:var(--ink);
  font-family:var(--font-body);font-size:14.5px;font-weight:600;line-height:1;font-feature-settings:"tnum" 1;
  box-shadow:0 0 0 4px #fff;
  transition:transform .5s var(--ease-out),opacity .5s var(--ease);
}
.screen .pin::after,.pinned .pin::after{content:"";position:absolute;inset:-11px;border-radius:50%;border:1.5px solid rgba(0,222,100,.5);transition:transform .4s var(--ease-out),border-color .3s}
.pin.pin--plain::after{display:none}
.pin.is-hot::after{transform:scale(1.18);border-color:rgba(0,222,100,.9)}
html.js [data-pins] .pin{opacity:0;transform:scale(.6)}
html.js [data-pins].is-in .pin{opacity:1;transform:none;transition-delay:calc(var(--i,0) * 110ms + 250ms)}
@media (max-width:720px){.screen .pin,.pinned .pin{width:24px;height:24px;margin:-12px 0 0 -12px;font-size:12.5px;box-shadow:0 0 0 3px #fff}.screen .pin::after,.pinned .pin::after{inset:-8px}}

ol.legend,ul.legend{counter-reset:legend;display:flex;flex-direction:column;gap:20px}
.legend>li{counter-increment:legend;position:relative;display:grid;grid-template-columns:30px minmax(0,1fr);gap:3px 16px;align-items:start}
.legend>li::before{content:counter(legend);grid-row:span 2;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;background:var(--neon);color:var(--ink);font-family:var(--font-body);font-size:14.5px;font-weight:600;font-feature-settings:"tnum" 1;transition:box-shadow .3s var(--ease)}
.legend>li.is-hot::before{box-shadow:0 0 0 4px rgba(34,255,134,.28)}
.legend>li strong{display:block;font-size:var(--fs-body);font-weight:600;line-height:30px;letter-spacing:-.01em;color:var(--fg)}
.legend>li span:not(.badge){display:block;font-size:var(--fs-sm);line-height:1.45;color:var(--fg-2)}
ol.legend--compact,ul.legend--compact{gap:14px}
.legend--compact>li strong{font-size:var(--fs-card)}
/* legend as a row of columns under a full-width screen (4 across, 2 under 960px, 1 under 560px) */
ol.legend--row,ul.legend--row{display:grid;grid-template-columns:repeat(var(--cols,4),minmax(0,1fr));gap:28px var(--gap-card);margin-top:clamp(32px,4vw,48px)}
@media (max-width:959px){ol.legend--row,ul.legend--row{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){ol.legend--row,ul.legend--row{grid-template-columns:minmax(0,1fr);gap:18px}}

/* ---------- 13 Stat row ---------- */
.stat-row{display:grid;grid-template-columns:repeat(var(--cols,4),minmax(0,1fr));gap:32px var(--gap-card)}
.stat-row__item{padding-top:22px;border-top:1px solid var(--rule)}
.stat-row__value{display:block;font-family:var(--font-display);font-size:clamp(40px,3.4vw + 4px,60px);font-weight:500;line-height:1;letter-spacing:-.035em;color:var(--fg);font-feature-settings:"tnum" 1;white-space:nowrap}
.stat-row__value small{font-size:.45em;font-weight:500;letter-spacing:-.01em;margin-left:.12em;color:var(--fg-2)}
.stat-row__label{display:block;margin-top:14px;font-size:var(--fs-sm);line-height:1.45;color:var(--fg-2)}
@media (max-width:959px){.stat-row{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:480px){.stat-row{grid-template-columns:minmax(0,1fr)}}
/* large screens: card, legend, stat-row and step text read the type tokens, which grow with the
   container from 1600px (§02) */

/* ---------- 13b Steps (timelines, getting started, delivery plans) ---------- */
/* <ol class="steps"> of .steps__item: a 30px .num-dot, a hairline connector to the next dot, then an
   optional .steps__meta (a badge or a label), the .steps__title, the .steps__text and an optional
   .steps__list. In a row from 960px (equal columns, --gap-card apart, as many as there are items),
   a vertical timeline below. steps--accent makes the connectors green; on a list with data-reveal
   they draw in, one after the other, when it reveals.
   Full-width rule (owner, 2026-10-15): the row spans the whole container. The last step's connector
   runs on to the container's right edge and ends in the green square, so the row never stops short
   at the last dot, and step text fills its column (no narrow measure). */
.steps{--steps-gap:var(--gap-card);--steps-line:var(--line-2);display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--steps-gap)}
.on-dark .steps,.section--dark .steps{--steps-line:rgba(255,255,255,.16)}
.steps--accent{--steps-line:var(--green)}
.steps__item{position:relative;display:flex;flex-direction:column;align-items:flex-start;min-width:0}
.steps__item>.num-dot{margin-bottom:22px}
.steps__item::after{content:"";position:absolute;top:14.5px;left:44px;right:calc(14px - var(--steps-gap));height:1px;background:var(--steps-line);transform-origin:left;transition:transform .9s var(--ease-out);transition-delay:calc(var(--i,0) * 220ms + 200ms)}
.steps__item:last-child::after{right:12px}
.steps__item:last-child::before{content:"";position:absolute;top:11px;right:0;width:8px;height:8px;background:var(--mark);transition:opacity .4s var(--ease);transition-delay:calc(var(--i,0) * 220ms + 950ms)}
.steps__item:nth-child(2){--i:1}.steps__item:nth-child(3){--i:2}.steps__item:nth-child(4){--i:3}.steps__item:nth-child(5){--i:4}.steps__item:nth-child(6){--i:5}
html.js .steps[data-reveal]:not(.is-in) .steps__item::after{transform:scaleX(0)}
html.js .steps[data-reveal]:not(.is-in) .steps__item:last-child::before{opacity:0}
.steps__meta{margin-bottom:12px}
.steps__meta.label{color:var(--accent)}
.steps__title{font-family:var(--font-display);font-size:var(--fs-card-title);font-weight:500;line-height:1.25;letter-spacing:-.014em;color:var(--fg);text-wrap:pretty}
.steps__text{margin-top:10px;font-size:var(--fs-card);line-height:1.55;color:var(--fg-2)}
.steps__list{margin-top:18px;padding-top:16px;border-top:1px solid var(--rule);display:flex;flex-direction:column;gap:8px;align-self:stretch}
.steps__list li{position:relative;padding-left:20px;font-size:var(--fs-sm);line-height:1.5;color:var(--fg-2)}
.steps__list li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:7px;background:var(--mark)}
@media (max-width:959px){
  .steps{--steps-gap:32px;grid-auto-flow:row;grid-auto-columns:auto;grid-template-columns:minmax(0,1fr)}
  .steps__item{display:grid;grid-template-columns:30px minmax(0,1fr);column-gap:18px;align-items:start;justify-items:start}
  .steps__item>.num-dot{grid-row:1 / span 6;margin:0}
  .steps__item>:not(.num-dot){grid-column:2}
  .steps__item>.num-dot+.steps__title{margin-top:2px}
  .steps__item>.num-dot+.steps__meta{margin-top:6px}
  .steps__item::after{top:38px;bottom:calc(8px - var(--steps-gap));left:14.5px;right:auto;width:1px;height:auto;transform-origin:top}
  .steps__item:last-child::after,.steps__item:last-child::before{display:none}   /* a vertical timeline ends at its last step */
  html.js .steps[data-reveal]:not(.is-in) .steps__item::after{transform:scaleY(0)}
  .steps__list{justify-self:stretch}
}
/* steps--vertical: the timeline layout (top to bottom, dot on the left) at every width, for steps
   read beside copy (e.g. iGaming Agents' bespoke agents). It never gets the row's end square.
   (.ag-bespoke .steps: compat until agents.html uses steps--vertical; then drop it from here.) */
:is(.steps--vertical,.ag-bespoke .steps){--steps-gap:32px;grid-auto-flow:row;grid-auto-columns:auto;grid-template-columns:minmax(0,1fr)}
:is(.steps--vertical,.ag-bespoke .steps)>.steps__item{display:grid;grid-template-columns:30px minmax(0,1fr);column-gap:18px;align-items:start;justify-items:start}
:is(.steps--vertical,.ag-bespoke .steps)>.steps__item>.num-dot{grid-row:1 / span 6;margin:0}
:is(.steps--vertical,.ag-bespoke .steps)>.steps__item>:not(.num-dot){grid-column:2}
:is(.steps--vertical,.ag-bespoke .steps)>.steps__item>.num-dot+.steps__title{margin-top:2px}
:is(.steps--vertical,.ag-bespoke .steps)>.steps__item::after{top:38px;bottom:calc(8px - var(--steps-gap));left:14.5px;right:auto;width:1px;height:auto;transform-origin:top}
:is(.steps--vertical,.ag-bespoke .steps)>.steps__item:last-child::after,:is(.steps--vertical,.ag-bespoke .steps)>.steps__item:last-child::before{display:none}
html.js :is(.steps--vertical,.ag-bespoke .steps)[data-reveal]:not(.is-in)>.steps__item::after{transform:scaleY(0)}

/* ---------- 14 Screen frame (browser chrome for product screenshots) ---------- */
.screen{position:relative;margin:0;background:#fff;border:1px solid #DFE2E7;border-radius:14px;box-shadow:var(--shadow-3)}
.screen__bar{display:flex;align-items:center;gap:7px;height:38px;padding:0 14px;border-bottom:1px solid var(--line);border-radius:13px 13px 0 0;background:#FBFBFC}
.screen__bar>i{width:9px;height:9px;border-radius:50%;background:#E1E3E8}
.screen__url{margin:0 auto;transform:translateX(-22px);max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:4px 16px;border-radius:7px;background:#F1F2F4;font-size:12.5px;line-height:1.2;color:var(--ink-3);letter-spacing:.01em}
.screen__body{position:relative;border-radius:0 0 13px 13px}
.screen__body>img,.screen__body>picture>img{display:block;width:100%;height:auto;border-radius:0 0 13px 13px}
.screen--bare .screen__body>img{border-radius:13px}
.screen figcaption,.screen-caption{margin-top:16px}
.on-dark .screen,.section--dark .screen{border-color:rgba(255,255,255,.1);box-shadow:none}
@media (max-width:720px){.screen{border-radius:10px}.screen__bar{height:30px;border-radius:9px 9px 0 0}.screen__bar>i{width:7px;height:7px}.screen__url{font-size:11px;padding:3px 10px;transform:translateX(-14px)}.screen__body,.screen__body>img{border-radius:0 0 9px 9px}}
@media (max-width:480px){.screen__url{transform:none;max-width:calc(100% - 64px);margin-right:0}}

/* ---------- 15 Closing CTA band (dark) ---------- */
.cta-band{position:relative;overflow:hidden;background:var(--night);padding-block:clamp(88px,min(7vw + 24px,11vh + 24px),168px)}
.cta-band .wrap{position:relative;z-index:1}
/* copy on the left, the live visual (assets/live.js) on the right; stacks under 960px */
.cta-band__grid{--live-w:clamp(340px,min(31vw,var(--wrap) * .3583),560px);--live-h:clamp(360px,12.5vw + 160px,440px);display:grid;grid-template-columns:minmax(0,1fr) minmax(0,var(--live-w));gap:clamp(48px,6vw,96px);align-items:center}
@media (min-width:960px){.cta-band__grid .cta-band__title{font-size:clamp(36px,3.4vw + 8px,62px)}}
@media (min-width:1600px){.cta-band__grid .cta-band__title{font-size:clamp(62px,1.25vw + 42px,74px)}.cta-band__lead{font-size:clamp(21px,.3125vw + 16px,24px)}}
@media (max-width:959px){.cta-band__grid{grid-template-columns:minmax(0,1fr);gap:56px;--live-h:300px}.cta-band__live{width:100%;max-width:520px;justify-self:center}}
/* phones: the live field is pure decoration (~300px under the button), so the band ends on the copy */
@media (max-width:719px){.cta-band__live{display:none}}
.cta-band .brand-field,.page-hero .brand-field{-webkit-mask-image:linear-gradient(to bottom,#000 72%,transparent);mask-image:linear-gradient(to bottom,#000 72%,transparent)}
/* Below 1200px the field would run under the copy: keep it to the right edge, and keep the copy clear of it. */
@media (max-width:1199px){
  .cta-band .brand-field,.page-hero .brand-field{
    -webkit-mask-image:linear-gradient(to bottom,#000 72%,transparent),linear-gradient(to right,transparent 60%,#000 84%);
    -webkit-mask-composite:source-in;
    mask-image:linear-gradient(to bottom,#000 72%,transparent),linear-gradient(to right,transparent 60%,#000 84%);
    mask-composite:intersect}
}
@media (max-width:720px){
  .cta-band .brand-field,.page-hero .brand-field{
    -webkit-mask-image:linear-gradient(to bottom,#000 72%,transparent),linear-gradient(to right,transparent 50%,#000 92%);
    mask-image:linear-gradient(to bottom,#000 72%,transparent),linear-gradient(to right,transparent 50%,#000 92%)}
}
.cta-band__title{color:var(--fg);max-width:15em;font-size:clamp(36px,4.2vw + 6px,72px);line-height:1.04;letter-spacing:-.035em}
.cta-band__title em{display:block;font-style:normal;color:var(--neon)}
.cta-band__lead{margin-top:28px;max-width:52ch;font-size:clamp(18px,.45vw + 14px,21px);line-height:1.55;color:var(--fg-2)}
.cta-band__actions{margin-top:44px;display:flex;flex-wrap:wrap;align-items:center;gap:20px 28px}
.cta-band__email{font-size:16px;color:var(--fg-2)}
.cta-band__email a{color:var(--fg);text-decoration:underline;text-decoration-color:rgba(34,255,134,.6);text-decoration-thickness:1.5px;text-underline-offset:4px;transition:text-decoration-color .2s}
.cta-band__email a:hover{text-decoration-color:var(--neon)}
@media (max-width:480px){.cta-band__actions{flex-direction:column;align-items:stretch}.cta-band__actions .btn{width:100%}}
/* phones: the first line ("See OddsForge running") stays on one line instead of leaving a lone word */
@media (max-width:480px){.cta-band__title{font-size:min(36px,calc((100vw - 2 * var(--gutter)) / 11))}}
@media (min-width:721px) and (max-width:1199px){
  .cta-band>.wrap:not(.cta-band__grid) .cta-band__title,.cta-band>.wrap:not(.cta-band__grid) .cta-band__lead{max-width:min(15em,62%)}   /* legacy band with a background field */
}

/* ---------- 16 Footer (dark) ---------- */
/* On the page's 12-column grid (the --grid-gap gutter, so the columns line up with .grid--3 and
   .grid--4 above): the brand block takes 4 columns and each link column 2. Under 1200px the brand
   block sits above the links, which take 3 columns each. */
.site-footer{--logo-mark:var(--neon);background:var(--night-3);border-top:1px solid rgba(255,255,255,.06);padding-top:clamp(56px,min(5vw + 8px,8vh + 8px),96px);padding-bottom:clamp(28px,2.4vw,44px);font-size:15px}
.site-footer__top{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:48px var(--grid-gap,24px)}
.site-footer__brand{grid-column:span 4;display:flex;flex-direction:column;align-items:flex-start;gap:16px}
.site-footer__logo{display:block;color:#fff;border-radius:4px}
.site-footer__brand p{max-width:30ch;color:var(--fg-2);line-height:1.55}
.site-footer__brand .aws-mark{margin-top:12px}
.site-footer__cols{grid-column:span 8;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:36px var(--grid-gap,24px)}
.site-footer__col h2{margin-bottom:14px;font-family:var(--font-display);font-size:12.5px;font-weight:600;line-height:22px;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3)}
.site-footer__col ul{display:flex;flex-direction:column;gap:0}
.site-footer__col a{display:inline-block;padding:5px 0;line-height:1.5;color:var(--fg-2);transition:color .2s var(--ease)}   /* a taller tap target, same spacing */
.site-footer__col a:hover{color:#fff}
.site-footer__base{margin-top:clamp(48px,5vw,80px);padding-top:clamp(22px,1.8vw,30px);border-top:1px solid rgba(255,255,255,.07);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px 24px;font-size:13.5px;color:var(--fg-3)}
.site-footer__legal{display:flex;gap:24px}
.site-footer__legal a:hover{color:#fff}
@media (max-width:1199px){.site-footer__brand,.site-footer__cols{grid-column:1/-1}}
/* large screens: the footer grows with the container like the rest of the type */
@media (min-width:1600px){
  .site-footer{font-size:clamp(15px,.21vw + 11.6px,17px)}
  .site-footer__logo .logo{height:clamp(22px,.42vw + 15.3px,26px)}
  .site-footer__col h2{font-size:clamp(12.5px,.1vw + 10.9px,13.5px);line-height:clamp(22px,.42vw + 15.3px,26px);margin-bottom:clamp(14px,.42vw + 7.3px,18px)}
  .site-footer__base{font-size:clamp(13.5px,.16vw + 11px,15px)}
  .site-footer .aws-mark{--aws-w:clamp(38px,.42vw + 31.3px,42px);font-size:clamp(12px,.1vw + 10.4px,13px)}
}
/* touch widths (under 960px): 44px rows for the footer links; inline links (emails in the CTA band, menu and closers) get a
   taller hit area without moving the text (vertical padding on an inline box doesn't change the line) */
@media (max-width:959px){.site-footer__col a{padding:11px 0}}   /* touch widths: 22.5px line + 22px = a 44px row */
.cta-band__email a,.cta-band__lead a,.site-menu__foot a:not(.btn){padding-block:12px}
@media (max-width:560px){.site-footer__cols{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:36px}}

/* ---------- 17 Motion utilities ---------- */
/* reveal: fade + 14px rise. Needs <html class="js"> (set inline in <head>). */
html.js [data-reveal]{opacity:0;transform:translateY(14px);transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-out);transition-delay:calc(var(--reveal-delay,0ms))}
html.js [data-reveal].is-in{opacity:1;transform:none}
html.js [data-reveal-stagger]>*{opacity:0;transform:translateY(14px);transition:opacity var(--dur) var(--ease-out),transform var(--dur) var(--ease-out);transition-delay:calc(var(--i,0) * 80ms)}
html.js [data-reveal-stagger].is-in>*{opacity:1;transform:none}
html.js [data-reveal="fade"]{transform:none}
/* draw-in for SVG strokes (site.js sets pathLength=1) */
html.js .draw-ready{stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset 1.4s var(--ease-out);transition-delay:calc(var(--i,0) * 90ms)}
html.js .is-in .draw-ready,html.js .draw-ready.is-in{stroke-dashoffset:0}
/* counters keep their width while they settle */
[data-count]{font-feature-settings:"tnum" 1}

/* ---------- 18 Live visuals (assets/live.js): hero box + closing CTA band ---------- */
/* Each mount is a reserved box, so nothing moves when the visual draws. In the hero the box is the
   shared .page-hero__aside (§08). live.js picks the variant for [data-live="hero"] and the CTA band
   (?hero=scale|feed|coverage|field|stack, default scale); [data-live="field"] always draws the field.
   Illustration colours (amber, mint) are raw on purpose. */
.live-visual{position:relative;min-width:0;height:var(--live-h,360px);color:var(--on-night-2)}
@media (max-width:959px){.live-visual{width:100%;max-width:560px}.page-hero__aside.live-visual{max-width:none}}
@media (min-width:600px) and (max-width:959px){.page-hero{--hero-aside-h:400px}}

/* feed: agent task cards arrive, progress and resolve */
.lv-feed{position:absolute;inset:0;display:flex;flex-direction:column}
.lv-feed__head{flex:none;display:flex;align-items:center;justify-content:space-between;gap:16px;height:18px;margin-bottom:14px;font-family:var(--font-display);font-size:12px;font-weight:500;line-height:1;letter-spacing:.12em;text-transform:uppercase;color:var(--on-night-3);white-space:nowrap}
.lv-feed__sum{font-family:var(--font-body);font-size:13px;letter-spacing:0;text-transform:none}
.lv-feed__sum b{font-weight:600;color:#fff;font-feature-settings:"tnum" 1}
.lv-live{position:relative;display:inline-flex;align-items:center;gap:10px}
.lv-live::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;background:var(--neon)}
.lv-live::after{content:"";position:absolute;left:0;top:50%;width:7px;height:7px;margin-top:-3.5px;border-radius:50%;box-shadow:0 0 0 1px var(--neon);animation:lv-ring 2.8s var(--ease-out) infinite}
@keyframes lv-ring{0%{transform:scale(1);opacity:.7}70%,100%{transform:scale(2.6);opacity:0}}
@keyframes lv-blink{50%{opacity:.3}}
.lv-feed__list{--lv-gap:10px;position:relative;flex:1;min-height:0;-webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 88px),transparent);mask-image:linear-gradient(to bottom,#000 calc(100% - 88px),transparent)}
.lv-card{position:absolute;left:0;right:0;top:0;overflow:hidden;padding:14px 16px 15px;border-radius:12px;background:#15151A;box-shadow:inset 0 0 0 1px rgba(255,255,255,.075);transition:transform .9s var(--ease-out),opacity .7s var(--ease),box-shadow .9s var(--ease);will-change:transform,opacity}
.lv-card.is-approved{box-shadow:inset 0 0 0 1px rgba(34,255,134,.55)}
.lv-card__top{display:flex;align-items:center;gap:9px;height:16px;font-family:var(--font-display);font-size:11.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--on-night-2);white-space:nowrap}
.lv-card__top::before{content:"";flex:none;width:6px;height:6px;background:var(--neon)}
.lv-card__time{margin-left:auto;font-family:var(--font-body);font-size:12px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--on-night-3);font-feature-settings:"tnum" 1}
.lv-card__task{margin-top:8px;font-size:15.5px;font-weight:500;line-height:21px;letter-spacing:-.008em;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lv-card__foot{margin-top:12px;display:flex;align-items:center;gap:12px;min-width:0;height:24px}
.lv-card__by{min-width:0;font-size:12.5px;line-height:1.2;color:#86EBB4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transform:translateX(-4px);transition:opacity .6s var(--ease) .25s,transform .6s var(--ease-out) .25s}
.lv-card__by.is-on{opacity:1;transform:none}
.lv-card__bar{position:absolute;left:0;right:0;bottom:0;height:2px;background:linear-gradient(90deg,rgba(34,255,134,.2),var(--neon));transform:scaleX(0);transform-origin:left;opacity:0}
.lv-chip{display:inline-flex;flex:none;align-items:center;gap:7px;height:24px;padding:0 10px 0 9px;border-radius:var(--r-pill);background:rgba(255,255,255,.06);color:var(--on-night-2);font-family:var(--font-display);font-size:12px;font-weight:500;line-height:1;letter-spacing:.01em;white-space:nowrap;transition:background-color .5s var(--ease),color .5s var(--ease),opacity .22s var(--ease),transform .22s var(--ease)}
.lv-chip::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:currentColor;opacity:.75}
.lv-chip.is-swap{opacity:0;transform:translateY(3px)}
.lv-chip[data-tone="work"]{color:#D9DCE2}
.lv-chip[data-tone="work"]::before{background:var(--neon);opacity:1;animation:lv-blink 1.3s ease-in-out infinite}
.lv-chip[data-tone="wait"]{background:rgba(245,185,71,.13);color:#F6C35C}
.lv-chip[data-tone="done"]{background:rgba(34,255,134,.1);color:var(--neon)}
.lv-chip[data-tone="done"]::before{width:8px;height:4px;border-radius:0;background:none;border-left:1.6px solid;border-bottom:1.6px solid;transform:translateY(-1.5px) rotate(-45deg);opacity:1}

/* coverage: a week of routine work, tile by tile */
.lv-cov{--tile-gap:5px;--cat-w:104px;position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center}
.lv-cov__label{font-family:var(--font-display);font-size:12px;font-weight:500;line-height:1.2;letter-spacing:.12em;text-transform:uppercase;color:var(--on-night-3)}
.lv-cov__count{margin-top:14px;font-family:var(--font-display);font-size:52px;font-weight:500;line-height:1;letter-spacing:-.035em;color:#fff;font-feature-settings:"tnum" 1;white-space:nowrap}
.lv-cov__count b{font-weight:500}
.lv-cov__count span{margin-left:.12em;font-size:20px;letter-spacing:-.01em;color:var(--on-night-2)}
.lv-cov__sub{margin-top:12px;display:flex;align-items:center;gap:9px;height:20px;font-size:14px;line-height:20px;color:var(--on-night-2);transition:opacity .2s var(--ease),transform .2s var(--ease)}
.lv-cov__sub.is-swap{opacity:0;transform:translateY(3px)}
.lv-cov__sub::before{content:"";flex:none;width:8px;height:8px;border-radius:2px;background:var(--neon);opacity:0}
.lv-cov__sub[data-kind="work"]::before{opacity:1;animation:lv-blink 1.3s ease-in-out infinite}
.lv-cov__sub[data-kind="wait"]::before{opacity:1;background:#F5B947}
.lv-cov__sub[data-kind^="ok"]{color:#86EBB4}
.lv-cov__sub[data-kind^="ok"]::before{opacity:1}
.lv-cov__bar{margin-top:18px;display:flex;height:4px;border-radius:2px;background:rgba(255,255,255,.08);overflow:hidden}
.lv-cov__bar i{display:block;flex:none;width:0;height:100%;transition:width .35s linear}
.lv-cov__g{background:var(--green)}
.lv-cov__a{background:#F5B947}
.lv-cov__rows{margin-top:24px;display:grid;gap:13px}
.lv-cov__row{display:grid;grid-template-columns:var(--cat-w) minmax(0,1fr);gap:12px;align-items:start}
.lv-cov__cat{font-size:13px;line-height:16px;color:var(--on-night-2);white-space:nowrap}
.lv-cov__tiles{display:grid;grid-template-columns:repeat(18,minmax(0,1fr));gap:var(--tile-gap)}
.lv-cov__tiles i{position:relative;display:block;aspect-ratio:1;border-radius:2px;background:rgba(255,255,255,.075)}
.lv-cov__tiles i::before,.lv-cov__tiles i::after{content:"";position:absolute;inset:0;border-radius:inherit;opacity:0;transition:opacity .45s var(--ease),transform .7s var(--ease-out)}
.lv-cov__tiles i::before{background:#F5B947}
.lv-cov__tiles i::after{background:var(--green)}
.lv-cov__tiles i.is-wait::before{opacity:1}
.lv-cov__tiles i.is-done::after{opacity:.8}
.lv-cov__tiles i.is-flash::after{opacity:1;background:var(--neon);transform:scale(1.18);transition:opacity .18s var(--ease),transform .18s var(--ease)}
.lv-cov__foot{margin-top:22px;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 16px}
.lv-cov__key{display:flex;flex-wrap:wrap;gap:6px 16px;font-size:12.5px;line-height:1.3;color:var(--on-night-3)}
.lv-cov__key li{display:flex;align-items:center;gap:7px}
.lv-cov__key li::before{content:"";flex:none;width:9px;height:9px;border-radius:2px;background:rgba(255,255,255,.14)}
.lv-cov__key .is-done::before{background:var(--green)}
.lv-cov__key .is-wait::before{background:#F5B947}
.lv-cov--compact{--tile-gap:4px;--cat-w:96px}
.lv-cov--compact .lv-cov__count{margin-top:10px;font-size:38px}
.lv-cov--compact .lv-cov__count span{font-size:17px}
.lv-cov--compact .lv-cov__bar{margin-top:14px}
.lv-cov--compact .lv-cov__rows{margin-top:18px;gap:8px}
.lv-cov--compact .lv-cov__cat{font-size:12px;line-height:14px}
.lv-cov--compact .lv-cov__foot{margin-top:16px}
@media (max-width:959px){
  .lv-cov{--tile-gap:3px;--cat-w:90px}
  .lv-cov__count{margin-top:10px;font-size:36px}
  .lv-cov__count span{font-size:16px}
  .lv-cov__bar{margin-top:14px}
  .lv-cov__rows{margin-top:16px;gap:8px}
  .lv-cov__cat{font-size:12px;line-height:12px}
  .lv-cov__foot{margin-top:14px}
}

/* field + stack: one canvas (or the hero-stack figure) filling the box */
.lv-field,.lv-stack,.lv-scale{position:absolute;inset:0}
.lv-field canvas{display:block;width:100%;height:100%}
/* Hero figures: every figure in a hero box (home, OddsForge, Agent Testing, iGaming Agents) mounts in
   the one shared .lv-scale box: <div class="lv-scale" data-figure="name">. The figure
   (assets/fig/<name>.js) fills it and replaces its contents; it sits above the field, which live.js
   shows until the figure has drawn and then removes. The mount is exactly the hero box (§08) at every
   size: it never runs on past the container into the page margin, so the visual's right edge is the
   container's right edge. Each figure centres its subject in the mount and fades softly at its edges. */
.live-visual>.lv-scale{position:absolute;inset:0;z-index:1}
.lv-scale[hidden]{display:none}
/* the field (the hero box and the closing CTA band): the canvas is exactly its box, never running on
   into the page margin; the field centres on the box and fades softly on all four sides, so it never
   reads as a box */
.live-visual .lv-field canvas{
  --lv-fx:linear-gradient(to right,transparent,#000 12%,#000 88%,transparent);
  --lv-fy:linear-gradient(to bottom,transparent,#000 10%,#000 90%,transparent);
  -webkit-mask-image:var(--lv-fx),var(--lv-fy);-webkit-mask-composite:source-in;
  mask-image:var(--lv-fx),var(--lv-fy);mask-composite:intersect}

/* ---------- 19 Figure frame (large "How it works" figures) ---------- */
/* Sizing rule: on a laptop or desktop screen (1200px and up) a large figure fits in the screen below the nav, with at most its section
   heading scrolled out: at most --fig-max-h tall (78% of the screen's height; 599px at 1366×768,
   702px at 1440×900, 842px at 1920×1080). Every [data-figure-slot] is a frame already; wrap any other
   large diagram in <div class="figure-frame">. The frame is an inline-size container named "figure"
   (size inner parts with cqi units or @container figure (…)), it never runs past its column, and it
   exposes:
     --fig-max-h   the tallest the figure may be (read it in the figure: height:min(…,var(--fig-max-h)))
     --fig-max-w   the widest it may be (default: the full container); set it on the frame to narrow a
                   figure, which then stays centred
     --fig-ratio   width ÷ height of a figure that scales in proportion (an SVG, a scaled stage): set it
                   on the frame and the frame narrows (centred) until the figure fits --fig-max-h
   Under 1200px (tablets) figures may stack and be taller (--fig-max-h is 9999px: no limit, but still a
   length, so min()/calc() that read it keep working). */
[data-figure-slot],.figure-frame{
  --fig-max-h:9999px;--fig-max-w:100%;
  position:relative;min-width:0;max-width:100%;margin-inline:auto;container:figure / inline-size}
[data-figure-slot]>[data-figure],.figure-frame>*{min-width:0;max-width:100%}
@media (min-width:1200px){
  [data-figure-slot],.figure-frame{
    --fig-max-h:clamp(440px,min(78vh,100vh - var(--nav-h) - 64px),980px);
    max-width:min(100%,var(--fig-max-w),var(--fig-max-h) * var(--fig-ratio,100))}
}

/* Figure stage strip + in/out labels: the shared parts of every "How it works" figure.
   <ol class="fig-steps" data-cycle> of .fig-steps__item: a square number tile (.fig-steps__n: "1",
   never "01"), a Space Grotesk .fig-steps__title and an Inter .fig-steps__text sub-line. Equal
   columns, centred. .is-active (data-cycle sets it in turn, or set it yourself) turns the tile neon.
   fig-steps--inline: tile and title on one line, left-aligned (column headers over a figure).
   Inside a figure frame narrower than 520px the strip becomes a list (tile left); add fig-steps--fixed
   in a figure that scales as one picture to keep the row.
   .fig-io: the "What goes in / What comes out" column labels (the .label style, with its gap below);
   fig-io--end right-aligns it, fig-io--center centres it. Both adapt to dark contexts. */
.fig-steps{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--gap-card);text-align:center}
.fig-steps__item{display:flex;flex-direction:column;align-items:center;min-width:0}
.fig-steps__n{flex:none;display:grid;place-items:center;width:26px;height:26px;border-radius:7px;background:color-mix(in srgb,var(--fg) 7%,transparent);color:var(--fg-2);font-family:var(--font-body);font-size:var(--fs-xs);font-weight:600;line-height:1;font-feature-settings:"tnum" 1;transition:background-color .45s var(--ease),color .45s var(--ease),box-shadow .45s var(--ease)}
.fig-steps__item.is-active .fig-steps__n,.fig-steps__n.is-active{background:var(--neon);color:var(--ink);box-shadow:0 0 0 4px rgba(34,255,134,.18)}
.fig-steps__title{display:block;margin-top:12px;font-family:var(--font-display);font-size:var(--fs-card);font-weight:500;line-height:1.3;letter-spacing:-.01em;color:var(--fg)}
.fig-steps__text{display:block;margin-top:4px;max-width:24ch;font-size:var(--fs-xs);line-height:1.4;color:var(--fg-2);text-wrap:balance}
.fig-steps--inline{text-align:left}
.fig-steps--inline .fig-steps__item{display:grid;grid-template-columns:26px minmax(0,1fr);column-gap:10px;align-items:center;justify-items:start}
.fig-steps--inline .fig-steps__title{margin-top:0}
.fig-steps--inline .fig-steps__text{grid-column:2;max-width:none}
@container figure (max-width:520px){
  .fig-steps:not(.fig-steps--fixed){grid-auto-flow:row;grid-template-columns:minmax(0,1fr);gap:14px;text-align:left}
  .fig-steps:not(.fig-steps--fixed) .fig-steps__item{display:grid;grid-template-columns:26px minmax(0,1fr);column-gap:12px;align-items:start;justify-items:start}
  .fig-steps:not(.fig-steps--fixed) .fig-steps__n{grid-row:span 2}
  .fig-steps:not(.fig-steps--fixed) .fig-steps__title{margin-top:3px}
  .fig-steps:not(.fig-steps--fixed) .fig-steps__text{max-width:none}
}
.fig-io{display:block;margin-bottom:16px;font-family:var(--font-display);font-size:var(--fs-label);font-weight:600;line-height:1.2;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3)}
.fig-io--end{text-align:right}
.fig-io--center{text-align:center}

/* comparison switcher (only with ?hero= in the URL) */
.lv-switch{position:fixed;right:20px;bottom:20px;z-index:80;display:flex;align-items:center;gap:1px;padding:5px 5px 5px 15px;border-radius:var(--r-pill);background:rgba(17,17,22,.68);-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);box-shadow:inset 0 0 0 1px rgba(255,255,255,.13),0 10px 30px -10px rgba(0,0,0,.55);font-family:var(--font-display);font-size:13px;font-weight:500;line-height:1;color:var(--on-night-2)}
.lv-switch__k{margin-right:7px;font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--on-night-3)}
.lv-switch__dot{color:rgba(255,255,255,.22)}
.lv-switch button{height:30px;padding:0 11px;border-radius:var(--r-pill);color:var(--on-night-2);cursor:pointer;transition:color .2s var(--ease),background-color .2s var(--ease)}
.lv-switch button:hover{color:#fff;background:rgba(255,255,255,.07)}
.lv-switch button[aria-pressed="true"]{background:var(--neon);color:var(--ink)}
.lv-switch button:focus-visible{outline:2px solid var(--neon);outline-offset:2px}
@media (max-width:480px){.lv-switch{right:50%;transform:translateX(50%);bottom:14px;padding-left:12px}.lv-switch button{padding:0 9px}}
@media print{.lv-switch{display:none}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  html.js [data-reveal],html.js [data-reveal-stagger]>*,html.js [data-pins] .pin{opacity:1;transform:none;transition:none}
  html.js .draw-ready{stroke-dashoffset:0;transition:none}
  html.js .flow:not(.is-in) .flow__stages::before{transform:none}
  html.js .steps[data-reveal]:not(.is-in) .steps__item::after{transform:none}
  .brand-field{transition:none}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
}
@media print{.site-nav,.site-menu,.brand-field{display:none}html.js [data-reveal],html.js [data-reveal-stagger]>*{opacity:1;transform:none}}

/* Products menu icons: small hover animations (owner request) */
.site-nav__ico svg g,.site-nav__ico svg .ic-mark,.site-nav__ico svg .ic-ring,.site-nav__ico svg .ic-ball,.site-nav__ico svg .ic-arm,.site-nav__ico svg .ic-knob,.site-nav__ico svg .ic-reels{transform-box:fill-box}
.site-nav__ico svg .ic-l1,.site-nav__ico svg .ic-l2{transition:transform .35s cubic-bezier(.2,.8,.2,1)}
.site-nav__opt:is(:hover,:focus-visible) .ic-l1{transform:translateY(-2.2px)}
.site-nav__opt:is(:hover,:focus-visible) .ic-l2{transform:translateY(-1.1px)}
.site-nav__opt:is(:hover,:focus-visible) .ic-mark{animation:ic-glow 1.2s ease-in-out infinite}
@keyframes ic-glow{50%{opacity:.45}}
.site-nav__ico svg .ic-ring{transform-origin:center}
.site-nav__opt:is(:hover,:focus-visible) .ic-ring{animation:ic-ring .9s cubic-bezier(.2,.8,.2,1)}
@keyframes ic-ring{35%{transform:scale(1.18)}}
.site-nav__opt:is(:hover,:focus-visible) .ic-ball{animation:ic-ball 1.1s cubic-bezier(.45,0,.2,1)}
@keyframes ic-ball{0%{transform:none}55%{transform:translateX(6.7px);opacity:1}70%{transform:translateX(6.7px);opacity:0}71%{transform:none;opacity:0}100%{transform:none;opacity:1}}
.site-nav__ico svg .ic-arm{transform-origin:bottom}
.site-nav__opt:is(:hover,:focus-visible) .ic-arm{animation:ic-arm .8s cubic-bezier(.3,0,.2,1)}
.site-nav__opt:is(:hover,:focus-visible) .ic-knob{animation:ic-knob .8s cubic-bezier(.3,0,.2,1)}
.site-nav__opt:is(:hover,:focus-visible) .ic-reels{animation:ic-reels .8s steps(1,end)}
@keyframes ic-arm{40%{transform:scaleY(.3)}}
@keyframes ic-knob{40%{transform:translateY(3.5px)}}
@keyframes ic-reels{40%{fill:#C9F7DC}55%{fill:#fff}65%{fill:#C9F7DC}80%{fill:#fff}}
@media (prefers-reduced-motion:reduce){.site-nav__ico svg *{animation:none!important;transition:none!important}}
