/* 1. TOKENS — verbatim copy of styles/tokens.css, plus additions. Notes § 1. */

:root {

  /* 1. SCALES — type, space, shape, motion, depth. Notes § 1.
     NO COLOUR HERE. The live palette is "Cool Ledger", declared once further
     down and marked as such. A token declared in two places lies about which
     one is live. */

  /* Fonts are self-hosted from assets/fonts/ — see the @font-face block
   below and docs/fonts-handoff.md. No third-party font request is made. */

  --ff-sans: "Geist", ui-sans-serif, system-ui, -apple-system,
             "Segoe UI", Helvetica, Arial, sans-serif;
  --ff-mono: "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono",
             Menlo, Consolas, monospace;

  /* Fluid from 360px to 1440px. Below 360 the min clamps; above 1440 the
     max clamps. Tracking tightens as size grows — that relationship is the
     whole point, do not flatten it. */

  /* size                       min       fluid                      max   */
  --fs-display:  clamp(2.375rem, 1.833rem + 2.407vw, 4.000rem); /* 38->64 */
  --fs-h1:       clamp(2.125rem, 1.583rem + 2.407vw, 3.750rem); /* 34->60 */
  --fs-h2:       clamp(2.125rem, 1.542rem + 2.593vw, 3.875rem); /* 34->62 */
  --fs-h3:       clamp(1.375rem, 1.208rem + 0.741vw, 1.875rem); /* 22->30 */
  --fs-h4:       clamp(1.125rem, 1.063rem + 0.278vw, 1.313rem); /* 18->21 */
  --fs-body-lg:  clamp(1.063rem, 0.958rem + 0.463vw, 1.375rem); /* 17->22 */
  --fs-body:     clamp(1.000rem, 0.979rem + 0.093vw, 1.063rem); /* 16->17 */
  --fs-body-sm:  clamp(0.875rem, 0.854rem + 0.093vw, 0.938rem); /* 14->15 */
  --fs-caption:  clamp(0.750rem, 0.729rem + 0.093vw, 0.813rem); /* 12->13 */
  --fs-mono-sm:  clamp(0.750rem, 0.729rem + 0.093vw, 0.813rem); /* 12->13 */
  --fs-mono-code:clamp(0.813rem, 0.792rem + 0.093vw, 0.875rem); /* 13->14 */

  --lh-display: 1.00;
  --lh-h1:      1.03;
  --lh-h2:      1.08;
  --lh-h3:      1.18;
  --lh-h4:      1.30;
  --lh-body-lg: 1.55;
  --lh-body:    1.60;
  --lh-body-sm: 1.55;
  --lh-caption: 1.45;
  --lh-mono:    1.45;
  --lh-code:    1.65;

  /* Sans tracks negative and scales with size. Mono tracks POSITIVE. */
  --ls-display: -0.030em;
  --ls-h1:      -0.038em;
  --ls-h2:      -0.025em;
  --ls-h3:      -0.022em;
  --ls-h4:      -0.016em;
  --ls-body-lg: -0.012em;
  --ls-body:    -0.011em;
  --ls-body-sm: -0.008em;
  --ls-caption: -0.005em;
  --ls-mono:     0.020em;
  --ls-code:     0em;

  --fw-display: 380;   /* light-to-medium. never bold at display sizes */
  --fw-h1:      400;
  --fw-h2:      450;
  --fw-h3:      500;
  --fw-h4:      500;
  --fw-body:    400;
  --fw-medium:  500;
  --fw-mono:    500;


  /* 3. SPACING — 4px base, named steps. Use the name, never a raw px. · rationale: docs/styles-notes.md § 3 */
  --sp-3xs:  0.125rem;  /*   2px  hairline nudges, icon optical offsets */
  --sp-2xs:  0.25rem;   /*   4px  icon-to-label gap */
  --sp-xs:   0.5rem;    /*   8px  chip padding, tight stacks */
  --sp-sm:   0.75rem;   /*  12px  control inner padding */
  --sp-md:   1rem;      /*  16px  default element gap */
  --sp-lg:   1.5rem;    /*  24px  card padding (mobile), button padding */
  --sp-xl:   2rem;      /*  32px  card padding (desktop), grid gap */
  --sp-2xl:  3rem;      /*  48px  block separation inside a section */
  --sp-3xl:  4rem;      /*  64px  header-to-content inside a section */
  --sp-4xl:  6rem;      /*  96px  scroll-margin-top under the sticky nav */
  --sp-5xl:  8rem;      /* 128px  reserved for the hero only */


  /* 4. LAYOUT · rationale: docs/styles-notes.md § 4 */
  --container:        1200px;  /* default content column */
  --container-wide:   1360px;  /* reserved: no element uses it since
                                  #coverage was removed */
  --container-narrow:  720px;  /* FAQ, engagement steps, legal prose */
  --measure:            68ch;  /* max line length for body copy */
  --gutter:  clamp(1.25rem, 0.55rem + 3.1vw, 3rem);   /* 20 -> 48px */

  /* Section rhythm. Three tokens so band height can VARY deliberately —
     uniform rhythm is the reason a page reads as flat. */
  --section-y-tight: clamp(2.500rem, 1.833rem + 2.963vw, 4.000rem);  /* 40->64  */
  --section-y:       clamp(3.500rem, 2.333rem + 5.185vw, 7.000rem);  /* 56->112 */
  --section-y-loose: clamp(4.500rem, 2.667rem + 8.148vw, 10.00rem);  /* 72->160 */

  --nav-h:           56px;     /* 64px from lg up, overridden in styles.css */


  /* 5. RADII — small and scaled to element size. Nothing above 14px. · rationale: docs/styles-notes.md § 5 */
  --r-xs:   3px;   /* inline code, tiny tags */
  --r-sm:   4px;   /* filter chips, table cells, swatches */
  --r-md:   6px;   /* buttons, inputs, selects, tabs, diagram nodes */
  --r-lg:  10px;   /* cards, bento cells, code panel, accordion rows */
  --r-xl:  14px;   /* the hero demo frame — the only element that gets it */
  --r-pill: 999px; /* status chips ONLY, so they read as state not as UI */


  /* 6. BORDERS & ELEVATION · rationale: docs/styles-notes.md § 6 */
  --bw-hairline: 1px;
  --bw-strong:   1px;
  --bw-focus:    2px;
  --focus-offset: 2px;


  /* 7. MOTION — durations and curves measured off live production sites. · rationale: docs/styles-notes.md § 7 */
  --dur-instant:  80ms;    /* colour-only swaps inside a pressed control */
  --dur-micro:   140ms;    /* hover, focus, border/colour change */
  --dur-standard:240ms;    /* tab swap, accordion, panel change */
  --dur-entrance:440ms;    /* scroll reveal */
  --dur-ambient:2400ms;    /* the diagram comet loop */

  --ease-out:      cubic-bezier(0.25, 0.46, 0.45, 0.94); /* easeOutQuad  */
  --ease-standard: cubic-bezier(0.40, 0.00, 0.20, 1.00);
  --ease-emphasis: cubic-bezier(0.25, 1.00, 0.50, 1.00); /* easeOutQuart */
  --ease-expo:     cubic-bezier(0.19, 1.00, 0.22, 1.00); /* easeOutExpo  */
  /* A real spring in pure CSS. Budget: ONE use on the whole page, on the
     "Copied" confirmation. Everything else decelerates without overshoot. */
  --ease-spring: linear(0,.006,.0225,.048,.081,.119,.162,.209,.257,.308,.358,.409,.459,.508,.556,.602,.645,.687,.726,.762,.796,.827,.856,.882,.905,.927,.946,.963,.977,.99,1.001,1.011,1.019,1.026,1.031,1.035,1.038,1.04,1.042,1.043,1.043,1.042,1.041,1.039,1.037,1.035,1.033,1.031,1.029,1.027,1.025,1.023,1.021,1.019,1.017,1.015,1.013,1.011,1.01,1.008,1.007,1.006,1.005,1.004,1.003,1.002,1.001,1.001,1,.999,.999,.999,.999,.998,.998,.998,.998,.998,.998,.998,.998,.998,.999,.999,.999,.999,.999,.999,1,1,1,1,1,1,1,1,1,1,1);

  --stagger: 60ms;         /* multiplied by --i on staggered reveals */


  --motion: 0;


  /* 8. STACKING — every z-index on the page comes from this list. · rationale: docs/styles-notes.md § 8 */
  --z-base:      0;
  --z-raised:   10;   /* hovered bento cell, active diagram node */
  --z-sticky:  100;   /* in-section sticky headings */
  --z-nav:     200;   /* the site header */
  --z-drawer:  300;   /* mobile filter drawer */
  --z-overlay: 400;   /* scrim behind the drawer */
  --z-toast:   500;   /* "Copied" confirmation */
  --z-skip:    600;   /* skip link, always on top when focused */
}


/* rationale: docs/styles-notes.md § 8 */

/* Geist — cyrillic-ext */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(assets/fonts/geist-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* Geist — cyrillic */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(assets/fonts/geist-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* Geist — vietnamese */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(assets/fonts/geist-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* Geist — latin-ext */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(assets/fonts/geist-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Geist — latin */
@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(assets/fonts/geist-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Geist Mono — cyrillic-ext */
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(assets/fonts/geist-mono-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* Geist Mono — cyrillic */
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(assets/fonts/geist-mono-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* Geist Mono — symbols2 (box drawing, used by the code panel) */
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(assets/fonts/geist-mono-symbols2.woff2) format('woff2');
  unicode-range: U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F;
}
/* Geist Mono — vietnamese */
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(assets/fonts/geist-mono-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* Geist Mono — latin-ext */
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(assets/fonts/geist-mono-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Geist Mono — latin */
@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(assets/fonts/geist-mono-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* rationale: docs/styles-notes.md § 8 */
@media (prefers-reduced-motion: no-preference) {
  :root { --motion: 1; }
}

/* rationale: docs/styles-notes.md § 8 */

/* PALETTE — "Cool Ledger". Monochrome and cool by construction: blue is the
   highest channel in every ground below, and the ink is navy, not black. No
   accent hue — the interactive colour is the ink. § 1 of styles-notes. */
:root {
  /* The raw pair the palette derives from. Tokens, not literals, because
     #getting-started re-declares --c-bg and --c-text for its own subtree and
     still has to name the page's ground and ink. */
  --c-ink:            #0A2540;
  --c-ground:         #F6F9FC;

  --c-bg:             var(--c-ground);
  --c-surface:        #FFFFFF;
  --c-sunken:         #EBF0F5;
  --c-overlay-hover:  rgba(10, 37, 64, 0.04);
  --c-overlay-active: rgba(10, 37, 64, 0.07);

  --c-border:         rgba(10, 37, 64, 0.10);
  --c-border-strong:  rgba(10, 37, 64, 0.45);
  --c-border-hover:   rgba(10, 37, 64, 0.58);

  --c-text:           var(--c-ink);
  --c-text-2:         #425466;
  --c-text-3:         #556575;
  --c-text-dim:       #697386;   /* >=24px ONLY — 4.17:1 on --c-sunken */
  --c-text-disabled:  #9AA5B1;


  --c-accent:         var(--c-ink);
  --c-accent-hover:   #061A2E;
  --c-accent-active:  #04121F;
  --c-accent-ink:     #FFFFFF;
  --c-accent-muted:   rgba(10, 37, 64, 0.06);
  --c-focus:          var(--c-ink);

  /* Semantic, but pulled down so they sit on paper without shouting. These
     are the only hues left in the payment vocabulary and they appear only
     where a payment state is being described. */
  --c-ok:             #2F6B52;
  --c-warn:           #6E5A2B;
  --c-err:            #8A3A34;
  --c-ok-muted:       rgba(47, 107, 82, 0.10);
  --c-warn-muted:     rgba(110, 90, 43, 0.11);
  --c-err-muted:      rgba(138, 58, 52, 0.10);


  --c-glow:           rgba(10, 37, 64, 0.05);
  --shadow-overlay:   0 8px 32px rgba(10, 37, 64, 0.16);
}
@media (prefers-contrast: more) {
  :root {
    --c-border:        rgba(10, 37, 64, 0.26);
    --c-border-strong: rgba(10, 37, 64, 0.68);
    --c-text-2:        #2E3F52;
    --c-text-3:        #3B4C60;
  }
}

/* ------------------------ END verbatim copy of styles/tokens.css --------- */


/* 1. TOKENS ADDED BY THE CSS AGENT · rationale: docs/styles-notes.md § 1 */
:root {
  /* -- control sizing (design system § Component states: 44px buttons,
        36px icon buttons and the nav CTA, 32px chips, 24x24 minimum) ---- */
  --h-control:      44px;   /* buttons, inputs, selects */
  --h-control-sm:   36px;   /* nav CTA, copy button, icon buttons */
  --target-min:     24px;   /* WCAG 2.5.8 minimum target */
  --h-textarea:    120px;   /* design system § Form fields */

  /* -- icon sizing (design system § Iconography: 16 / 20 / 24 only) ----- */
  --size-icon:      24px;
  --size-icon-sm:   16px;
  --size-check:     20px;   /* the consent checkbox box */
  --size-spinner:   16px;

  /* -- rule widths that are not borders and not the focus ring ---------- */
  --bw-rule:         2px;   /* nav active rule, row rule, .facts opening rule */
  --select-arrow:    6px;   /* the CSS-drawn <select> chevron */

  /* -- layout ----------------------------------------------------------- */
  --nav-h-lg:       64px;   /* --nav-h from lg up */
  --diagram-min-w: 320px;   /* below this the SVGs scroll rather than shrink */
  --blur-nav:       18px;   /* the one permitted backdrop-filter radius */


  --rail:          30rem;   /* 480px — the split layout's text column */


  --measure-head:  62rem;   /* 992px — 2 x the rendered body measure */


  /* --accent-gap IS GONE. It existed to hold the indigo accent and
     #marketing's ochre far enough apart that they could never appear in one
     viewport, and it bought that with up to 30rem of empty page. The
     monochrome pass removed the indigo: --c-accent is now ink, not a hue,
     and ink does not compete with ochre for "which is the brand colour".
     The premise is void, so the void is too. */
  --split-gap:     var(--sp-3xl);


  --fs-hero-split: clamp(2.125rem, 1.542rem + 2.593vw, 3.750rem);


  --c-surface-3:   #F0F4F8;


  --c-border-card: rgba(10, 37, 64, 0.13);


  --c-raised:       var(--c-surface);
  --c-raised-hover: var(--c-surface-3);
  --c-edge-hover:   var(--c-accent);


  /* Shadows carry the ink's temperature. Neutral black on a cool ground reads
     as soot, not depth. Alphas unchanged; only the tint moved. */
  --shadow-1: 0 1px 2px rgba(10, 37, 64, .05), 0 2px 6px rgba(10, 37, 64, .05);
  --shadow-2: 0 2px 4px rgba(10, 37, 64, .05), 0 14px 30px rgba(10, 37, 64, .09);
  --shadow-3: 0 6px 12px rgba(10, 37, 64, .06), 0 30px 64px rgba(10, 37, 64, .14);

  /* The existing vocabulary maps onto the scale rather than sitting beside
     it — there is no fourth set of shadow values in this file. */
  --shadow-raised: var(--shadow-1);
  --shadow-nav:    0 4px 16px -8px rgba(10, 37, 64, 0.14);


  /* The one hue on the page, warm on purpose: complementary to the navy, not
     a leftover. Deepened when the ink went cool — white on it is 7.15:1 — so
     it holds its weight beside navy instead of reading as faded. */
  --c-marketing:        #7A4E1D;
  --c-marketing-hover:  #663F16;
  --c-marketing-active: #523211;
  --c-marketing-ink:    #FFFFFF;  /* label ON a --c-marketing fill */

  --c-marketing-edge:   rgba(122, 78, 29, 0.42);

  /* -- SVG label sizes. User units inside the two authored viewBoxes, not
        CSS layout px, so they are not on the type scale. ---------------- */
  --svg-label:      13px;
  --svg-sub:        11px;

  --svg-glyph:      14px;

  /* The hero's vertical canvas is authored 360x560; unstyled it was 739px of
     hero before the copy was counted. This is the cap that brings it back
     under half a small viewport (§ 9). */
  --flow-hero-cap:  24rem;

  /* -- motion distances. Every one is a figure the design system § Motion
        names by hand; they live here so no transform carries a raw px. --- */
  --nudge-press:     1px;   /* button :active translateY */
  /* --nudge-lift (2px) removed in iteration 2: the card hover rise is now
     --nudge-card and nothing else used it. */
  --rise-reveal:    12px;   /* scroll reveal */
  --rise-step:       4px;   /* attempt-log row stepping in */
  --rise-panel:      8px;   /* mobile nav panel entrance */
  --burger-shift:  3.5px;   /* the two nav bars folding into an X */
  --nudge-lift:      1px;
  --nudge-card:      3px;   /* card hover rise — the iteration-2 brief asks
                               for 2-3px; 3px so the lift is legible against
                               the new card edge */

  /* The card-hover duration. tokens.css offers 140ms and 240ms and the brief
     asks for 150-200ms, so the one value between them lives here. */
  --dur-lift:      180ms;


  --dur-draw:      620ms;
  --dur-draw-long: 1500ms;   /* the scroll-drawn diagram, a longer single pass */
  --draw-step:      60ms;

  --draw-head:      0.72;


  --spot-size:      22rem;
  --c-spot-edge:    rgba(10, 37, 64, 0.50);
  --dur-spot:       260ms;


  --dur-line:       560ms;
  --stagger-line:    70ms;   /* the task's 60-80ms band */
  --line-bleed:    0.16em;


  --c-glow:          rgba(10, 37, 64, 0.035);
  --texture-cell:    72px;
  --c-texture:       rgba(10, 37, 64, 0.013);
  --dur-drift:        64s;


  --rail-tick:       28px;
  --rail-tick-rest:  0.5;
  --rail-inset:      var(--sp-md);


  --mag-max:          4px;


  --stagger-slow:   112ms;
  --dur-entrance-slow: 640ms;
  --rise-reveal-slow: 18px;  /* against --rise-reveal's 12px */


  --measure:        44ch;


  /* -- the dark section. These decide whether #getting-started's text is
        legible: the scrim is heaviest where the copy sits and lightest where
        the photograph is allowed to show. § 14 of styles-notes. ---------- */
  --scrim-near:     rgba(10, 37, 64, 0.94);
  --scrim-mid:      rgba(10, 37, 64, 0.80);
  --scrim-far:      rgba(10, 37, 64, 0.58);
  --scrim-angle:    105deg;

  /* #one-integration's scrim is heavier and runs at a different angle: its
     photograph is busier than the office window and the section carries more
     small text over it. */
  --scrim-2-near:   rgba(10, 37, 64, 0.96);
  --scrim-2-mid:    rgba(10, 37, 64, 0.86);
  --scrim-2-far:    rgba(16, 52, 86, 0.80);
  --scrim-2-angle:  118deg;

  --scrim-fade:     160px;   /* the dissolve from the light section above */

  /* The photograph behind #one-integration. A token so the file names its
     assets in one place, and so the section rule carries no url() literal.
     JPEG here, AVIF in the @supports block below — see the note there. */
  --photo-one-integration: url("assets/img/photo-01.jpg");

  /* --c-surface is re-declared inside a dark section, so a rule that needs
     the PAGE's surface — the fade out of #how-it-works, which sits on it —
     cannot read --c-surface. It reads this. */
  --c-surface-page: #FFFFFF;

  /* -- the photo mosaic. Three frames, full-bleed, one row. The first column
        is widest so the composition has a subject rather than three equal
        slabs; the 6px gutter is a seam, not a grid gap. ----------------- */
  --mosaic-cols:    1.35fr 1fr 1fr;
  --mosaic-row:     clamp(180px, 20vw, 280px);
  --mosaic-row-sm:  clamp(150px, 34vw, 220px);
  --mosaic-gap:     6px;
  --mosaic-2:       url("assets/img/photo-02.jpg");
  --mosaic-3:       url("assets/img/photo-01.jpg");
  /* Cell 2 deliberately names the same file as the #getting-started ground:
     one URL is one fetch, and the mosaic's crop of it differs anyway. */


  /* -- the API console. Its ground is the ink, not a --c-* surface: it is
        the same dark object on every ground. The syntax colours are the one
        hue permitted outside #marketing — they carry meaning, and they are
        measured against the console, not the page. -------------------- */
  --c-console:        var(--c-ink);
  --c-console-text:   #D7E2EF;
  --c-console-chrome: rgba(255, 255, 255, 0.05);
  --c-console-edge:   rgba(255, 255, 255, 0.10);
  --c-console-tab:    rgba(255, 255, 255, 0.60);
  /* The badge is the page saying no host or key below is real. At .52 it
     measured 4.81:1 — passing, but the narrowest pair on the page, and this
     is the last label that should be the hardest to read. */
  --c-console-note:   rgba(255, 255, 255, 0.66);
  --c-console-hover:  rgba(255, 255, 255, 0.07);

  --c-code-comment:   #93A9C0;
  --c-code-key:       #9FC6F0;
  --c-code-str:       #E4CFA8;
  --c-code-ok:        #7ED9A8;
  --c-code-warn:      #F0C879;

  /* -- the blueprint ground. Two weights: the console section carries it at
        full strength, the two diagram sections at a whisper. ------------- */
  --c-blueprint:      rgba(10, 37, 64, 0.055);
  --c-blueprint-soft: rgba(10, 37, 64, 0.04);
  --blueprint-cell:   48px;

  /* -- the ticker. The duration is long on purpose: fast enough to read as
        motion, slow enough that no word is hard to read. ---------------- */
  --tick-dur:         38s;

  /* -- the value gallery ------------------------------------------------ */
  --gcard-min:        210px;

  /* -- the engineering rail --------------------------------------------- */
  --rail-head:        380px;
  --rail-card:        300px;
  --rail-card-h:      250px;

  /* -- the transaction state machine ------------------------------------ */
  --sm-cycle:         5s;
  --sm-step:          0.6s;
  --sm-link:          clamp(18px, 3.2vw, 54px);
  --sm-run:           clamp(13px, 2.8vw, 49px);

  /* -- the two ambient gradient fields, hero and contact ---------------- */
  --field-blur:       28px;
  --c-field-1:        rgba(10, 37, 64, 0.20);
  --c-field-2:        rgba(66, 84, 102, 0.20);
  --c-field-3:        rgba(150, 180, 210, 0.30);
  --shot-ground-brightness: .42;
}

/* A CSS background has no <picture>, so it would take the JPEG tier the <img>
   elements never touch — measured, 496 KB against 272 KB. The @supports guard
   is load-bearing: a custom property accepts any text, so an unsupported
   image-set() fails at the point of USE, leaving the section with no
   photograph. The plain url() above is the floor. § 26 of notes. */
@supports (background-image: image-set(url("assets/img/photo-01.avif") type("image/avif"))) {
  :root {
    --photo-one-integration: image-set(
      url("assets/img/photo-01.avif") type("image/avif"),
      url("assets/img/photo-01.jpg")  type("image/jpeg"));
    --mosaic-2: image-set(
      url("assets/img/photo-02.avif") type("image/avif"),
      url("assets/img/photo-02.jpg")  type("image/jpeg"));
    --mosaic-3: image-set(
      url("assets/img/photo-01.avif") type("image/avif"),
      url("assets/img/photo-01.jpg")  type("image/jpeg"));
  }
}


/* 2. RESET · rationale: docs/styles-notes.md § 2 */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Anchor targets clear the sticky header (WCAG 2.2 · 2.4.11). */
  scroll-padding-top: var(--sp-4xl);
}

body { min-height: 100vh; }


img,
picture,
video,
canvas {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button { background: none; border: 0; }

ul[class],
ol[class] { list-style: none; padding: 0; }

table { border-collapse: collapse; }


[hidden] { display: none !important; }


/* 3. BASE — elements and typography · rationale: docs/styles-notes.md § 3 */

body {
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--ff-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  font-weight: var(--fw-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis-weight: none;
}

h1, h2, h3, h4 {
  color: var(--c-text);
  text-wrap: balance;
  overflow-wrap: break-word;
}

h1 {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  font-weight: var(--fw-display);
}

h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-h2);
}

h3 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-h3);
}

h4 {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
}

p { text-wrap: pretty; overflow-wrap: break-word; }


a { color: var(--c-accent); }

p a:not(:where(.btn)),
li a:not(:where(.btn)),
address a:not(:where(.btn)) {
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in oklab, currentColor 40%, transparent);
}

@media (hover: hover) {
  p a:not(:where(.btn)):hover,
  li a:not(:where(.btn)):hover,
  address a:not(:where(.btn)):hover {
    color: var(--c-accent-hover);
    text-decoration-color: currentColor;
  }
}

p a:not(:where(.btn)):active,
li a:not(:where(.btn)):active,
address a:not(:where(.btn)):active { color: var(--c-accent-active); }

/* Inline <code> in body copy. Design system § Mono usage rules. Scoped with
   :not(pre code): this rule paints a chip, and inside a <pre> it tiled a
   light bar behind every line of the console. Narrow the wrong selector
   rather than stacking an override on it. */
code:not(pre code) {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  color: var(--c-text);
  background: var(--c-sunken);
  border-radius: var(--r-xs);
  padding-inline: 0.15em;
}
pre code {
  font-family: var(--ff-mono);
  letter-spacing: var(--ls-code);
}

address { font-style: normal; }

caption { text-align: left; }

::selection {
  background: var(--c-accent-muted);
  color: var(--c-text);
}


:focus-visible {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
  border-radius: inherit;
}


input:focus,
textarea:focus,
select:focus {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
}

/* Every anchor target and every focusable clears the sticky header. */
[id] { scroll-margin-top: var(--sp-4xl); }


/* 4. UTILITIES — build-contract §2. Markup agents use these and must not · rationale: docs/styles-notes.md § 4 */

/* -- .sr-only --------------------------------------------------------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* -- .skip-link — first focusable element in <body> -------------------- */
.skip-link {
  position: absolute;
  inset-inline-start: var(--sp-md);
  inset-block-start: var(--sp-md);
  z-index: var(--z-skip);
  display: inline-flex;
  align-items: center;
  min-height: var(--h-control-sm);
  padding-inline: var(--sp-md);

  background: var(--c-surface);
  box-shadow: var(--shadow-overlay);
  color: var(--c-text);
  border: var(--bw-hairline) solid var(--c-border-strong);
  border-radius: var(--r-md);
  font-size: var(--fs-body-sm);
  text-decoration: none;

  transform: translateY(calc(-100% - var(--sp-2xl)));
}
.skip-link:focus-visible { transform: none; }

/* -- .eyebrow ---------------------------------------------------------- */
/* A pill, not a line of small caps. inline-block alone is not enough:
   .section__head is a grid and a grid item stretches to its track anyway —
   rendered, that gave a 720px pill with three words in it. fit-content plus
   justify-self covers the grid, flex and block cases together. */
.eyebrow {
  display: inline-block;
  inline-size: fit-content;
  justify-self: start;
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  text-transform: uppercase;
  color: var(--c-text-3);
  text-wrap: pretty;

  padding: var(--sp-3xs) var(--sp-xs);
  border: var(--bw-hairline) solid var(--c-border);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  box-shadow: var(--shadow-1);
}

/* -- .lede ------------------------------------------------------------- */
.lede {
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  letter-spacing: var(--ls-body-lg);
  color: var(--c-text-2);
  max-width: var(--measure);
  text-wrap: balance;
}

/* -- .prose ------------------------------------------------------------ */
.prose {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--c-text-2);
  max-width: var(--measure);
  text-wrap: pretty;
}

/* -- .mono ------------------------------------------------------------- */
.mono {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  font-variant-numeric: tabular-nums;
}

/* -- horizontal scroll containers -------------------------------------- */

.demo__log,
.flow__canvas {
  scrollbar-width: thin;
  scrollbar-color: var(--c-border-strong) transparent;
}

/* -- .card ------------------------------------------------------------- */

.card {
  background: var(--c-raised);
  border: var(--bw-hairline) solid var(--c-border-card);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-raised);
  padding: var(--sp-lg);
}
@media (min-width: 900px) {
  .card { padding: var(--sp-xl); }
}

/* -- .btn -------------------------------------------------------------- */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--c-text);
  --btn-border: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  min-height: var(--h-control);
  padding-inline: var(--sp-lg);
  border: var(--bw-hairline) solid var(--btn-border);
  border-radius: var(--r-md);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  letter-spacing: -0.006em;
  font-weight: var(--fw-medium);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}

.btn--primary {
  --btn-bg: var(--c-accent);
  --btn-fg: var(--c-accent-ink);
  --btn-border: transparent;
}
.btn--secondary {
  --btn-bg: transparent;
  --btn-fg: var(--c-text);
  --btn-border: var(--c-border-strong);
}


@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover   { --btn-bg: var(--c-accent-hover); }
  .btn--secondary:hover { --btn-bg: var(--c-overlay-hover); --btn-border: var(--c-border-hover); }
}

.btn--primary:active   { --btn-bg: var(--c-accent-active); transform: translateY(var(--nudge-press)); }
.btn--secondary:active { --btn-bg: var(--c-overlay-active); transform: translateY(var(--nudge-press)); }

.btn--secondary:focus-visible { --btn-border: var(--c-accent); }


.btn:disabled,
.btn[aria-disabled="true"] {
  --btn-fg: var(--c-text-3);
  --btn-border: var(--c-border-strong);
  border-style: dashed;
  cursor: not-allowed;
  transform: none;
}
.btn--primary:disabled,
.btn--primary[aria-disabled="true"] {
  --btn-bg: var(--c-raised);
}
.btn--secondary:disabled,
.btn--secondary[aria-disabled="true"] {
  --btn-bg: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .btn:disabled:hover,
  .btn[aria-disabled="true"]:hover {
    --btn-fg: var(--c-text-3);
    --btn-border: var(--c-border-strong);
  }
  .btn--primary:disabled:hover,
  .btn--primary[aria-disabled="true"]:hover { --btn-bg: var(--c-raised); }
  .btn--secondary:disabled:hover,
  .btn--secondary[aria-disabled="true"]:hover { --btn-bg: transparent; }
}

/* -- .chip ------------------------------------------------------------- */
/* Status pills. Never interactive. The leading glyph is what carries the
   state when colour is unavailable. */
.chip {
  --chip-fill: var(--c-sunken);
  --chip-fg: var(--c-text-2);

  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  padding-inline: var(--sp-xs);
  border-radius: var(--r-pill);
  background: var(--chip-fill);
  color: var(--chip-fg);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  text-transform: uppercase;
  white-space: nowrap;
}

.chip--ok   { --chip-fill: var(--c-ok-muted);   --chip-fg: var(--c-ok); }
.chip--warn { --chip-fill: var(--c-warn-muted); --chip-fg: var(--c-warn); }
.chip--err  { --chip-fill: var(--c-err-muted);  --chip-fg: var(--c-err); }

.chip__glyph {
  margin-inline-end: var(--sp-2xs);
  font-size: 0.85em;
  line-height: 1;
  color: currentColor;
}


/* 5. LAYOUT PRIMITIVES · rationale: docs/styles-notes.md § 5 */

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

.container--narrow { max-width: var(--container-narrow); }

.section {
  position: relative;
  padding-block: var(--section-y);
}


.section--loose { padding-block: var(--section-y); }


.section__head {
  display: grid;
  gap: var(--sp-md);
  margin-block-end: var(--sp-2xl);
  max-width: var(--container-narrow);
}
.section__head .eyebrow { margin-block-end: calc(var(--sp-xs) * -1); }

.section__title {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-h2);
  color: var(--c-text);
  text-wrap: balance;
}


.line {
  display: block;
  overflow: hidden;
  padding-block: var(--line-bleed);
  margin-block: calc(var(--line-bleed) * -1);
}
.line__inner { display: block; }


.section__note {
  margin-block-start: var(--sp-2xl);
  padding-inline-start: var(--sp-lg);
  border-inline-start: var(--bw-hairline) solid var(--c-border-strong);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--c-text-2);
  max-width: var(--measure);
  text-wrap: pretty;
}


.is-hidden { display: none !important; }


/* 5. GROUND ALTERNATION AND COMPOSITION  (iteration 2, § 3.1 and § 3.2) · rationale: docs/styles-notes.md § 5 */


#how-it-works,
#developers,
#engineering,
#getting-started {
  background: var(--c-sunken);
}


.section { padding-block-end: var(--section-y); }


#getting-started {
  padding-block-start: var(--section-y-loose);
}

/* -- CENTRED: text-only sections --------------------------------------- */


#contact > .container { max-width: var(--container-narrow); }


#one-integration > .container > .section__head,
#developers      > .container > .section__head { max-width: none; }

#one-integration > .container > .section__head > .section__title,
#developers      > .container > .section__head > .section__title {
  max-width: var(--measure-head);
}

/* -- SPLIT: the text rail and the object column ------------------------- */
@media (min-width: 1200px) {
  #how-it-works    > .container,
  #marketing       > .container {
    display: grid;
    grid-template-columns: minmax(0, var(--rail)) minmax(0, 1fr);

    grid-template-rows: auto 1fr;
    column-gap: var(--split-gap);
    align-items: start;
  }
  #how-it-works > .container { grid-template-rows: auto auto 1fr; }


  #how-it-works    > .container > .section__head,
  #marketing       > .container > .section__head {
    grid-column: 1;
    margin-block-end: 0;
    max-width: none;
  }


  #how-it-works > .container > .section__head { grid-row: 1; }
  #how-it-works > .container > .statement     { grid-column: 1; grid-row: 2; }
  #how-it-works > .container > .demo {
    grid-column: 2;
    grid-row: 1 / span 3;
    margin-block-start: 0;

    align-self: center;
  }
  #how-it-works > .container > .section__note { grid-column: 1; grid-row: 3; }


  /* §5 — head and the section's CTA in the rail, the card grid beside. */
  #marketing > .container > .section__head { grid-row: 1; }
  #marketing > .container > .bento {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin-block-start: 0;
  }
  #marketing > .container > .steps__cta {
    grid-column: 1;
    grid-row: 2;
    margin-block-start: var(--sp-2xl);
  }


  #how-it-works    .section__head .lede,
  #marketing       .section__head .lede { max-width: none; }


  #marketing .bento { grid-template-columns: repeat(2, 1fr); }
}


/* 6. NAV — sticky header, scroll progress line, mobile disclosure panel · rationale: docs/styles-notes.md § 6 */

.nav {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-nav);
  background: var(--c-bg);
  border-block-end: var(--bw-hairline) solid var(--c-border);
}

/* The single permitted backdrop-filter on the page, and only once scrolled. */
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  /* 92% and 18px, not 80% and 12px. At the old pair a sentence of body text
     was legibly readable through the bar and read as a rendering fault, not
     as glass. What passes under it is now a tone, never a word. */
  .nav.is-scrolled {
    background: color-mix(in oklab, var(--c-bg) 92%, transparent);
    -webkit-backdrop-filter: blur(var(--blur-nav)) saturate(1.2);
    backdrop-filter: blur(var(--blur-nav)) saturate(1.2);

    box-shadow: var(--shadow-nav);
  }
}
@media (prefers-reduced-transparency: reduce) {
  .nav.is-scrolled {
    background: var(--c-bg);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    box-shadow: var(--shadow-nav);
  }
}

.nav__progress {
  position: absolute;
  inset-inline-start: 0;
  inset-block-end: 0;
  width: 100%;
  height: var(--bw-rule);
  background: var(--c-accent);
  transform: scaleX(0);
  transform-origin: left center;
  pointer-events: none;
  /* No transition — JS writes this every rAF frame. */
}

.nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  min-height: var(--nav-h);
}

.nav__brand,
.footer__home {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  color: var(--c-text);
  text-decoration: none;
  border-radius: var(--r-sm);
  flex: none;
}


.nav__mark,
.footer__mark {
  flex: none;
  width: var(--size-icon);
  height: var(--size-icon);
  color: currentColor;
}

.nav__wordmark,
.footer__wordmark {
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-medium);
  letter-spacing: -0.01em;
  color: var(--c-text);
}


.nav__primary { display: none; }
.nav__list { display: none; }


.nav__cta {
  display: none;
  flex: none;
  min-height: var(--h-control-sm);

  padding-inline: var(--sp-md);
}


.nav__panel-cta {
  display: flex;
  width: 100%;
  margin-block-start: var(--sp-md);
}

@media (min-width: 480px) {
  .nav__cta       { display: inline-flex; }
  .nav__panel-cta { display: none; }
}

.nav__toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--h-control-sm);
  height: var(--h-control-sm);
  border-radius: var(--r-md);
  color: var(--c-text-2);
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .nav__toggle:hover { color: var(--c-text); background: var(--c-overlay-hover); }
}

.nav__toggle-icon {
  width: var(--size-icon);
  height: var(--size-icon);
}
.nav__toggle-bar { transform-origin: center; transform-box: fill-box; }

/* Two bars fold into an ✕. Transform only — never geometry. */
.nav__toggle.is-open .nav__toggle-bar--top    { transform: translateY(var(--burger-shift)) rotate(45deg); }
.nav__toggle.is-open .nav__toggle-bar--bottom { transform: translateY(calc(var(--burger-shift) * -1)) rotate(-45deg); }


.nav__panel {
  background: var(--c-bg);
  border-block-end: var(--bw-hairline) solid var(--c-border);
  box-shadow: var(--shadow-overlay);
  padding-block: var(--sp-md);
}

.nav__panel-list {
  display: grid;
  gap: var(--sp-2xs);
}

.nav__panel-link {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  min-height: var(--h-control);
  padding-inline: var(--sp-xs);
  border-radius: var(--r-sm);
  color: var(--c-text-2);
  font-size: var(--fs-body-sm);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .nav__panel-link:hover { color: var(--c-text); background: var(--c-overlay-hover); }
}
/* Active item in the panel gets a 4px accent dot, not an underline. */
.nav__panel-link::before {
  content: "";
  width: var(--sp-2xs);
  height: var(--sp-2xs);
  border-radius: var(--r-pill);
  background: transparent;
  flex: none;
}
.nav__panel-link.is-active { color: var(--c-text); }
.nav__panel-link.is-active::before { background: var(--c-accent); }

@media (min-width: 900px) {
  :root { --nav-h: var(--nav-h-lg); }

  .nav__primary { display: block; margin-inline: auto; }

  .nav__list {
    display: flex;
    align-items: center;
    gap: var(--sp-lg);
  }

  .nav__link {
    display: inline-flex;
    align-items: center;
    min-height: var(--target-min);
    padding-block: var(--sp-xs);
    border-radius: var(--r-sm);
    color: var(--c-text-2);
    font-size: var(--fs-body-sm);
    text-decoration: none;
    /* Reserve the rule at every state so the active item does not shift. */
    border-block-end: var(--bw-hairline) solid transparent;
  }
  .nav__link:hover { color: var(--c-text); }
  .nav__link.is-active,
  .nav__link[aria-current="true"] {
    color: var(--c-text);
    border-block-end-color: var(--c-accent);
  }

  .nav__toggle { display: none; }
  .nav__panel  { display: none; }
}


/* 6. THE SECTION RAIL  —  TASK 2.7 · rationale: docs/styles-notes.md § 6 */


.rail { display: none; }

@media (min-width: 1200px) {
  .rail {
    display: block;
    position: fixed;
    inset-block-start: 50%;
    inset-inline-start: var(--rail-inset);

    transform: translateY(-50%);
    z-index: var(--z-sticky);
    /* Decorative and unreachable. See the block comment. */
    pointer-events: none;
  }

  .rail__list {
    display: grid;
    gap: var(--sp-md);
    list-style: none;
    padding: 0;
    margin: 0;
  }

  /* The row is tick + label. The tick is the ::before so the label element
     carries nothing but the label. */
  .rail__item {
    display: flex;
    align-items: center;
    gap: var(--sp-sm);
    color: var(--c-border-strong);
  }

  .rail__item::before {
    content: "";
    display: block;
    inline-size: var(--rail-tick);
    block-size: var(--bw-hairline);
    background: currentColor;

    transform: scaleX(var(--rail-tick-rest));
    transform-origin: 0 50%;
  }

  .rail__item.is-active {
    color: var(--c-text);
  }
  .rail__item.is-active::before {
    block-size: var(--bw-rule);
    transform: none;
  }

  /* Below 1520 there is no room for a label at all — see the measured
     arithmetic in the block comment. */
  .rail__label { display: none; }
}

@media (min-width: 1520px) {
  .rail__label {
    display: block;
    font-family: var(--ff-mono);
    font-size: var(--fs-mono-sm);
    line-height: var(--lh-mono);
    letter-spacing: var(--ls-mono);
    font-weight: var(--fw-mono);
    white-space: nowrap;

    opacity: 0;
  }
  .rail__item.is-active .rail__label { opacity: 1; }
}


/* 7. FOOTER · rationale: docs/styles-notes.md § 7 */

.footer {
  padding-block: var(--section-y-tight);
  border-block-start: var(--bw-hairline) solid var(--c-border);
}

.footer__inner {
  display: grid;
  gap: var(--sp-2xl);
}

.footer__brand {
  display: grid;
  justify-items: start;
  gap: var(--sp-md);
  max-width: var(--measure);
}

.footer__positioning {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-text-2);
  max-width: var(--measure);
}

.footer__address {
  display: grid;
  gap: var(--sp-2xs);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--c-text-3);
}
.footer__address-line { display: block; }
.footer__address-line--name {
  color: var(--c-text-2);
  font-weight: var(--fw-medium);
  letter-spacing: 0.01em;
}

.footer__address-line--email { overflow-wrap: anywhere; }

/* "AGB is a trading name of…" — same register as the address above it, not
   a second paragraph of body copy. */
.footer__trading {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--c-text-3);
  max-width: var(--measure);
}

.footer__columns {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2xl);
}

.footer__list { display: grid; gap: var(--sp-xs); }

.footer__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--target-min);
  padding-block: var(--sp-2xs);
  border-radius: var(--r-sm);
  color: var(--c-text-2);
  font-size: var(--fs-body-sm);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) {
  .footer__link:hover { color: var(--c-text); }
}

.footer__base {
  display: grid;
  gap: var(--sp-md);
  margin-block-start: var(--sp-2xl);
  padding-block-start: var(--sp-lg);
  border-block-start: var(--bw-hairline) solid var(--c-border);
}

.footer__legal,
.footer__copyright {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--c-text-3);
  max-width: var(--measure);
}

@media (min-width: 480px) {
  .footer__columns { flex-direction: row; }
}

@media (min-width: 640px) {
  .footer__inner {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
  }
  .footer__base {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
  }
  .footer__copyright { white-space: nowrap; }
}


/* 8. PAGE SECTION 1 — #hero · rationale: docs/styles-notes.md § 8 */

.section--hero {
  position: relative;

  z-index: 0;
  /* Contains the radial glow so it can never widen the page at 360px. */
  overflow: hidden;
  padding-block-start: var(--sp-5xl);

  padding-block-end: var(--section-y);
}

/* The page's single permitted gradient. No element is provided for it. */
.section--hero::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 50%;
  translate: -50% 0;
  width: min(var(--container), 150%);
  aspect-ratio: 2 / 1;
  background: radial-gradient(circle closest-side at 50% 35% in oklab,
              var(--c-glow), transparent);
  pointer-events: none;
  z-index: -1;
}


.section--hero::after {
  content: "";
  position: absolute;
  inset: -10%;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(to right,  var(--c-texture) var(--bw-hairline), transparent 0),
    linear-gradient(to bottom, var(--c-texture) var(--bw-hairline), transparent 0);
  background-size: var(--texture-cell) var(--texture-cell);

  -webkit-mask-image: radial-gradient(115% 78% at 50% 32%, black, transparent 68%);
          mask-image: radial-gradient(115% 78% at 50% 32%, black, transparent 68%);
}


.hero {
  display: grid;
  gap: var(--sp-2xl);
}

.hero__col { min-width: 0; }   /* or .flow__svg refuses to shrink and the
                                  grid blows out. */

.hero__col--text {
  display: grid;
  justify-items: start;
  align-content: start;
  gap: var(--sp-lg);
}

.hero__eyebrow { margin-block-end: calc(var(--sp-xs) * -1); }

.hero__title {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  font-weight: var(--fw-display);
  color: var(--c-text);
  text-wrap: balance;
  /* No overflow-wrap, no hyphens: no word in this headline may split. */
}


.hero__title-break { display: none; }
@media (min-width: 480px) {
  .hero__title-break { display: inline; }
}

.hero__sub { max-width: var(--measure); }

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-md);
  width: 100%;
  margin-block-start: var(--sp-md);
}


.hero__cta,
.hero__cta-secondary { width: 100%; }

@media (min-width: 640px) {
  .hero__actions { width: auto; }
  .hero__cta,
  .hero__cta-secondary { width: auto; }
}


/* 1100, not 1200, and 1.02fr rather than 1fr. The h1 grew in this run and the
   old even split broke it into four narrow lines; the copy column needs the
   extra sliver and the title needs a measure of its own. The 15ch cap is what
   actually holds the line count — the wider column alone was not enough. */
@media (min-width: 1100px) {
  .hero--split {
    grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
    column-gap: var(--sp-2xl);
    align-items: center;
  }


  .hero__title {
    font-size: var(--fs-hero-split);
    line-height: var(--lh-h1);
    letter-spacing: var(--ls-h1);
    max-inline-size: 15ch;
  }
}


/* 9. PAGE SECTION 2 — #how-it-works · flow diagram, failover demo, statement · rationale: docs/styles-notes.md § 9 */


.svg-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* -- the diagram ------------------------------------------------------- */

.flow {
  display: grid;
  gap: var(--sp-xl);
  margin-block-start: var(--sp-2xl);
}


.flow--hero { margin-block-start: 0; }

.flow--hero .flow__canvas--v .flow__svg { max-height: var(--flow-hero-cap); }


@media (min-width: 1200px) {
  .flow--hero .flow__canvas--h {
    --svg-label: 19px;
    --svg-sub:   19px;
  }

  .flow--hero .flow__canvas--h .flow__node-glyph { font-size: var(--svg-glyph); }
}


.flow__canvas {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.flow__svg {
  display: block;
  width: 100%;
  height: auto;
  min-width: var(--diagram-min-w);
  font-family: var(--ff-sans);
}

.flow__canvas--h { display: none; }
.flow__canvas--v { display: block; }


.flow__canvas--v .flow__svg {
  max-width: 26rem;
  margin-inline: auto;

  /* min() so the floor can never exceed the room. At 360 the panel left this
     canvas 270px while --diagram-min-w held the SVG at 320, and the panel
     clipped the surplus — the Provider C node came off mid-box, with no
     scrollbar to say so. The horizontal canvas keeps its hard floor;
     crushing its nodes is worse than scrolling. This one is vertical. */
  min-width: min(var(--diagram-min-w), 100%);
}

/* Below the 900px switch the canvas takes the panel's inner width rather
   than sitting inside its padding: at 270px the labels fall under 10px.
   width:auto because the inherited 100% resolves against the containing
   block, so the margins would only OFFSET the box, not widen it. */
@media (max-width: 899.98px) {
  .flow--hero .flow__canvas--v {
    width: auto;
    margin-inline: calc(var(--sp-lg) * -1);
  }
}

/* Base edge — always visible, always arrowheaded. */
.flow__edge {
  fill: none;
  stroke: var(--c-border-strong);
  stroke-width: 1.5;
  marker-end: url(#agb-arrow-base);
}


.flow__pulse {
  fill: none;
  stroke: none;
}

.flow__node { cursor: pointer; }


.flow__node-box {
  fill: var(--c-raised);
  stroke: var(--c-border-strong);
  stroke-width: 1.25;
}
.flow__node--engine .flow__node-box { stroke-width: 1.5; }


.flow__node-label,
.flow__node-glyph {
  font-family: var(--ff-mono);
  font-size: var(--svg-label);
  letter-spacing: 0.02em;
  font-weight: var(--fw-mono);
  fill: var(--c-text-2);
}
.flow__node-glyph { text-anchor: start; }

.flow__canvas--v .flow__node-glyph { font-size: var(--svg-sub); }

.flow__node-sub {
  font-family: var(--ff-mono);
  font-size: var(--svg-sub);
  letter-spacing: 0.02em;
  font-weight: var(--fw-mono);
  fill: var(--c-text-2);
}


.flow__node[data-state="idle"] .flow__node-box {
  stroke: var(--c-border-strong);
  fill: var(--c-raised);
}


.flow__node--engine[data-state="idle"] .flow__node-box {
  stroke: var(--c-accent);
  fill: var(--c-accent-muted);
}
.flow__node--engine[data-state="idle"] .flow__node-label { fill: var(--c-text); }
.flow__node[data-state="active"] .flow__node-box {
  stroke: var(--c-accent);
  fill: var(--c-accent-muted);
  stroke-width: 2;
}
.flow__node[data-state="ok"] .flow__node-box {
  stroke: var(--c-ok);
  fill: var(--c-ok-muted);
}
.flow__node[data-state="warn"] .flow__node-box {
  stroke: var(--c-warn);
  fill: var(--c-warn-muted);
  stroke-dasharray: 4 3;
}
.flow__node[data-state="failed"] .flow__node-box {
  stroke: var(--c-err);
  fill: var(--c-err-muted);
  stroke-dasharray: 2 3;
}

.flow__node[data-state="active"] .flow__node-label,
.flow__node[data-state="ok"] .flow__node-label,
.flow__node[data-state="warn"] .flow__node-label { fill: var(--c-text); }
.flow__node[data-state="failed"] .flow__node-label { fill: var(--c-text-2); }

.flow__node[data-state="ok"] .flow__node-glyph     { fill: var(--c-ok); }
.flow__node[data-state="warn"] .flow__node-glyph   { fill: var(--c-warn); }
.flow__node[data-state="failed"] .flow__node-glyph { fill: var(--c-err); }

/* Selection sits on top of whatever data-state says. */
.flow__node.is-selected .flow__node-box   { stroke-width: 2; }
.flow__node.is-selected .flow__node-label { fill: var(--c-text); }
.flow__node.is-dimmed                     { opacity: 0.55; }

/* Edge state. */
.flow__edge[data-state="idle"] {
  stroke: var(--c-border-strong);
  marker-end: url(#agb-arrow-base);
}
.flow__edge[data-state="active"] {
  stroke: var(--c-accent);
  marker-end: url(#agb-arrow-accent);
}
.flow__edge[data-state="ok"] {
  stroke: var(--c-ok);
  marker-end: url(#agb-arrow-ok);
}
.flow__edge[data-state="warn"] {
  stroke: var(--c-warn);
  stroke-dasharray: 4 3;
  marker-end: url(#agb-arrow-warn);
}
.flow__edge[data-state="failed"] {
  stroke: var(--c-err);
  stroke-dasharray: 2 3;
  marker-end: url(#agb-arrow-err);
}


.flow__edges:has(.is-lit) .flow__edge:not(.is-lit) { stroke-opacity: 0.35; }


.flow__node:focus-visible {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
}
.flow__node:focus-visible .flow__node-box { stroke-width: 2; }

.flow__node[data-state="idle"]:focus-visible .flow__node-box { stroke: var(--c-focus); }

/* Markers do not inherit paint from the referencing path. */
.flow__arrow--base   path { fill: var(--c-border-strong); }
.flow__arrow--accent path { fill: var(--c-accent); }
.flow__arrow--ok     path { fill: var(--c-ok); }
.flow__arrow--warn   path { fill: var(--c-warn); }
.flow__arrow--err    path { fill: var(--c-err); }

/* -- the shared detail panel ------------------------------------------- */
.flow__detail {
  background: var(--c-raised);
  border: var(--bw-hairline) solid var(--c-border-card);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-raised);
  padding: var(--sp-lg);
  /* Reserve the tallest item's height so swapping never jumps the page.
     A fixed floor, not an animated height. */
  min-height: 11rem;
}

.flow__detail-title {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
  color: var(--c-text);
  margin-block-end: var(--sp-xs);
}

.flow__detail-body {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text-2);
  max-width: var(--measure);
  text-wrap: pretty;
}

/* -- the failover demo ------------------------------------------------- */
.demo {
  display: grid;
  justify-items: start;
  gap: var(--sp-md);
  margin-block-start: var(--sp-2xl);
}

.demo__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-md);
  width: 100%;
}
.demo__btn { width: 100%; }


.demo__status {
  min-height: calc(var(--fs-mono-sm) * var(--lh-mono));
  color: var(--c-text-3);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono);
  letter-spacing: var(--ls-mono);
}


.demo[data-demo-state="running"] .demo__status { color: var(--c-text-2); }


.demo__log {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  background: var(--c-raised);
  border: var(--bw-hairline) solid var(--c-border-card);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-raised);
}

.demo__table {
  width: 100%;
  font-variant-numeric: tabular-nums;
}

.demo__caption {
  color: var(--c-text-3);
  text-transform: uppercase;
  padding: var(--sp-sm) var(--sp-sm);
  border-block-end: var(--bw-hairline) solid var(--c-border);
}

.demo__table th {
  text-align: left;
  color: var(--c-text-3);
  text-transform: uppercase;
  font-weight: var(--fw-mono);
  padding: var(--sp-sm) var(--sp-sm);
  border-block-end: var(--bw-hairline) solid var(--c-border);
  white-space: nowrap;
}


.demo__row { border-block-start: var(--bw-hairline) solid var(--c-border); }
.demo__row:first-child { border-block-start: 0; }

.demo__cell {
  padding: var(--sp-sm) var(--sp-sm);
  text-align: left;
  vertical-align: middle;
}
.demo__cell--attempt {
  white-space: nowrap;
  color: var(--c-text);
  /* Reserved at every state so the active rule cannot shift the column. */
  border-inline-start: var(--bw-rule) solid transparent;
}
.demo__cell--provider { white-space: nowrap; color: var(--c-text-2); }
.demo__cell--result   { white-space: nowrap; }

.demo__row[data-state="pending"] .demo__cell,
.demo__row[data-state="pending"] .demo__cell--attempt,
.demo__row[data-state="pending"] .demo__cell--provider { color: var(--c-text-3); }


.demo__note {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--c-text-3);
  max-width: var(--measure);
}


.statement {
  margin-block-start: var(--sp-2xl);
  padding-block-start: var(--sp-lg);
  border-block-start: var(--bw-hairline) solid var(--c-border);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body-lg);
  letter-spacing: var(--ls-body-lg);
  color: var(--c-text);
  max-width: var(--measure);
  text-wrap: pretty;
}

@media (min-width: 480px) {
  .demo__caption,
  .demo__table th,
  .demo__cell { padding-inline: var(--sp-lg); }
}

@media (min-width: 640px) {
  .demo__controls { width: auto; }
  .demo__btn { width: auto; }
}

@media (min-width: 900px) {
  .flow__canvas--h { display: block; }
  .flow__canvas--v { display: none; }
  .flow__detail { padding: var(--sp-xl); }
}


/* 10. REMOVED IN ITERATION 5 — was PAGE SECTION 2, #boundary · rationale: docs/styles-notes.md § 10 */

/* 11. PAGE SECTION 4 — #one-integration · the bento grid and the · rationale: docs/styles-notes.md § 11 */


.bento {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-md);
  list-style: none;
  padding: 0;
  margin: 0;
}

.bento__cell {
  background: var(--c-raised);
  border: var(--bw-hairline) solid var(--c-border-card);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-raised);
  padding: var(--sp-lg);
  min-width: 0;
}


.bento--sequence { counter-reset: agb-step; }
.bento--sequence .bento__cell { counter-increment: agb-step; }


.cap-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-sm);
}


.cap-card__step {
  display: block;
  font-family: var(--ff-mono);
  font-size: var(--fs-h3);
  line-height: 1;
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  color: var(--c-text-3);
  font-variant-numeric: tabular-nums;
  margin-block-end: var(--sp-2xs);
}
.cap-card__step::before { content: counter(agb-step, decimal-leading-zero); }

.bento:not(.bento--sequence) .cap-card__step { display: none; }


.cap-card__title {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-h3);
  color: var(--c-text);
}

.cap-card__body {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text-2);
  max-width: var(--measure);
  text-wrap: pretty;
}

.cap-card__detail {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-text-3);
  max-width: var(--measure);
  text-wrap: pretty;
}


.cap-card__toggle {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  /* Pinned to the foot of the cell so DETAIL aligns across the row. */
  margin-block-start: auto;
  min-height: var(--target-min);
  padding-inline: var(--sp-xs);
  margin-inline-start: calc(var(--sp-xs) * -1);
  border-radius: var(--r-sm);
  background: none;
  color: var(--c-text-3);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  text-transform: uppercase;
  cursor: pointer;
}


.cap-card__detail { display: none; }


.cap-card:has(:focus-visible) .cap-card__detail,
.cap-card.is-open             .cap-card__detail { display: block; }


@media (hover: hover) and (pointer: fine) {
  .cap-card__toggle:hover { color: var(--c-text-2); }


  .cap-card:hover,
  .cap-card:has(:focus-visible) {
    background: var(--c-raised-hover);
    border-color: var(--c-edge-hover);
  }
}


.cap-card:has(:focus-visible) { border-color: var(--c-edge-hover); }

@media (min-width: 640px) {

  .bento { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 900px) {
  .bento { grid-template-columns: repeat(3, 1fr); }
  .bento__cell { padding: var(--sp-xl); }
  .bento__cell--wide-lg { grid-column: span 2; }

}


/* 12. PAGE SECTION 4 — #developers · the API facts list · rationale: docs/styles-notes.md § 12 */


.integration { margin-block: var(--sp-2xl); }


.integration__canvas {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--c-border-strong) transparent;
}

.integration__svg {
  display: block;
  width: 100%;
  height: auto;
  min-width: var(--diagram-min-w);
  font-family: var(--ff-mono);
}


.integration__canvas--h { display: none; }
.integration__canvas--v .integration__svg {
  max-width: 26rem;
  margin-inline: auto;
}

@media (min-width: 1024px) {
  .integration__canvas--h { display: block; }
  .integration__canvas--v { display: none; }
}


.integration[data-integration-state="without"] [data-int-layer="without"] { display: block; }
.integration[data-integration-state="without"] [data-int-layer="with"]    { display: none; }

/* ---- the drawing ------------------------------------------------------ */


.integration__link {
  fill: none;
  stroke: var(--c-border-strong);
  stroke-width: 1.5;
  stroke-linecap: round;
}


.integration__link--direct { stroke-width: 1.4; }


.integration__link--in { stroke: var(--c-border-hover); stroke-width: 2; }

.integration__node-box {
  fill: var(--c-raised);
  stroke: var(--c-border-strong);
  stroke-width: 1.25;
}


.integration__node--hub .integration__node-box {
  fill: var(--c-sunken);
  stroke: var(--c-border-hover);
  stroke-width: 1.5;
}


.integration__tag-box {
  fill: var(--c-raised);
  stroke: var(--c-border);
}

.integration__node-label,
.integration__node-sub,
.integration__tag-label,
.integration__caption {
  font-family: var(--ff-mono);
  font-weight: var(--fw-mono);
  letter-spacing: var(--ls-mono);
  fill: var(--c-text-3);
}
.integration__node-label { fill: var(--c-text-2); }
.integration__node--hub .integration__node-label { fill: var(--c-text); }

/* ---- the toggle ------------------------------------------------------- */

.integration__controls {
  display: flex;
  margin-block-start: var(--sp-lg);
}


.integration__toggle {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  text-transform: uppercase;
}


.integration__toggle::before {
  content: "";
  inline-size: var(--sp-xs);
  block-size: var(--sp-xs);
  border: var(--bw-hairline) solid currentColor;
  border-radius: var(--r-xs);
}
.integration__toggle[aria-pressed="true"]::before { background: currentColor; }


.integration__toggle[aria-pressed="true"] {
  --btn-bg: var(--c-overlay-active);
  --btn-border: var(--c-border-hover);
}
@media (hover: hover) and (pointer: fine) {
  .integration__toggle[aria-pressed="true"]:hover { --btn-border: var(--c-text-3); }
}

.facts {
  display: grid;
  list-style: none;
  padding: 0;
  margin-block-start: var(--sp-2xl);
  border-block-start: var(--bw-rule) solid var(--c-border-strong);
  font-size: var(--fs-body);
  max-width: var(--measure);
}

.facts__item {
  padding-block: var(--sp-lg);
  border-block-end: var(--bw-hairline) solid var(--c-border);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--c-text-2);
  text-wrap: pretty;
}


@media (min-width: 900px) {
  .facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--sp-xl);
    max-width: none;
  }
}


/* 12. PAGE SECTION 5 — #engineering · the readiness grid and the status · rationale: docs/styles-notes.md § 12 */


.bento--ready { align-items: start; }


.bento--ready { gap: var(--sp-sm); }

@media (min-width: 640px) {
  .bento--ready { gap: var(--sp-md); }
}
@media (min-width: 900px) {
  .bento--ready { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .bento--ready { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}


.ready-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;

  gap: var(--sp-xs);
  padding-block: var(--sp-md);
  padding-inline: var(--sp-lg);

  /* THE DEFAULT STATE IS ROADMAP. See the header note. */
  --pill-label:      "Roadmap";
  --pill-fg:         var(--c-text-3);
  --pill-bg:         transparent;
  --pill-edge:       var(--c-border-strong);
  --pill-edge-style: dashed;
  --pill-mark:       transparent;
}


@media (min-width: 640px) {
  .ready-card { padding: var(--sp-lg); }
}

.ready-card[data-readiness="beta"] {
  --pill-label:      "Beta";
  --pill-fg:         var(--c-text);
  --pill-bg:         var(--c-sunken);
  --pill-edge:       var(--c-text);
  --pill-edge-style: solid;

  --pill-mark:       linear-gradient(to right,
                       currentColor 0 50%, transparent 50% 100%);
}

.ready-card[data-readiness="available"] {
  --pill-label:      "Available";
  --pill-fg:         var(--c-accent);
  --pill-bg:         var(--c-accent-muted);
  --pill-edge:       var(--c-accent);
  --pill-edge-style: solid;
  --pill-mark:       currentColor;
}


.ready-card__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2xs);
  padding-block: var(--sp-3xs);
  padding-inline: var(--sp-xs);
  border: var(--bw-hairline) var(--pill-edge-style) var(--pill-edge);
  border-radius: var(--r-pill);
  background: var(--pill-bg);
  color: var(--pill-fg);
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  line-height: var(--lh-mono);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  text-transform: uppercase;
  white-space: nowrap;
}


.ready-card__pill::before {
  content: "";
  flex: none;
  width: var(--sp-xs);
  height: var(--sp-xs);
  border: var(--bw-hairline) solid currentColor;
  border-radius: var(--r-xs);
  background: var(--pill-mark);
}

/* The word. This single declaration is what makes the attribute the only
   edit — see the header note. */
.ready-card__pill::after { content: var(--pill-label); }


.ready-card__title {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
  color: var(--c-text);
  text-wrap: pretty;
}

.ready-card__body {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  letter-spacing: var(--ls-body-sm);
  color: var(--c-text-2);
  max-width: var(--measure);
  text-wrap: pretty;
}

/* 13. PAGE SECTION 5 — #marketing · the separate service line · rationale: docs/styles-notes.md § 13 */


.section--marketing {

  padding-block-start: var(--section-y);
  padding-block-end:   var(--section-y);
  border-block-start: var(--bw-rule) solid var(--c-marketing);

  --c-edge-hover: var(--c-marketing);


  --stagger:       var(--stagger-slow);
  --dur-entrance:  var(--dur-entrance-slow);
  --rise-reveal:   var(--rise-reveal-slow);
  --dur-lift:      260ms;
  --dur-spot:      420ms;
  --spot-size:     26rem;
}

.eyebrow--marketing { color: var(--c-marketing); }


.bento--marketing .bento__cell { border-color: var(--c-marketing-edge); }

@media (hover: hover) and (pointer: fine) {
  .bento--marketing .cap-card:hover { border-color: var(--c-marketing); }
}


.section--marketing .btn--primary {
  --btn-bg: var(--c-marketing);
  --btn-fg: var(--c-marketing-ink);
}
@media (hover: hover) and (pointer: fine) {
  .section--marketing .btn--primary:hover { --btn-bg: var(--c-marketing-hover); }
}
.section--marketing .btn--primary:active { --btn-bg: var(--c-marketing-active); }


/* The nav's accent used to be muted to grey while the ochre band was on
   screen — the other half of the same guard. With the accent now ink there is
   nothing to mute and nothing to collide with, and muting it only weakened
   the active state. Removed with the gap it belonged to. */


/* 14. PAGE SECTION 6 — #getting-started · rationale: docs/styles-notes.md § 14 */

.steps { display: grid; }

.step {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-lg);
  align-items: start;
  padding-block: var(--sp-xl);
  border-block-start: var(--bw-hairline) solid var(--c-border);
}
.step:first-child { border-block-start: 0; padding-block-start: 0; }

/* --c-text-dim is permitted only at >=24px. --fs-h2 is 28->44px, so this
   clears it at every width, including 360. */
.step__num {
  font-size: var(--fs-h2);
  line-height: 1;
  letter-spacing: var(--ls-h2);
  font-weight: var(--fw-body);
  color: var(--c-text-dim);
  font-variant-numeric: tabular-nums;
}

.step__body { display: grid; gap: var(--sp-xs); min-width: 0; }

/* The heading level is correct (section h2 -> h3); the size is a class
   decision, per build contract §4. */
.step__title {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-medium);
  color: var(--c-text);
}

.steps__closing {
  margin-block-start: var(--sp-2xl);
  max-width: var(--measure);
}

.steps__cta { margin-block-start: var(--sp-xl); }
.steps__cta .btn { width: 100%; }

@media (min-width: 480px) {
  .steps__cta .btn { width: auto; }
}


/* 15. PAGE SECTION 7 — #contact · rationale: docs/styles-notes.md § 15 */

/* 15. LIVE — the enquiry route · rationale: docs/styles-notes.md § 15 */

.contact {
  display: grid;
  gap: var(--sp-2xl);
  max-width: var(--container-narrow);
}


.contact__address {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-md);
}

.contact__email {
  font-family: var(--ff-mono);
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-mono);
  font-weight: var(--fw-mono);
  overflow-wrap: anywhere;
}


.contact__copy {
  min-height: var(--h-control-sm);
  padding-inline: var(--sp-md);
}


.contact__copy.is-copied { --btn-border: var(--c-ok); }


.contact__copy-status {
  flex-basis: 100%;
  min-height: calc(var(--fs-mono-sm) * var(--lh-mono));
  color: var(--c-text-2);
}

.contact__include-title {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
  color: var(--c-text);
  margin-block-end: var(--sp-md);
}


.contact__include-list { display: grid; }

.contact__include-item {
  padding-block: var(--sp-sm);
  border-block-start: var(--bw-hairline) solid var(--c-border);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--c-text-2);
  max-width: var(--measure);
}


/* 15. MOTHBALLED — the contact form · rationale: docs/styles-notes.md § 15 */

.field { display: grid; gap: var(--sp-2xs); min-width: 0; }

.field__label {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-text-2);
}
/* The label stays neutral in the error state — turning it red doubles the
   alarm for no extra information. */

.field__req,
.field__opt {
  font-size: var(--fs-caption);
  color: var(--c-text-3);
}

.field__input {
  width: 100%;
  min-height: var(--h-control);
  padding-inline: var(--sp-sm);
  border: var(--bw-strong) solid var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-sunken);
  color: var(--c-text);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}
@media (hover: hover) and (pointer: fine) {
  .field__input:hover { border-color: var(--c-border-hover); }
}
.field__input:focus { border-color: var(--c-accent); }
.field__input[aria-invalid="true"] { border-color: var(--c-err); }
.field__input:disabled {
  background: var(--c-raised);
  border-color: var(--c-border);
  color: var(--c-text-disabled);
  cursor: not-allowed;
}


.field__select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-end: var(--sp-2xl);
  background-image:
    linear-gradient(45deg,  transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-size: var(--select-arrow) var(--select-arrow);

  background-position:
    right calc(var(--sp-lg) + var(--select-arrow) / 2) center,
    right var(--sp-lg) center;
  background-repeat: no-repeat;
  cursor: pointer;
}
.field__select option { background: var(--c-raised); color: var(--c-text); }

.field__textarea {
  min-height: var(--h-textarea);
  padding-block: var(--sp-sm);
  line-height: 1.6;
  resize: vertical;
}

.field__hint {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--c-text-3);
  max-width: var(--measure);
}


.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2xs);
  margin-block-start: var(--sp-xs);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-err);
  max-width: var(--measure);
}
.field__error:empty { display: none; }

.field--consent { gap: var(--sp-xs); }

.checkbox {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-sm);
  align-items: start;
  padding-block: var(--sp-2xs);
  cursor: pointer;
}

.checkbox__input {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  width: var(--target-min);
  height: var(--target-min);
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.checkbox__box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--size-check);
  height: var(--size-check);
  margin-block-start: var(--sp-3xs);
  border: var(--bw-strong) solid var(--c-border-strong);
  border-radius: var(--r-xs);
  background: var(--c-sunken);
  color: var(--c-accent-ink);
}
.checkbox__box svg { opacity: 0; }

/* Adjacent-sibling selectors — no :has() needed, works everywhere. */
.checkbox__input:checked + .checkbox__box {
  background: var(--c-accent);
  border-color: var(--c-accent);
}
.checkbox__input:checked + .checkbox__box svg { opacity: 1; }
.checkbox__input:focus-visible + .checkbox__box {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
}

.checkbox__text {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-text-2);
  max-width: var(--measure);
}


.contact-form { display: grid; gap: var(--sp-lg); }

.contact-form__legend {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--c-text-3);
  max-width: var(--measure);
}

.contact-form__actions { display: grid; }

.contact-form__submit {
  position: relative;
  /* Enough inline padding that swapping the label for a spinner cannot
     change the button's width. */
  padding-inline: var(--sp-2xl);
}

.btn__label { display: inline-block; }

.btn__spinner {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  width: var(--size-spinner);
  height: var(--size-spinner);
  margin-block-start: calc(var(--size-spinner) / -2);
  margin-inline-start: calc(var(--size-spinner) / -2);
  border: var(--bw-focus) solid currentColor;
  border-block-start-color: transparent;
  border-radius: var(--r-pill);
  opacity: 0;
}
.contact-form__submit.is-loading .btn__label  { opacity: 0; }
.contact-form__submit.is-loading .btn__spinner { opacity: 1; }

.contact-form__status {

  margin-block-start: var(--sp-lg);
  color: var(--c-text-2);
  max-width: var(--measure);
}
.contact-form__status:empty { display: none; }
.contact-form__status.is-error   { color: var(--c-err); }
.contact-form__status.is-success { color: var(--c-ok); }

.contact__success { margin-block-start: var(--sp-lg); }
.contact__success-title {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
  color: var(--c-text);
  margin-block-end: var(--sp-xs);
}
.contact__success-title:focus-visible {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
}

@media (min-width: 480px) {
  .contact-form__actions { justify-items: start; }
}

@media (min-width: 900px) {
  .contact__success { padding: var(--sp-xl); }
}


/* 16. MOTION LAYER · rationale: docs/styles-notes.md § 16 */

@media (prefers-reduced-motion: no-preference) {

  html { scroll-behavior: smooth; }

  /* ---- controls: hover / focus / press micro-transitions -------------- */
  .btn,
  .nav__link,
  .nav__panel-link,
  .nav__toggle,
  .footer__link,

  .field__input,
  .checkbox__box,
  .cap-card__toggle,
  .skip-link,
  p a, li a, address a {
    transition:
      background-color calc(var(--dur-micro) * var(--motion)) var(--ease-out),
      border-color     calc(var(--dur-micro) * var(--motion)) var(--ease-out),
      color            calc(var(--dur-micro) * var(--motion)) var(--ease-out),
      outline-color    calc(var(--dur-micro) * var(--motion)) var(--ease-out),
      text-decoration-color calc(var(--dur-micro) * var(--motion)) var(--ease-out),
      opacity          calc(var(--dur-micro) * var(--motion)) var(--ease-out),
      transform        calc(var(--dur-standard) * var(--motion)) var(--ease-out);
  }

  /* The press is a colour-only change plus a 1px nudge, at --dur-instant. */
  .btn:active { transition-duration: calc(var(--dur-instant) * var(--motion)); }


  @media (hover: hover) and (pointer: fine) {
    .cap-card {
      transition:
        transform        calc(var(--dur-lift)  * var(--motion)) var(--ease-out),
        background-color calc(var(--dur-lift)  * var(--motion)) var(--ease-out),
        border-color     calc(var(--dur-lift)  * var(--motion)) var(--ease-out);
    }
    .cap-card:hover {
      transform: translateY(calc(var(--nudge-card) * -1));
      z-index: var(--z-raised);
    }
  }


  /* ---- the burger folding into an ✕ ---------------------------------- */
  .nav__toggle-bar {
    transition: transform calc(var(--dur-standard) * var(--motion)) var(--ease-standard);
  }

  /* ---- 1. the flow diagram ------------------------------------------- */
  .flow__edge,
  .flow__node-box,
  .flow__node-label,
  .flow__node-glyph,
  .flow__node {
    transition:
      stroke         calc(var(--dur-standard) * var(--motion)) var(--ease-out),
      fill           calc(var(--dur-standard) * var(--motion)) var(--ease-out),
      stroke-opacity calc(var(--dur-standard) * var(--motion)) var(--ease-out),
      opacity        calc(var(--dur-standard) * var(--motion)) var(--ease-out);
  }


  .flow__pulse.is-lit {
    stroke: var(--c-accent);
    stroke-width: 2;
    stroke-linecap: round;
    fill: none;
    stroke-dasharray: 24 400;
    animation: agb-comet calc(var(--dur-ambient) * var(--motion)) linear infinite;
  }

  .flow__pulse[data-edge="agb-pa"]     { animation-delay: calc(var(--stagger) * 2); }
  .flow__pulse[data-edge="agb-pb"]     { animation-delay: calc(var(--stagger) * 3); }
  .flow__pulse[data-edge="agb-pc"]     { animation-delay: calc(var(--stagger) * 4); }
  .flow__pulse[data-edge="pa-issuer"]  { animation-delay: calc(var(--stagger) * 6); }
  .flow__pulse[data-edge="pb-issuer"]  { animation-delay: calc(var(--stagger) * 7); }
  .flow__pulse[data-edge="pc-issuer"]  { animation-delay: calc(var(--stagger) * 8); }

  @keyframes agb-comet {
    from { stroke-dashoffset: 424; }
    to   { stroke-dashoffset: 0; }
  }

  /* ---- 2. attempt-log rows stepping in -------------------------------- */
  .demo__row {
    transition: color calc(var(--dur-micro) * var(--motion)) var(--ease-out);
  }
  .demo__row.is-done .demo__cell {
    animation: agb-step-in calc(150ms * var(--motion)) var(--ease-out) both;
  }
  @keyframes agb-step-in {
    from { opacity: 0; transform: translateY(calc(var(--rise-step) * -1)); }
    to   { opacity: 1; transform: none; }
  }


  [data-reveal].is-revealed {
    animation: agb-rise calc(var(--dur-entrance) * var(--motion)) var(--ease-emphasis) both;
    animation-delay: calc(var(--i, 0) * var(--stagger) * var(--motion));
  }

  @keyframes agb-rise {
    from { opacity: 0; transform: translateY(var(--rise-reveal)); }
    to   { opacity: 1; transform: none; }
  }


  .btn__label,
  .btn__spinner {
    transition: opacity calc(var(--dur-micro) * var(--motion)) var(--ease-out);
  }
  .contact-form__submit.is-loading .btn__spinner {
    animation: agb-spin calc(700ms * var(--motion)) linear infinite;
  }
  @keyframes agb-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
  }

  /* ---- mobile nav panel entrance -------------------------------------- */
  .nav__panel.is-open {
    animation: agb-panel-in calc(var(--dur-standard) * var(--motion)) var(--ease-standard) both;
  }
  @keyframes agb-panel-in {
    from { opacity: 0; transform: translateY(calc(var(--rise-panel) * -1)); }
    to   { opacity: 1; transform: none; }
  }


  /* rationale: docs/styles-notes.md § 16 */


  .integration__link {
    --int-delay: calc(var(--int-order, 0) * var(--draw-step));
    stroke-dasharray: 1 1;
    stroke-dashoffset: 0;
    opacity: 1;
    transition:
      stroke-dashoffset calc(var(--dur-draw) * var(--motion)) var(--ease-out)
                        calc(var(--int-delay) * var(--motion)),
      opacity calc(var(--dur-micro) * var(--motion)) linear
              calc((var(--int-delay) + var(--dur-draw) * var(--draw-head)) * var(--motion));
  }

  .integration[data-reveal]:not(.is-revealed) .integration__link,
  .integration.is-undrawn .integration__link {
    stroke-dashoffset: 1;
    opacity: 0;
  }
  /* The re-arm must be instantaneous or it plays backwards first. */
  .integration.is-undrawn .integration__link { transition: none; }


  .integration [data-int-order="1"] { --int-order: 0; }
  .integration [data-int-order="2"] { --int-order: 1; }
  .integration [data-int-order="3"] { --int-order: 2; }
  .integration [data-int-order="4"] { --int-order: 3; }
  .integration [data-int-order="5"] { --int-order: 4; }
  .integration [data-int-order="6"] { --int-order: 5; }
  .integration [data-int-order="7"] { --int-order: 6; }

  /* The draw IS the entrance. See above. */
  .integration.is-revealed { animation: none; }


  @media (hover: hover) and (pointer: fine) {

    .cap-card::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 1;
      border-radius: inherit;
      padding: var(--bw-hairline);
      background: radial-gradient(var(--spot-size) circle
                    at calc(50% + var(--spot-x, 0px)) calc(50% + var(--spot-y, 0px)),
                    var(--c-spot-edge), transparent 62%);
      -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0);
      -webkit-mask-composite: xor;
              mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0);
              mask-composite: exclude;
      opacity: 0;
      pointer-events: none;
      transition: opacity calc(var(--dur-spot) * var(--motion)) var(--ease-out);
    }


    .cap-card:hover::after,
    .cap-card:has(:focus-visible)::after { opacity: 1; }
  }


  .section__head.is-revealed:has(.line) { animation: none; }


  .section__head.is-revealed [data-split-lines] .line__inner {
    animation: agb-line-rise calc(var(--dur-line) * var(--motion)) var(--ease-emphasis) both;
    animation-delay: calc(var(--i, 0) * var(--stagger-line) * var(--motion));
  }
  [data-split-lines].is-settled .line__inner { animation: none; }

  @keyframes agb-line-rise {
    from { opacity: 0; transform: translateY(100%); }
    to   { opacity: 1; transform: none; }
  }


  [data-stagger].is-revealed { animation: none; }
  [data-stagger].is-revealed > * {
    animation: agb-rise calc(var(--dur-entrance) * var(--motion)) var(--ease-emphasis) both;
    animation-delay: calc(var(--i, 0) * var(--stagger) * var(--motion));
  }


  .section--hero::after {
    animation: agb-drift calc(var(--dur-drift) * var(--motion)) linear infinite;
  }
  @keyframes agb-drift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(var(--texture-cell), var(--texture-cell), 0); }
  }


  .rail__item {
    transition: color calc(var(--dur-standard) * var(--motion)) var(--ease-out);
  }
  .rail__item::before {
    transition: transform calc(var(--dur-standard) * var(--motion)) var(--ease-emphasis);
  }
  .rail__label {
    transition: opacity calc(var(--dur-standard) * var(--motion)) var(--ease-out);
  }


  @media (hover: hover) and (pointer: fine) {
    [data-magnetic] {
      transform: translate(var(--mag-x, 0px), var(--mag-y, 0px));
    }
    [data-magnetic]:active {
      transform: translate(var(--mag-x, 0px),
                           calc(var(--mag-y, 0px) + var(--nudge-press)));
    }
  }


  /* ---- 12. the ticker ------------------------------------------------- */
  /* Two identical groups in the track and a keyframe that travels exactly
     -50%: that pairing is what makes the loop seamless. Change one without
     the other and there is a visible jump once per cycle. */
  .ticker__track {
    animation: agb-tick calc(var(--tick-dur) * var(--motion)) linear infinite;
  }
  @keyframes agb-tick {
    to { transform: translate3d(-50%, 0, 0); }
  }


  /* ---- 13. the transaction state machine ------------------------------ */
  .sm__node {
    transition: color        calc(var(--dur-standard) * var(--motion)) var(--ease-out),
                border-color calc(var(--dur-standard) * var(--motion)) var(--ease-out),
                background   calc(var(--dur-standard) * var(--motion)) var(--ease-out);
  }
  .sm.is-live .sm__node {
    animation: agb-sm-on calc(var(--sm-cycle) * var(--motion)) linear infinite;
    animation-delay: calc(var(--i) * var(--sm-step) * var(--motion));
  }
  .sm.is-live .sm__link::after {
    animation: agb-sm-run calc(var(--sm-cycle) * var(--motion)) linear infinite;
    animation-delay: calc((var(--i) * var(--sm-step) + 0.3s) * var(--motion));
  }
  @keyframes agb-sm-on {
    0%, 6%   { color: var(--c-text-2);      border-color: var(--c-border-strong); background: var(--c-bg); }
    10%, 40% { color: var(--c-accent-ink);  border-color: var(--c-accent);        background: var(--c-accent); }
    55%,100% { color: var(--c-text-2);      border-color: var(--c-border-strong); background: var(--c-bg); }
  }
  @keyframes agb-sm-run {
    0%       { opacity: 0; transform: translateX(0); }
    10%      { opacity: 1; }
    38%      { opacity: 1; transform: translateX(var(--sm-run)); }
    46%,100% { opacity: 0; transform: translateX(var(--sm-run)); }
  }


  /* ---- 14. the FAQ chevron -------------------------------------------- */
  .faq__q::after {
    transition: transform calc(var(--dur-standard) * var(--motion)) var(--ease-emphasis);
  }


  /* ---- 15. diagrams that draw themselves ------------------------------ */
  /* Set from script off getTotalLength(), released on first intersection,
     then unobserved. Plays once. */
  [data-draw] path,
  [data-draw] line,
  [data-draw] polyline {
    stroke-dasharray: var(--len, 1200);
    stroke-dashoffset: var(--len, 1200);
    transition: stroke-dashoffset calc(var(--dur-draw-long) * var(--motion)) var(--ease-expo);
  }
  [data-draw].is-drawn path,
  [data-draw].is-drawn line,
  [data-draw].is-drawn polyline {
    stroke-dashoffset: 0;
  }
}

/* ------------------------------------------------------------------------
   THE REDUCED-MOTION END STATES. Everything above lives inside the
   no-preference gate, so under `reduce` none of it runs. These are the
   states the page must still be readable in — and the draw one is NOT
   optional: without it a reduced-motion visitor gets a diagram whose lines
   are permanently offset to invisible.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  [data-draw] path,
  [data-draw] line,
  [data-draw] polyline {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  /* The lifecycle stops, and the first node stays lit so the diagram still
     reads as a sequence with a beginning rather than five inert pills. */
  .sm__node:first-child {
    color: var(--c-accent-ink);
    border-color: var(--c-accent);
    background: var(--c-accent);
  }
}

/* Both continuous loops are CSS animations, so they are paused from the same
   observer that already gates the hero canvas — off-screen and on tab-hide.
   An animation nobody can see is still work the compositor is doing. */
.ticker__track,
.sm.is-live .sm__node,
.sm.is-live .sm__link::after {
  animation-play-state: running;
}
.is-paused .ticker__track,
.sm.is-paused .sm__node,
.sm.is-paused .sm__link::after {
  animation-play-state: paused;
}

/* 17. ELEVATION ROLES AND THE HERO PRODUCT PANEL · rationale: docs/styles-notes.md § 17 */


.integration__canvas { box-shadow: var(--shadow-2); }


.flow--hero {
  background: var(--c-surface);
  border: var(--bw-hairline) solid var(--c-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  padding: var(--sp-lg);
}
/* Inside a panel, a second shadow is noise. The detail strip becomes an
   inset plate instead. */
.flow--hero .flow__detail {
  box-shadow: none;
  background: var(--c-sunken);
}


.btn--primary { box-shadow: var(--shadow-1); }

@media (hover: hover) and (pointer: fine) {
  .btn--primary:hover {
    box-shadow: var(--shadow-2);
    transform: translateY(calc(var(--nudge-lift) * -1));
  }
}
/* The press has to beat the hover rise, so it is re-declared after it. */
.btn--primary:active {
  box-shadow: var(--shadow-1);
  transform: translateY(var(--nudge-press));
}


.hero__mesh {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 200px), transparent 100%);
          mask-image: linear-gradient(to bottom, black calc(100% - 200px), transparent 100%);

  transform: translateY(var(--shot-shift, 0px));
}


/* 18. PHOTOGRAPHY — the frame · rationale: docs/styles-notes.md § 18 */

.shot {
  /* The box exists before the pixels do. */
  aspect-ratio: 4 / 3;
  margin: 0;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-2);

  background-color: var(--c-sunken);
  background-image: var(--shot-lqip, none);
  background-size: cover;
  background-position: center;
}

/* <picture> is inline by default, so the percentage height below would resolve
   against it rather than .shot and collapse the frame. */
.shot picture { display: contents; }

/* Taller than the frame so the parallax shift has somewhere to travel without
   ever exposing an edge. */
.shot img {
  display: block;
  width: 100%;
  height: 108%;
  object-fit: cover;

  /* One treatment family: each role tunes brightness off this base, never
     saturation. The old saturate(.92) was an 8% cut and did nothing. */
  filter: grayscale(1) contrast(1.06);

  transform: translateY(var(--shot-shift, 0px));
}

/* Pin a layer only where the transform actually changes. Under reduce,
   --shot-shift never moves. */
@media (prefers-reduced-motion: no-preference) {
  .shot img { will-change: transform; }
}

/* THE BAND — a strip, not a picture. Shortened from clamp(220px,32vw,380px):
   at that height it was a framed photograph parked between two sections and
   read as decoration. Short, with both edges dissolved, the ribs become
   rhythm instead of a subject. */
.shot--band {
  position: relative;
  aspect-ratio: auto;
  height: auto;
  margin-block: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: hidden;
  background: var(--c-sunken);

  display: grid;
  grid-template-columns: var(--mosaic-cols);
  grid-template-rows: var(--mosaic-row);
  gap: var(--mosaic-gap);
}
/* The <img> holds the widest cell; the other two are pseudo elements, so no
   empty alt enters the tree for decoration. THE THREE FILES MUST ALL DIFFER —
   the reference put photo-03 in cells 1 and 2 and the same ceiling rendered
   twice side by side. */
.shot--band img {
  grid-column: 1;
  grid-row: 1;
  height: 100%;
  width: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.02) brightness(1.06);
}
.shot--band::before,
.shot--band::after {
  content: "";
  grid-row: 1;
  background-size: cover;
  background-position: center;
  filter: grayscale(1) contrast(1.04);
}
.shot--band::before {
  grid-column: 2;
  background-image: var(--mosaic-2);
}
.shot--band::after {
  grid-column: 3;
  background-image: var(--mosaic-3);
  background-position: 40% 60%;
}

/* Below the breakpoint three cells across a phone are three slivers. The
   mosaic drops to the widest frame alone and keeps the strip's proportions. */
@media (max-width: 719.98px) {
  .shot--band {
    grid-template-columns: 1fr;
    grid-template-rows: var(--mosaic-row-sm);
  }
  .shot--band::before,
  .shot--band::after { display: none; }
}
/* The 34rem --split cap went with the last in-flow frame; the one remaining
   .shot--split is the ground, which sets max-width:none. A --split frame that
   returns to the flow is a direct child of its section's .container — never
   in a grid of its own, never after .container closes. § 18 of notes. */

/* ------------------------------------------------------------------
   THE TWO DARK SECTIONS — #one-integration and #getting-started. In both the
   photograph is not IN the section, it IS the section, and no component
   inside gains a dark-mode selector. § 14 of styles-notes.
   ------------------------------------------------------------------ */
.sec--dark {
  position: relative;
  isolation: isolate;
  overflow: hidden;

  /* The floor under the photograph. Negative-z children paint above an
     element's own background, so this shows only while the image loads —
     and is the whole section if images are off. */
  background: var(--c-ink);

  --c-text:          #FFFFFF;
  --c-text-2:        #C6D4E3;
  --c-text-3:        #AEBFD1;
  --c-text-dim:      #98AABE;

  --c-border:        rgba(255, 255, 255, 0.16);
  --c-border-card:   rgba(255, 255, 255, 0.14);
  --c-border-strong: rgba(255, 255, 255, 0.42);
  --c-border-hover:  rgba(255, 255, 255, 0.58);

  /* The primary button inverts here: white fill, navy label. */
  --c-accent:        #FFFFFF;
  --c-accent-hover:  #E6EDF5;
  --c-accent-active: #D6E1EC;
  --c-accent-ink:    #0A2540;
  --c-accent-muted:  rgba(255, 255, 255, 0.10);
  --c-focus:         #FFFFFF;

  --c-surface:       rgba(255, 255, 255, 0.07);
  --c-sunken:        rgba(255, 255, 255, 0.04);
  --c-surface-3:     rgba(255, 255, 255, 0.09);
  --c-raised:        rgba(255, 255, 255, 0.07);
  --c-raised-hover:  rgba(255, 255, 255, 0.11);
  --c-overlay-hover: rgba(255, 255, 255, 0.06);
  --c-overlay-active:rgba(255, 255, 255, 0.10);
  --c-bg:            transparent;

  /* Cast against navy, ink shadows are invisible and white ones are haze. */
  --shadow-1: none;
  --shadow-2: none;
  --shadow-3: none;
}

/* The pill DARKENS its ground here rather than lightening it. The mockup's
   10% white wash is a local scrim running the wrong way: measured, it lifted
   the ground under the label and took the pair to 3.31:1 — the one failure in
   either dark section. A pill is a scrim, so raising it is the fix. */
.sec--dark .eyebrow {
  background: rgba(10, 37, 64, 0.45);
  box-shadow: none;
}

/* Both dark sections dissolve out of the light section above them rather than
   starting at a seam. --dark-fade-from is the ground of whatever sits above,
   so each section names its own. */
.sec--dark::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  block-size: var(--scrim-fade);
  z-index: -1;
  pointer-events: none;
  /* Smoothstep — 1 - (3t^2 - 2t^3) — not linear and not an ease. Measured:
     a straight ramp is continuous in colour and still draws a visible line,
     because the eye catches the RATE turning over (0 per px above the
     boundary, 5 just below). Only a curve with zero velocity at BOTH ends
     removes it. Same reasoning for .shot--band::after. */
  background: linear-gradient(to bottom,
    color-mix(in oklab, var(--dark-fade-from) 100%, transparent)    0%,
    color-mix(in oklab, var(--dark-fade-from)  96%, transparent) 12.5%,
    color-mix(in oklab, var(--dark-fade-from)  84%, transparent)   25%,
    color-mix(in oklab, var(--dark-fade-from)  68%, transparent) 37.5%,
    color-mix(in oklab, var(--dark-fade-from)  50%, transparent)   50%,
    color-mix(in oklab, var(--dark-fade-from)  32%, transparent) 62.5%,
    color-mix(in oklab, var(--dark-fade-from)  16%, transparent)   75%,
    color-mix(in oklab, var(--dark-fade-from)   4%, transparent) 87.5%,
    color-mix(in oklab, var(--dark-fade-from)   0%, transparent)  100%);
}

/* -- #one-integration. Its photograph is a CSS background rather than an
      <img>, because there is no <figure> in this section's markup to hang one
      on and the picture carries no meaning a screen reader needs. ---------- */
#one-integration {
  --dark-fade-from: var(--c-surface-page);
}
#one-integration::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    linear-gradient(var(--scrim-2-angle),
      var(--scrim-2-near) 0%, var(--scrim-2-mid) 48%, var(--scrim-2-far) 100%),
    var(--photo-one-integration) center / cover no-repeat;
}

/* -- #getting-started. Its photograph is a real <figure> already in the
      markup, taken out of flow and stretched behind the content. ---------- */
#getting-started {
  --dark-fade-from: var(--c-ground);
}
/* Raising the scrim is the fix for a failing text pair here — never
   lightening the text.
   z-index -2, not -1: ::before is this section's first child, so at an equal
   z-index the figure paints over it and the top fade vanishes. It did. */
#getting-started .shot--split {
  position: absolute;
  inset: 0;
  z-index: -2;
  margin: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: none;
  background-color: var(--c-ink);
}
#getting-started .shot--split img {
  height: 100%;
  filter: grayscale(1) contrast(1.04) brightness(var(--shot-ground-brightness));
}
#getting-started .shot--split::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(var(--scrim-angle),
    var(--scrim-near) 0%, var(--scrim-mid) 46%, var(--scrim-far) 100%);
}

/* With the scrim flattened both sections still have to be dark rooms, so the
   ground becomes the ink itself and the photographs go. */
@media (prefers-reduced-transparency: reduce) {
  .sec--dark { background: var(--c-ink); }
  .sec--dark::before { display: none; }
  #one-integration::after { display: none; }
  #getting-started .shot--split { display: none; }
}
/* Forced colours: every token these sections re-declare goes back to a system
   colour. Setting only the background left the white-on-navy tokens in force
   over it and the headings rendered white on white. The UA would normally
   override `color`, but a fallback that needs rescuing is not a fallback. */
@media (forced-colors: active) {
  .sec--dark {
    background: Canvas;

    --c-text:          CanvasText;
    --c-text-2:        CanvasText;
    --c-text-3:        CanvasText;
    --c-text-dim:      CanvasText;

    --c-border:        CanvasText;
    --c-border-card:   CanvasText;
    --c-border-strong: CanvasText;
    --c-border-hover:  CanvasText;

    --c-accent:        LinkText;
    --c-accent-hover:  LinkText;
    --c-accent-active: LinkText;
    --c-accent-ink:    Canvas;
    --c-accent-muted:  Canvas;
    --c-focus:         CanvasText;

    --c-surface:       Canvas;
    --c-sunken:        Canvas;
    --c-surface-3:     Canvas;
    --c-raised:        Canvas;
    --c-raised-hover:  Canvas;
    --c-overlay-hover: Canvas;
    --c-overlay-active:Canvas;
    --c-bg:            Canvas;
  }
  .sec--dark::before { display: none; }
  #one-integration::after { display: none; }
  #getting-started .shot--split { display: none; }
}

/* 19. LEGAL PAGES — privacy.html, terms.html, cookies.html · rationale: docs/styles-notes.md § 19 */

.legal-meta {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-text-3);
  margin-block-start: var(--sp-sm);
}

.legal-body > h2 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  letter-spacing: var(--ls-h3);
  font-weight: var(--fw-h3);
  color: var(--c-text);
  margin-block-start: var(--sp-3xl);
  margin-block-end: var(--sp-md);
  padding-block-start: var(--sp-lg);
  border-block-start: var(--bw-hairline) solid var(--c-border);
  max-width: var(--measure);
}

.legal-body > h2:first-child {
  margin-block-start: 0;
  padding-block-start: 0;
  border-block-start: 0;
}

.legal-body > h3 {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
  color: var(--c-text);
  margin-block-start: var(--sp-xl);
  margin-block-end: var(--sp-xs);
  max-width: var(--measure);
}

.legal-body > .prose { margin-block-end: var(--sp-md); }
.legal-body > .prose:last-child { margin-block-end: 0; }

.prose-list {
  list-style: none;
  padding: 0;
  margin-block: var(--sp-md);
  max-width: var(--measure);
  display: grid;
  gap: var(--sp-sm);
}

.prose-list > li {
  position: relative;
  padding-inline-start: var(--sp-lg);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--c-text-2);
  text-wrap: pretty;
}

.prose-list > li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: calc(var(--lh-body) * 0.5em - (var(--bw-rule) / 2));
  inline-size: var(--sp-sm);
  block-size: var(--bw-rule);
  background: var(--c-border-strong);
}

.legal-table {
  inline-size: 100%;
  border-collapse: collapse;
  margin-block: var(--sp-lg);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  text-align: start;
}

.legal-table th,
.legal-table td {
  padding: var(--sp-sm) var(--sp-md);
  border-block-end: var(--bw-hairline) solid var(--c-border);
  vertical-align: top;
  text-align: start;
}

.legal-table thead th {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--c-text-3);
  font-weight: var(--fw-mono);
  border-block-end: var(--bw-hairline) solid var(--c-border-strong);
}

.legal-table td { color: var(--c-text-2); }

@media (max-width: 640px) {
  .legal-table,
  .legal-table thead,
  .legal-table tbody,
  .legal-table tr,
  .legal-table th,
  .legal-table td { display: block; inline-size: 100%; }
  .legal-table thead { position: absolute; inline-size: var(--bw-hairline); block-size: var(--bw-hairline); overflow: hidden; clip-path: inset(50%); }
  .legal-table tr {
    border-block-end: var(--bw-hairline) solid var(--c-border);
    padding-block: var(--sp-sm);
  }
  .legal-table td { border-block-end: 0; padding-inline: 0; }
}

.legal-address {
  display: grid;
  gap: var(--sp-3xs);
  font-style: normal;
  margin-block: var(--sp-md);
}
.legal-address__line { display: block; }


/* 20. ILLUSTRATION SET — five spot marks, inline SVG · rationale: docs/styles-notes.md § 20 */

/* Painted entirely from palette tokens, which is the whole point: inside a
   .sec--dark subtree the same markup inverts with no extra selector, and a
   palette swap carries the illustrations with it. No mark claims anything —
   they are diagrams of the page's own copy, not screenshots of a product. */
.ill {
  inline-size: 100%;
  block-size: auto;
  display: block;
}
.ill rect,
.ill circle {
  stroke: var(--c-border-strong);
  stroke-width: 1.6;
}
.ill .ill-fill      { fill: var(--c-accent); stroke: var(--c-accent); }
.ill .ill-line      { stroke: var(--c-text-3); stroke-width: 1.6; stroke-linecap: round; }
.ill .ill-line--ink { stroke: var(--c-accent-ink); stroke-width: 2; }
.ill .ill-dash      { stroke-dasharray: 3 5; }


/* 21. VALUE GALLERY — the block under the hero · rationale: docs/styles-notes.md § 21 */

.gallery {
  padding-block: clamp(var(--sp-2xl), 6vw, var(--sp-4xl));
  background: var(--c-surface);
  border-block-end: var(--bw-hairline) solid var(--c-border);
}
.gallery__inner {
  inline-size: min(var(--container), 100% - 2 * var(--gutter));
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--gcard-min), 1fr));
  gap: var(--sp-md);
}
.gcard {
  border: var(--bw-hairline) solid var(--c-border-card);
  border-radius: var(--r-lg);
  padding: var(--sp-lg) var(--sp-lg) var(--sp-xl);
  background: var(--c-bg);
  box-shadow: var(--shadow-1);
}
.gcard__art {
  block-size: 92px;
  display: grid;
  place-items: center;
  margin-block-end: var(--sp-md);
  border-radius: var(--r-md);
  background: var(--c-sunken);
  padding: var(--sp-sm) var(--sp-md);
}
.gcard__art .ill { max-inline-size: 130px; }
.gcard__title {
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: var(--ls-h4);
  font-weight: var(--fw-h4);
  margin: 0 0 var(--sp-2xs);
}
.gcard__body {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
  color: var(--c-text-2);
  margin: 0;
}


/* 22. API CONSOLE — #api, and the transaction state machine · rationale: docs/styles-notes.md § 22 */

.tsec {
  position: relative;
  padding-block: var(--section-y);
  background: var(--c-sunken);
  overflow: hidden;
}
.tsec .container { position: relative; z-index: var(--z-raised); }
.tsec__head {
  max-inline-size: var(--measure-head);
  margin-block-end: clamp(var(--sp-lg), 3vw, var(--sp-2xl));
}

/* -- the console itself ------------------------------------------------- */
.console {
  border: var(--bw-hairline) solid var(--c-border-card);
  border-radius: var(--r-lg);
  background: var(--c-console);
  box-shadow: var(--shadow-3);
  overflow: hidden;
}
.console__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-3xs);
  padding: var(--sp-2xs) var(--sp-xs);
  background: var(--c-console-chrome);
  border-block-end: var(--bw-hairline) solid var(--c-console-edge);
}
.console__tab {
  appearance: none;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--c-console-tab);
  padding: var(--sp-2xs) var(--sp-sm);
  border-radius: var(--r-sm);
  min-block-size: var(--target-min);
  transition: background calc(var(--dur-micro) * var(--motion)) var(--ease-out),
              color      calc(var(--dur-micro) * var(--motion)) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .console__tab:hover { color: var(--c-accent-ink); background: var(--c-console-hover); }
}
.console__tab.is-on {
  color: var(--c-console);
  background: var(--c-accent-ink);
}
.console__tab:focus-visible {
  outline: var(--bw-focus) solid var(--c-accent-ink);
  outline-offset: var(--focus-offset);
}
/* The badge is content, not chrome: it is the page saying out loud that no
   host, endpoint or key below is real. It must never be removed or muted
   into invisibility. */
.console__note {
  margin-inline-start: auto;
  font-family: var(--ff-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--c-console-note);
  border: var(--bw-hairline) solid var(--c-console-edge);
  border-radius: var(--r-pill);
  padding: var(--sp-3xs) var(--sp-xs);
  white-space: nowrap;
}
.console__pane {
  margin: 0;
  padding: var(--sp-lg) clamp(var(--sp-md), 2.4vw, var(--sp-xl)) var(--sp-xl);
  overflow-x: auto;
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-code);
  line-height: var(--lh-code);
  color: var(--c-console-text);
  tab-size: 2;
}
.console__pane[hidden] { display: none; }
.console__pane:focus-visible {
  outline: var(--bw-focus) solid var(--c-accent-ink);
  outline-offset: calc(var(--focus-offset) * -1);
}
.tok-c    { color: var(--c-code-comment); font-style: italic; }
.tok-k    { color: var(--c-code-key); }
.tok-s    { color: var(--c-code-str); }
.tok-ok   { color: var(--c-code-ok); }
.tok-warn { color: var(--c-code-warn); }

/* -- the transaction lifecycle ------------------------------------------ */
.sm__wrap { margin-block-start: clamp(var(--sp-xl), 3.4vw, var(--sp-3xl)); }
.sm__cap {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--c-text-3);
  margin: 0 0 var(--sp-sm);
}
.sm {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0;
}
.sm__node {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  padding: var(--sp-2xs) var(--sp-sm);
  border-radius: var(--r-pill);
  border: var(--bw-hairline) solid var(--c-border-strong);
  color: var(--c-text-2);
  background: var(--c-bg);
  white-space: nowrap;
}
.sm__link {
  inline-size: var(--sm-link);
  block-size: var(--bw-hairline);
  background: var(--c-border-strong);
  position: relative;
  opacity: .55;
}
.sm__link::after {
  content: "";
  position: absolute;
  inset-block-start: -2px;
  inset-inline-start: 0;
  inline-size: 5px;
  block-size: 5px;
  border-radius: 50%;
  background: var(--c-accent);
  opacity: 0;
}


/* 23. COMPARISON — #compare · rationale: docs/styles-notes.md § 23 */

.cmp {
  padding-block: var(--section-y);
  background: var(--c-sunken);
}
.cmp .section__title { max-inline-size: 20ch; }
.cmp__wrap {
  overflow-x: auto;
  border-radius: var(--r-lg);
  border: var(--bw-hairline) solid var(--c-border-card);
  background: var(--c-bg);
  box-shadow: var(--shadow-1);
}
.cmp__wrap:focus-visible {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
}
.cmp__table {
  inline-size: 100%;
  border-collapse: collapse;
  /* Below this the three columns stop being readable and the wrapper scrolls
     instead. That is why the wrapper is focusable. */
  min-inline-size: 720px;
}
.cmp__table th,
.cmp__table td {
  text-align: start;
  padding: var(--sp-md) var(--sp-lg);
  vertical-align: top;
  border-block-end: var(--bw-hairline) solid var(--c-border);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body-sm);
}
.cmp__table thead th {
  font-family: var(--ff-mono);
  font-size: var(--fs-mono-sm);
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--c-text-3);
  font-weight: var(--fw-medium);
}
.cmp__table tbody th {
  inline-size: 26%;
  color: var(--c-text);
  font-weight: var(--fw-medium);
}
.cmp__table td { color: var(--c-text-2); }
.cmp__table tr:last-child th,
.cmp__table tr:last-child td { border-block-end: 0; }
/* The AGB column is tinted, and its text is raised to full ink so the tint
   never costs contrast. */
.cmp__mine {
  background: var(--c-accent-muted);
  color: var(--c-text);
}
.cmp__table thead .cmp__mine { color: var(--c-text); }


/* 24. FAQ — #faq · rationale: docs/styles-notes.md § 24 */

.faq { padding-block: var(--section-y); }
.faq__item { border-block-end: var(--bw-hairline) solid var(--c-border); }
.faq__q {
  list-style: none;
  cursor: pointer;
  padding-block: var(--sp-md);
  padding-inline-end: var(--sp-2xl);
  position: relative;
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  color: var(--c-text);
  font-weight: var(--fw-h4);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "";
  position: absolute;
  inset-inline-end: var(--sp-3xs);
  inset-block-start: 50%;
  inline-size: 12px;
  block-size: 12px;
  margin-block-start: -6px;
  border-inline-end: 1.8px solid var(--c-text-3);
  border-block-end: 1.8px solid var(--c-text-3);
  transform: rotate(45deg) translateY(-2px);
}
.faq__item[open] .faq__q::after { transform: rotate(-135deg) translateY(-2px); }
.faq__q:focus-visible {
  outline: var(--bw-focus) solid var(--c-focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--r-xs);
}
.faq__a { padding-block-end: var(--sp-lg); }
.faq__a p {
  margin: 0;
  color: var(--c-text-2);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  max-inline-size: 62ch;
}


/* 25. TICKER — the drifting restatement between #api and #developers · rationale: docs/styles-notes.md § 25 */

.ticker {
  position: relative;
  overflow: hidden;
  padding-block: clamp(var(--sp-md), 2.2vw, var(--sp-xl));
  border-block: var(--bw-hairline) solid var(--c-border);
  background: var(--c-surface);
}
.ticker__track {
  display: flex;
  inline-size: max-content;
}
.ticker__group {
  display: flex;
  gap: clamp(var(--sp-xl), 4vw, var(--sp-3xl));
  padding-inline-end: clamp(var(--sp-xl), 4vw, var(--sp-3xl));
  white-space: nowrap;
}
.ticker__item {
  font-family: var(--ff-mono);
  font-size: clamp(var(--fs-mono-sm), 1.35vw, var(--fs-body-lg));
  letter-spacing: var(--ls-mono);
  text-transform: uppercase;
  color: var(--c-text-3);
}
.ticker__item::after {
  content: "·";
  margin-inline-start: clamp(var(--sp-xl), 4vw, var(--sp-3xl));
  color: var(--c-border-strong);
}
.ticker::before,
.ticker::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inline-size: 12%;
  z-index: var(--z-raised);
  pointer-events: none;
}
.ticker::before { inset-inline-start: 0; background: linear-gradient(to right, var(--c-surface), transparent); }
.ticker::after  { inset-inline-end: 0;  background: linear-gradient(to left,  var(--c-surface), transparent); }


/* 26. ALTERNATING GROUNDS, GRADIENT FIELDS, BLUEPRINT · rationale: docs/styles-notes.md § 26 */

/* The page changes ground five times instead of running one light sheet its
   whole length. Order matters more than the individual values: surface,
   dark, sunken, surface, warm, dark. */
#how-it-works { background: var(--c-surface); }
#developers   { background: var(--c-sunken); }
#engineering  { background: var(--c-surface); }

#marketing {
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--c-marketing) 7%, transparent),
    color-mix(in oklab, var(--c-marketing) 2%, transparent));
}
#marketing .eyebrow {
  background: color-mix(in oklab, var(--c-marketing) 10%, transparent);
  border-color: color-mix(in oklab, var(--c-marketing) 28%, transparent);
}

/* -- the two ambient fields. Blurred radials, out of flow, behind
      everything. They are the only gradients on the page that are not a
      scrim or a fade. ---------------------------------------------------- */
#hero, #contact {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
#hero::before {
  content: "";
  position: absolute;
  inset-block-start: -28%;
  inset-inline-end: -14%;
  inline-size: 78vw;
  block-size: 78vw;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(38% 38% at 32% 30%, var(--c-field-1), transparent 70%),
    radial-gradient(42% 42% at 70% 42%, var(--c-field-2), transparent 72%),
    radial-gradient(46% 46% at 52% 74%, var(--c-field-3), transparent 74%);
  filter: blur(var(--field-blur));
}
/* The gallery below the hero sits on --c-surface, so the hero's closing fade
   has to land on --c-surface too or it stops on a line. */
#hero::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 200px;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--c-surface));
}
#contact::before {
  content: "";
  position: absolute;
  inset-block-end: -35%;
  inset-inline-start: -10%;
  inline-size: 70vw;
  block-size: 70vw;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(40% 40% at 40% 40%, var(--c-field-1), transparent 70%),
    radial-gradient(44% 44% at 66% 60%, var(--c-field-3), transparent 72%);
  filter: blur(calc(var(--field-blur) + 2px));
}

/* -- the blueprint ground. Under the console at full strength, under the two
      diagram sections at a whisper. The radial mask is what stops it being
      graph paper: it exists at the centre and is gone at the edges. ------ */
.tsec--grid::before,
#developers::before,
#how-it-works::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--z-base);
  pointer-events: none;
  background-size: var(--blueprint-cell) var(--blueprint-cell);
  -webkit-mask-image: radial-gradient(130% 100% at 50% 40%, #000 40%, transparent 100%);
          mask-image: radial-gradient(130% 100% at 50% 40%, #000 40%, transparent 100%);
}
.tsec--grid::before {
  background-image:
    linear-gradient(to right,  var(--c-blueprint) var(--bw-hairline), transparent var(--bw-hairline)),
    linear-gradient(to bottom, var(--c-blueprint) var(--bw-hairline), transparent var(--bw-hairline));
  -webkit-mask-image: radial-gradient(120% 90% at 50% 30%, #000 45%, transparent 100%);
          mask-image: radial-gradient(120% 90% at 50% 30%, #000 45%, transparent 100%);
}
#developers::before,
#how-it-works::before {
  background-image:
    linear-gradient(to right,  var(--c-blueprint-soft) var(--bw-hairline), transparent var(--bw-hairline)),
    linear-gradient(to bottom, var(--c-blueprint-soft) var(--bw-hairline), transparent var(--bw-hairline));
}
/* The grid is behind the section's own children, which have to be raised out
   of the way or they inherit its stacking position and lose their own. */
#developers > *,
#how-it-works > * {
  position: relative;
  z-index: var(--z-raised);
}


/* 27. ENGINEERING AS A HORIZONTAL RAIL · rationale: docs/styles-notes.md § 27 */

@media (min-width: 900px) {
  /* clip, never scroll: the rail bleeds past the right margin on purpose and
     without this the whole document grows sideways by the bleed. */
  #engineering { overflow-x: clip; }

  #engineering .container {
    display: grid;
    grid-template-columns: var(--rail-head) minmax(0, 1fr);
    gap: clamp(var(--sp-xl), 4vw, var(--sp-4xl));
    align-items: start;
  }
  /* The heading pins while the cards travel past it. */
  #engineering .section__head {
    position: sticky;
    inset-block-start: calc(var(--nav-h) + var(--sp-2xl));
    margin: 0;
    max-inline-size: none;
  }
  /* flex, NOT grid. The bento cells carry explicit grid-column/grid-row
     placements; grid-auto-flow: column fights them into overlapping cards
     with the text shredded to one word per line. Under flex those
     placements are ignored outright instead of contested. */
  #engineering .bento--ready {
    display: flex;
    /* Explicit, not inherited: the bento's grid rules set align-items on this
       container and a ragged row of card bottoms is what a rail cannot have. */
    align-items: stretch;
    gap: var(--sp-lg);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline-start: 2px;
    padding-block-end: var(--sp-lg);
    padding-inline-end: 22vw;
    margin-inline-end: calc((100vw - var(--container)) / -2);
    scrollbar-width: thin;
    scrollbar-color: var(--c-border-strong) transparent;
  }
  #engineering .bento--ready:focus-visible {
    outline: var(--bw-focus) solid var(--c-focus);
    outline-offset: var(--focus-offset);
  }
  #engineering .bento__cell {
    flex: 0 0 var(--rail-card);
    scroll-snap-align: start;
    min-block-size: var(--rail-card-h);
  }
}


/* 28. CARD LIFT, AND DIAGRAMS THAT DRAW THEMSELVES · rationale: docs/styles-notes.md § 28 */

@media (hover: hover) and (pointer: fine) {
  .ready-card,
  .cap-card,
  .gcard {
    transition: transform  calc(var(--dur-lift) * var(--motion)) var(--ease-emphasis),
                box-shadow calc(var(--dur-lift) * var(--motion)) var(--ease-emphasis),
                border-color calc(var(--dur-micro) * var(--motion)) var(--ease-out);
  }
  .ready-card:hover,
  .cap-card:hover,
  .gcard:hover {
    transform: translateY(calc(var(--nudge-card) * -1));
    box-shadow: var(--shadow-2);
  }
  .gcard:hover { border-color: var(--c-border-strong); }
}

.ready-card,
.cap-card,
.bento__cell { border-radius: var(--r-lg); }
