/* Nocturne — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see readme.md. */
/* ── Typography: the live union.ai faces ─────────────────────────────
   Yellix (UI) and IBM Plex Mono (code), served from the production site's
   own Webflow CDN, which sends `access-control-allow-origin: *`. Replaces
   the Inter @import this system shipped with. Weights match what the live
   site actually loads: 400/500/600 for Yellix, 400/700 for the mono. */
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bdd21a73f26db81f180_Yellix-Regular.otf") format("opentype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bddb82800e2bea44362_Yellix-Medium.otf") format("opentype"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bdd3bb86c06d050b493_Yellix-SemiBold.otf") format("opentype"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/691d182fe284c14edec412ca_IBMPlexMono-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/691d182f3766cd21fbc11742_IBMPlexMono-Bold.ttf") format("truetype"); font-weight: 700; font-style: normal; font-display: swap; }
/* ═══ _shared/union-nocturne.css ═══ */
/* Nocturne — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see readme.md. */
/* ── Typography: the live union.ai faces ─────────────────────────────
   Yellix (UI) and IBM Plex Mono (code), served from the production site's
   own Webflow CDN, which sends `access-control-allow-origin: *`. Replaces
   the Inter @import this system shipped with. Weights match what the live
   site actually loads: 400/500/600 for Yellix, 400/700 for the mono. */
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bdd21a73f26db81f180_Yellix-Regular.otf") format("opentype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bddb82800e2bea44362_Yellix-Medium.otf") format("opentype"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bdd3bb86c06d050b493_Yellix-SemiBold.otf") format("opentype"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/691d182fe284c14edec412ca_IBMPlexMono-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/691d182f3766cd21fbc11742_IBMPlexMono-Bold.ttf") format("truetype"); font-weight: 700; font-style: normal; font-display: swap; }

/* ═══ _shared/union-nocturne.css ═══ */
/* Nocturne — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see readme.md. */
/* ── Typography: the live union.ai faces ─────────────────────────────
   Yellix (UI) and IBM Plex Mono (code), served from the production site's
   own Webflow CDN, which sends `access-control-allow-origin: *`. Replaces
   the Inter @import this system shipped with. Weights match what the live
   site actually loads: 400/500/600 for Yellix, 400/700 for the mono. */
@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bdd21a73f26db81f180_Yellix-Regular.otf") format("opentype"); font-weight: 400; font-style: normal; font-display: swap; }

@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bddb82800e2bea44362_Yellix-Medium.otf") format("opentype"); font-weight: 500; font-style: normal; font-display: swap; }

@font-face { font-family: "Yellix"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/690e3bdd3bb86c06d050b493_Yellix-SemiBold.otf") format("opentype"); font-weight: 600; font-style: normal; font-display: swap; }

@font-face { font-family: "IBM Plex Mono"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/691d182fe284c14edec412ca_IBMPlexMono-Regular.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; }

@font-face { font-family: "IBM Plex Mono"; src: url("https://cdn.prod.website-files.com/690e38b4066a3319f4dad995/691d182f3766cd21fbc11742_IBMPlexMono-Bold.ttf") format("truetype"); font-weight: 700; font-style: normal; font-display: swap; }
#union-inference {
  --color-bg: #000000;        /* live --_theme---background */
  --color-surface: #18191a;   /* live --_theme---card */
  --color-text: #ffffff;      /* live --_theme---heading */
  --color-accent: #fcb51f;    /* live --_theme---accent */ /* review round 7 (Barron): the accent moves to
     the product's blurple — OKLCH hue 289.2, the hue of the app's own Pro
     accent (#9a8fe0, --om-accent-pro) — at the same lightness the steel
     accent held (L 0.660, so the documented ratios survive) and chroma
     in the product blurple's own range (its token sits at C 0.118; the
     accent takes 0.125, from the old steel's 0.030):
     the accent now reads as an accent rather than another neutral. */
  --color-accent-2: #f6c54c; /* the machine-derived stand-in follows: same
     hue, same L 0.734, chroma at the same 2:3 proportion it held */
  --color-divider: color-mix(in srgb, #ffffff 12%, transparent); /* live --_theme---border */

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. */
  --color-neutral-100: #ffffff;
  --color-neutral-200: #f2f3f3;  /* live --_brand---gray-100 */
  --color-neutral-300: #e3e5e6;
  --color-neutral-400: #cccfd1;  /* live --_theme---body (paragraphs) */
  --color-neutral-500: #aeb2b5;
  --color-neutral-600: #81858b;  /* live --_brand---gray-350 */
  --color-neutral-700: #72757a;  /* live --_brand---gray-400 */
  --color-neutral-800: #3a3d40;
  --color-neutral-900: #18191a;  /* live --_brand---dark, the card ground */

  --color-accent-100: #fdf4dc;
  --color-accent-200: #fbe7b4;
  --color-accent-300: #f9d67f;
  --color-accent-400: #f6c54c;
  --color-accent-500: #fcb51f;
  --color-accent-600: #ce9712;
  --color-accent-700: #a5780c;
  --color-accent-800: #785607;
  --color-accent-900: #4c3604;

  --color-accent-2-100: #fdf4dc;
  --color-accent-2-200: #fbe7b4;
  --color-accent-2-300: #f9d67f;
  --color-accent-2-400: #f6c54c;
  --color-accent-2-500: #fcb51f;
  --color-accent-2-600: #ce9712;
  --color-accent-2-700: #a5780c;
  --color-accent-2-800: #785607;
  --color-accent-2-900: #4c3604;

  /* Deck section-divider ground — review round 3: saturation as presence.
     Dividers take a saturated deep indigo (hue 277, the neutral ramp's own
     family; C 0.094 — written when the accent held C 0.030, before the
     round-7 blurple raised it past the ground's) with a lighter bloom and
     a ghost tint of the same hue, while the slide grounds stay
     desaturated. Deck-scale fills only — not interface colors. */
  --color-section: #33270a;
  --color-section-glow: #6b5109;
  --color-section-ghost: #b8860f;

  --font-heading: "Yellix", system-ui, sans-serif;
  --font-heading-weight: 600;  /* live h2/h3 weight */
  --font-body: "Yellix", system-ui, sans-serif;
  /* The mono face this file already @font-faces above. It used to be declared
     in home/style.css only, which meant every other page loading these tokens
     resolved var(--font-code) to nothing and rendered code in Yellix. */
  --font-code: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --space-1: 2.8px;
  --space-2: 5.6px;
  --space-3: 8.4px;
  --space-4: 11.2px;
  --space-6: 16.8px;
  --space-8: 22.4px;

  /* Rounder than the original Nocturne values, to sit with union.ai's live
     system (.5rem / 1rem / 1.5rem). Buttons and pills go fully round below. */
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 0 0 1px rgba(255,255,255,0.06);
  --shadow-md: 0 0 0 1px rgba(255,255,255,0.08), 0 6px 18px rgba(0,0,0,0.55);
  --shadow-lg: 0 0 0 1px rgba(255,255,255,0.11), 0 16px 40px rgba(0,0,0,0.65);
}
#union-inference {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
#union-inference h1, #union-inference h2, #union-inference h3, #union-inference h4 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
#union-inference code, #union-inference pre, #union-inference kbd, #union-inference samp { font-family: var(--font-code); }
#union-inference .lighten {mix-blend-mode:lighten;background-color:transparent}
/* ══════════════════════════════════════════════════════════════════════════
   Components — built with the tokens above. Plain CSS
   on plain HTML: no JavaScript, no build step. Each class is documented in
   readme.md and demonstrated in foundations/ and components/.
   ══════════════════════════════════════════════════════════════════════ */
#union-inference *, #union-inference *::before, #union-inference *::after { box-sizing: border-box; }
#union-inference { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; }
#union-inference h1, #union-inference h2, #union-inference h3, #union-inference h4, #union-inference h5, #union-inference h6 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.05; letter-spacing: -0.01em; margin: 0 0 var(--space-2);
}
#union-inference h1 { font-size: 42px; }
#union-inference h2 { font-size: 32px; }
#union-inference h3 { font-size: 25px; }
#union-inference h4 { font-size: 20px; }
#union-inference h5 { font-size: 16px; }
#union-inference h6 { font-size: 13px; }
#union-inference h6 { letter-spacing: 0.08em; text-transform: uppercase; }
#union-inference p { margin: 0 0 var(--space-3); }
#union-inference a { color: var(--color-accent); text-underline-offset: 3px; }
#union-inference img { display: block; max-width: 100%; }
#union-inference figure { margin: 0; }
#union-inference figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
#union-inference .text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
#union-inference :focus { outline: none; }
#union-inference :focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
#union-inference ::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }
/* — rules — *//* Rules fade to transparent at both ends instead of stopping cleanly — a
   Nocturne signature. The ramp is 48px an end (one deck baseline unit),
   painted from the same divider token. Freestanding rules fade; box
   outlines, in-control separators, and short accent marks stay solid. */
#union-inference .hr {
  height: 1px; border: 0; margin: var(--space-4) 0;
  background: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent);
}
/* — buttons — */
#union-inference .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px; line-height: 1.2; color: var(--color-text); /* matches the .input's 14px —
     the pair sits side by side in sign-up rows */
  background: transparent; border: 1px solid transparent;
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: 999px;
}
#union-inference .btn svg { display: block; }
#union-inference .btn:disabled { opacity: 0.45; cursor: not-allowed; }
#union-inference .btn-primary { color: var(--color-accent); border-color: var(--color-accent); }
#union-inference .btn-primary:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
#union-inference .btn-primary:active { background: color-mix(in srgb, var(--color-accent) 22%, transparent); }
#union-inference .btn-secondary { border-color: var(--color-divider); }
#union-inference .btn-secondary:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
#union-inference .btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
#union-inference .btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
#union-inference .btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
#union-inference .btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
#union-inference .btn-icon { width: 36px; height: 36px; padding: 0; }
#union-inference .btn-block { width: 100%; margin-top: var(--space-2); }
/* — forms — */
#union-inference .field > label {
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
#union-inference .input {
  width: 100%; min-height: 36px; padding: 6px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
#union-inference .input:hover { border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }
#union-inference .input:focus-visible { border-color: var(--color-accent); outline-offset: 0; }
#union-inference textarea.input { min-height: 90px; resize: vertical; }
#union-inference .radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
#union-inference .radio input, #union-inference .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
#union-inference .radio .dot {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}
#union-inference .radio:hover .dot { border-color: var(--color-accent); }
#union-inference .radio input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}
#union-inference .radio input:focus-visible + .dot { outline: 2px solid var(--color-accent); outline-offset: 2px; }
#union-inference .seg {
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
#union-inference .seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; font-size: 14px; cursor: pointer;
}
#union-inference .seg-opt + .seg-opt { border-left: 1px solid var(--color-divider); }
#union-inference .seg-opt:has(input:checked) { color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }
#union-inference .seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
#union-inference .seg-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: -2px; }
/* — cards — */
#union-inference .card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}
#union-inference .card-kicker { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
#union-inference .card-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 19px; line-height: 1.2;
}
#union-inference .card-body { margin: 0; font-size: 15.5px; opacity: 0.8; flex: 1; }
#union-inference .card-meta {
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
}
#union-inference .elev-sm { box-shadow: var(--shadow-sm); }
#union-inference .elev-md { box-shadow: var(--shadow-md); }
#union-inference .elev-lg { box-shadow: var(--shadow-lg); }
/* — tags — */
#union-inference .tag {
  display: inline-flex; align-items: center; font-size: 11px;
  letter-spacing: 0.02em; padding: 3px 10px;
  border-radius: calc(var(--radius-md) * 0.75);
}
#union-inference .tag-accent { background: var(--color-accent-800); color: var(--color-accent-100); }
#union-inference .tag-accent-2 { background: var(--color-accent-2-800); color: var(--color-accent-2-100); }
#union-inference .tag-neutral { background: var(--color-neutral-800); color: var(--color-neutral-100); }
#union-inference .tag-outline { border: 1px solid var(--color-accent); color: var(--color-accent); }
/* — navigation — */
#union-inference .nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: none;
}
#union-inference .nav-brand {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; margin-right: auto;
}
#union-inference .nav a { color: inherit; text-decoration: none; font-size: 15.5px; }
#union-inference .nav a:hover, #union-inference .nav a[aria-current='page'] { color: var(--color-accent); }
/* Docs moved out of the centre group to sit beside the CTA. It is a utility
   exit rather than a section of the site, so it reads a step quieter than the
   items it used to sit among — but only a step: it is still a nav link, and it
   still goes accent on hover like its neighbours. */
#union-inference .nav a.nav-utility { color: var(--color-neutral-500); }
#union-inference .nav a.nav-utility:hover { color: var(--color-accent); }
/* — tables — */
#union-inference .table { width: 100%; border-collapse: collapse; font-size: 14px; }
#union-inference .table th {
  text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  padding: var(--space-2); border-bottom: 1px solid transparent; /* keeps layout; the row paints the fading rule */
}
#union-inference .table td {
  padding: var(--space-2);
  border-bottom: 1px solid transparent;
}
/* Row rules as row-level strips so the end-fade spans the row, not each cell. */
#union-inference .table thead tr {
  background: linear-gradient(to right,
    transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
#union-inference .table tbody tr {
  background: linear-gradient(to right,
    transparent, color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
    color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
#union-inference .table tbody tr:hover {
  /* the hover tint layers over the row rule, which keeps painting */
  background:
    linear-gradient(color-mix(in srgb, var(--color-text) 4%, transparent),
                    color-mix(in srgb, var(--color-text) 4%, transparent)) no-repeat 0 0 / 100% 100%,
    linear-gradient(to right,
      transparent, color-mix(in srgb, var(--color-text) 8%, transparent) 48px,
      color-mix(in srgb, var(--color-text) 8%, transparent) calc(100% - 48px), transparent) no-repeat bottom / 100% 1px;
}
/* — dialog — */
#union-inference .dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}
#union-inference .dialog {
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}
#union-inference .dialog-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px;
}
#union-inference .dialog-body { font-size: 14px; opacity: 0.85; }
#union-inference .dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }
/* ═══ _shared/union-code-theme.css ═══ *//* union-code-theme.css — syntax highlighting for every code block in website/union/.
   Tokens lifted verbatim from ../../color-palette/union-code-theme.css
   ("Union Yellow Dark" v1). That file is the source of truth: if the palette
   changes, re-copy sections 1 and 1c below rather than editing them here.

   Every token meets WCAG AA (4.5:1) on its own card background in both themes.
   Section 2 maps the tokens onto the class names the prototypes already use:
     .tok-*      model-factory, advanced-scheduling
     .sov-tok-*  sovereign-ai
     .code-*     home (emitted by script.js)
*//* ── 1. Tokens ─────────────────────────────────────────────────────────── */
#union-inference {
  /* surface */
  --code-bg:            #18191a;  /* = --brand-dark, the design-system card  */
  --code-border:        #ffffff1f;/* = --theme-border                        */
  --code-radius:        1rem;     /* = --radius-medium                       */

  /* neutrals — carry ~70% of the characters in a snippet */
  --code-fg:            #e6e8ea;  /* identifiers, variables, plain text      */
  --code-param:         #c9ced4;  /* keyword-argument + parameter names      */
  --code-punct:         #9aa0a6;  /* = -> , : ( ) [ ] and all operators      */
  --code-comment:       #848c95;  /* italic — the quietest token             */

  /* accents — four hues, nothing else */
  --code-decorator:     #fdb51f;  /* Union Yellow · @env.task, @flyte.trace  */
  --code-keyword:       #b69bf5;  /* async def await return try except for   */
  --code-constant:      #b69bf5;  /* None True False self cls (italic)       */
  --code-function:      #74b6f2;  /* function definitions + call sites       */
  --code-class:         #5fcbc0;  /* classes, type annotations, builtins     */
  --code-string:        #8fcb7a;  /* string + f-string literals              */
  --code-number:        #ef9b55;  /* numeric literals                        */

  /* console / diff extras (terminal blocks, +/- blocks) */
  --code-error:         #e8676a;
  --code-added:         #8fcb7a;
  --code-removed:       #e8676a;
  --code-muted:         #848c95;

  /* chrome */
  --code-selection:     rgba(253, 181, 31, .22);
  --code-line-highlight:rgba(253, 181, 31, .08);
  --code-inline-bg:     #242628;
  --code-scrollbar:     #3a3d40;
}
/* ── 1c. Light theme ───────────────────────────────────────────────────────
   union.ai ships one code palette for both themes today. Union Yellow cannot
   carry a token on a light card (1.7:1) — at AA-legible lightness the brand
   warm reads as amber, not yellow — so the light theme keeps the same *roles*
   and swaps in a saturated 600/700-weight hue for each.

   The card goes WHITE here, not --brand-gray-100: white buys ~11% more
   contrast than #F2F3F3, and that headroom is what lets these hues stay
   vivid instead of collapsing into browns. Put the page's light gray behind
   the card so it still reads as a card. Every value below passes AA on
   #FFFFFF; on a #F2F3F3 card, amber/green/blue/comment land at 4.3–4.7 and
   only the decorator and comment miss AA outright.                          */
#union-inference .u-theme-light {
  --code-bg:        #ffffff;
  --code-fg:        #111418;
  --code-param:     #374151;
  --code-punct:     #565e66;
  --code-comment:   #6b7280;
  --code-decorator: #a16207;   /* amber — the light-theme stand-in for Union Yellow */
  --code-keyword:   #6d28d9;
  --code-function:  #2563eb;
  --code-constant:  #6d28d9;
  --code-class:     #0f766e;
  --code-string:    #15803d;
  --code-number:    #c2410c;
  --code-error:     #dc2626;
  --code-added:     #15803d;
  --code-removed:   #dc2626;
  --code-inline-bg: #f2f3f3;
  --code-border:    #0000001a;
}
/* ── 1b. The code surface ──────────────────────────────────────────────── */
#union-inference pre, #union-inference pre code, #union-inference .w-richtext pre {
  background-color: var(--code-bg);
  color: var(--code-fg);
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .875rem;      /* 14px */
  line-height: 1.7;
  font-variant-ligatures: none;
  tab-size: 4;
}
#union-inference pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
#union-inference pre ::selection, #union-inference pre::selection { background: var(--code-selection); }
#union-inference pre::-webkit-scrollbar-thumb { background: var(--code-scrollbar); border-radius: 4px; }
/* inline `code` inside body copy */
#union-inference :not(pre) > code {
  background-color: var(--code-inline-bg);
  border: 1px solid var(--code-border);
  border-radius: .375rem;
  padding: .1em .4em;
  color: var(--code-fg);
  font-size: .9em;
}
/* ── 2. Prototype class mappings ───────────────────────────────────────── *//* shared code surface */
#union-inference .tok-kw, #union-inference .sov-tok-kw, #union-inference .code-kw { color: var(--code-keyword); }
#union-inference .tok-str, #union-inference .sov-tok-str, #union-inference .code-str { color: var(--code-string); }
#union-inference .tok-title, #union-inference .sov-tok-title, #union-inference .code-title { color: var(--code-function); }
#union-inference .tok-param, #union-inference .code-param { color: var(--code-param); }
#union-inference .tok-meta, #union-inference .sov-tok-meta, #union-inference .code-meta { color: var(--code-decorator); }
#union-inference .tok-comment, #union-inference .code-comment { color: var(--code-comment); font-style: italic; }
#union-inference .tok-num, #union-inference .sov-tok-num, #union-inference .code-num { color: var(--code-number); }
#union-inference .tok-class, #union-inference .sov-tok-class, #union-inference .code-class { color: var(--code-class); }
#union-inference .code-punct { color: var(--code-punct); }
#union-inference .code-plain { color: var(--code-fg); }
/* the light theme is opt-in: add .u-theme-light to a code block's container *//* ═══ _shared/union-fig.css ═══ *//* ══════════════════════════════════════════════════════════════════════════
   union-fig.css — the home page's design language, shared by the platform
   pages (advanced-scheduling, agents, ai-factory, durability, inference,
   sovereign-ai).

   Source of truth: the "Home — Redesign" comp (Figma L1U2YQLR…, page 14:8)
   as realised in union/home/style.css. The geometry it encodes:

     · 1440 frame, 64px gutters, 1312 of content            (.u-wrap)
     · 130px of air above and below every section           (.fig-sec)
     · alternating grounds, black / near-black              (.is-alt)
     · centred intro pairs — big h2 over a 700px lead       (.fig-intro)
     · content rows as a 420 / 804 split with an 88px gap,
       sides alternating down the page                      (.fig-row .is-flip)
     · each row led by a numbered eyebrow, a yellow
       uppercase label, an h2, a lead, dot points, a link    (.fig-eyebrow …)
     · a full-bleed yellow closing block                     (.fig-cta)

   Two token systems are in play across these pages — union-system.css
   (--theme-* and --brand-*) and union-nocturne.css (--color-*). The two share no
   names, so every colour below reads the theme token first and falls back to
   the nocturne one. Nothing here needs a per-page bridge.
   ══════════════════════════════════════════════════════════════════════════ */
#union-inference {
  --fig-accent:  var(--theme-accent,  var(--color-accent, #fcb51f));
  --fig-heading: var(--theme-heading, var(--color-text, #ffffff));
  --fig-body:    var(--theme-body,    var(--color-neutral-400, #cccfd1));
  --fig-muted:   var(--brand-gray-350, var(--color-neutral-500, #aeb2b5));
  --fig-faint:   var(--brand-gray-400, var(--color-neutral-600, #81858b));
  --fig-border:  var(--theme-border,  var(--color-divider, rgba(255,255,255,.12)));
  --fig-ground:  #0c0c0d;   /* the alternating band, one step off black */
  --fig-ink:     #0b0b0c;   /* type on the yellow block */
}
/* ── container ─────────────────────────────────────────────────────── */
#union-inference .u-wrap {
  max-width: 1440px; margin: 0 auto;
  padding-left: clamp(20px, 4.4vw, 64px);
  padding-right: clamp(20px, 4.4vw, 64px);
}
/* ── section rhythm + alternating grounds ──────────────────────────── */
#union-inference .fig-sec { padding-top: clamp(56px, 9vw, 130px); padding-bottom: clamp(56px, 9vw, 130px); }
#union-inference .fig-sec.is-alt { background: var(--fig-ground); }
#union-inference .fig-sec.is-tight { padding-top: clamp(40px, 6vw, 84px); padding-bottom: clamp(40px, 6vw, 84px); }
/* ── centred intro pair ────────────────────────────────────────────── */
#union-inference .fig-intro { text-align: center; }
#union-inference .fig-intro_h2 {
  font-size: clamp(28px, 4.6vw, 56px); line-height: 1.12; letter-spacing: -0.025em;
  margin: 0 0 18px; color: var(--fig-heading); text-wrap: balance;
}
#union-inference .fig-intro_sub {
  font-size: clamp(16px, 1.6vw, 19px); line-height: 1.6; color: var(--fig-body);
  max-width: 700px; margin: 0 auto; text-wrap: pretty;
}
#union-inference .fig-intro_body { margin-top: clamp(40px, 5.5vw, 72px); text-align: left; }
/* ── content row: copy one side, visual the other ──────────────────── */
#union-inference .fig-row {
  display: grid; grid-template-columns: minmax(0, 420fr) minmax(0, 804fr);
  gap: clamp(28px, 5.2vw, 88px);
  /* start, not center: the comp top-aligns both columns, and centring left the
     heading stranded 200-400px down a tall row — so a contents card that jumped
     to the section landed with its title well below the fold line. */
  align-items: start;
}
/* `order` moves items between grid CELLS, so a flipped row has to swap the
   track widths too — otherwise the visual lands in the narrow column. */
#union-inference .fig-row.is-flip { grid-template-columns: minmax(0, 804fr) minmax(0, 420fr); }
#union-inference .fig-row.is-flip .fig-copy { order: 2; }
#union-inference .fig-row.is-flip .fig-visual { order: 1; }
/* for rows whose visual is denser than the comp's 470px placeholder */
#union-inference .fig-row.is-roomy { grid-template-columns: minmax(0, 360fr) minmax(0, 864fr); }
#union-inference .fig-row.is-roomy.is-flip { grid-template-columns: minmax(0, 864fr) minmax(0, 360fr); }
/* for rows whose copy carries a code block rather than a widget */
#union-inference .fig-row.is-even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
#union-inference .fig-copy { min-width: 0; }
#union-inference .fig-visual { min-width: 0; }
/* ── row furniture ─────────────────────────────────────────────────── */
#union-inference .fig-eyebrow { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
#union-inference .fig-eyebrow_n { font-size: 13px; letter-spacing: 0.06em; color: var(--fig-faint); }
#union-inference .fig-eyebrow_rule { display: block; width: 24px; height: 1px; background: var(--fig-border); }
#union-inference .fig-label {
  font-size: 15px; font-weight: 600; letter-spacing: 0.085em; text-transform: uppercase;
  color: var(--fig-accent); margin-bottom: 18px;
}
#union-inference .fig-h2 {
  font-size: clamp(27px, 3.9vw, 52px); line-height: 1.1; letter-spacing: -0.025em;
  margin: 0 0 22px; color: var(--fig-heading); text-wrap: balance;
}
#union-inference .fig-h3 {
  font-size: clamp(20px, 2.4vw, 28px); line-height: 1.2; letter-spacing: -0.02em;
  margin: 0 0 14px; color: var(--fig-heading); text-wrap: balance;
}
#union-inference .fig-lead {
  font-size: clamp(16px, 1.6vw, 19px); line-height: 1.62; color: var(--fig-body);
  margin: 0 0 26px; text-wrap: pretty;
}
#union-inference .fig-lead:last-child { margin-bottom: 0; }
#union-inference .fig-points { list-style: none; margin: 0 0 30px; padding: 0; display: grid; gap: 12px; }
#union-inference .fig-points li {
  position: relative; padding-left: 18px; font-size: 16px; line-height: 1.6;
  color: var(--fig-body); text-wrap: pretty;
}
#union-inference .fig-points li::before {
  content: ""; position: absolute; left: 0; top: 0.58em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--fig-accent);
}
#union-inference .fig-points li b, #union-inference .fig-points li strong { color: var(--fig-heading); font-weight: 600; }
#union-inference .fig-link {
  display: inline-block; font-size: 15px; font-weight: 500;
  color: var(--fig-accent); text-decoration: none;
}
#union-inference .fig-link:hover { opacity: 0.8; }
/* caption under a visual — the comp puts a title + note inside the placeholder */
#union-inference .fig-cap { margin-top: 18px; display: flex; flex-direction: column; gap: 5px; }
#union-inference .fig-cap_t { font-size: 15.5px; font-weight: 600; color: var(--fig-heading); }
#union-inference .fig-cap_d { font-size: 14.5px; line-height: 1.55; color: var(--fig-muted); text-wrap: pretty; }
/* ── closing CTA: the full-bleed yellow block ──────────────────────── */
#union-inference .fig-cta {
  background: var(--fig-accent); color: var(--fig-ink); text-align: center;
  padding-top: clamp(56px, 8vw, 120px); padding-bottom: clamp(56px, 8vw, 120px);
}
#union-inference .fig-cta.has-strip { padding-bottom: clamp(40px, 5vw, 64px); }
#union-inference .fig-cta_h2 {
  font-size: clamp(30px, 5.2vw, 64px); line-height: 1.08; letter-spacing: -0.03em;
  margin: 0 0 24px; color: var(--fig-ink); text-wrap: balance;
}
#union-inference .fig-cta_lead {
  font-size: clamp(16px, 1.8vw, 21px); line-height: 1.6; color: rgba(11, 11, 12, 0.78);
  max-width: 680px; margin: 0 auto 30px; text-wrap: pretty;
}
#union-inference .fig-cta_btns { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
#union-inference .fig-cta_btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--fig-ink); border: 1px solid var(--fig-ink); color: var(--fig-accent);
  border-radius: 999px; padding: 14px 28px; font-size: 16px; font-weight: 600;
  white-space: nowrap; text-decoration: none; cursor: pointer; font-family: inherit;
}
#union-inference .fig-cta_btn.is-ghost { background: transparent; border-color: rgba(11, 11, 12, 0.35); color: var(--fig-ink); }
/* The host pages carry a bare `a { color: accent }`, which would repaint these.
   `.button` is excluded as well as `.fig-cta_btn`: the union-system pages state
   their CTA buttons as `a.button`, and `a:not(.fig-cta_btn)` (0,2,1) outranks
   `.fig-cta .button` (0,2,0) — which painted the label black on a black pill. */
#union-inference .fig-cta a:not(.fig-cta_btn):not(.button):not(.btn), #union-inference .fig-cta a:not(.fig-cta_btn):not(.button):not(.btn):hover { color: var(--fig-ink); }
#union-inference .fig-cta a.fig-cta_btn { color: var(--fig-accent); }
#union-inference .fig-cta a.fig-cta_btn.is-ghost { color: var(--fig-ink); }
#union-inference .fig-cta a.fig-cta_btn:hover { background: #1c1c1e; border-color: #1c1c1e; color: var(--fig-accent); }
#union-inference .fig-cta a.fig-cta_btn.is-ghost:hover { background: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-inference .fig-strip {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 16px 28px; text-align: left;
  margin-top: clamp(40px, 5.5vw, 72px); padding-top: clamp(24px, 3vw, 36px);
  border-top: 1px solid rgba(11, 11, 12, 0.2);
}
#union-inference .fig-strip_text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
#union-inference .fig-strip_h { font-size: clamp(17px, 1.9vw, 22px); font-weight: 600; letter-spacing: -0.015em; color: var(--fig-ink); }
#union-inference .fig-strip_p { font-size: 15px; color: rgba(11, 11, 12, 0.7); text-wrap: pretty; }
@media (max-width: 1080px) {
  #union-inference .fig-row, #union-inference .fig-row.is-flip, #union-inference .fig-row.is-roomy, #union-inference .fig-row.is-roomy.is-flip, #union-inference .fig-row.is-even {
    grid-template-columns: minmax(0, 1fr); gap: clamp(28px, 5vw, 44px);
  }
  #union-inference .fig-row.is-flip .fig-copy, #union-inference .fig-row.is-flip .fig-visual { order: 0; }
  #union-inference .fig-points { margin-bottom: 24px; }
}
@media (max-width: 640px) {
  #union-inference .fig-eyebrow { margin-bottom: 10px; }
  #union-inference .fig-label { margin-bottom: 12px; font-size: 13.5px; }
  #union-inference .fig-strip { justify-content: flex-start; }
}
/* ══════════════════════════════════════════════════════════════════════════
   BRIDGE — the platform pages in the union-system family (advanced-scheduling,
   ai-factory, durability, sovereign-ai) are built from Client-First utilities:

     section > .padding-global > .container-large > .padding-section-large
       > .align-center.max-width-large.text-align-center
           > .text-style-tagline  +  h2.heading-style-h2  +  p.text-size-medium

   Rather than rewrite that markup on four pages, re-express those utilities in
   the home page's language. Everything is scoped under .fig-sec, which is added
   per section — so a section opts in by gaining the class, and the heroes,
   which keep their own composition, are never touched.
   ══════════════════════════════════════════════════════════════════════════ *//* .fig-sec owns the vertical rhythm; the container is left alone so every
   section lines up with the hero, which keeps the page's own .padding-global
   (5%) and .container-large (80rem). Overriding those to the home page's
   1440/64px made the sections 33px wider than the hero on both edges. */
#union-inference .fig-sec .padding-section-large, #union-inference .fig-sec .padding-section-medium { padding-top: 0; padding-bottom: 0; }
/* the tagline chip becomes the comp's yellow uppercase label */
#union-inference .fig-sec .text-style-tagline {
  display: block; border: 0; background: none; padding: 0;
  margin: 0 0 18px; font-size: 15px; font-weight: 600;
  letter-spacing: 0.085em; text-transform: uppercase; color: var(--fig-accent);
}
/* the section heading pair */
#union-inference .fig-sec .heading-style-h2 {
  font-size: clamp(28px, 4.6vw, 56px); line-height: 1.12; letter-spacing: -0.025em;
  font-weight: 600; text-wrap: balance;
}
#union-inference .fig-sec .heading-style-h3 {
  font-size: clamp(24px, 3.4vw, 42px); line-height: 1.14; letter-spacing: -0.022em;
  font-weight: 600; text-wrap: balance;
}
#union-inference .fig-sec .text-align-center .text-size-medium, #union-inference .fig-sec .fig-intro .text-size-medium {
  font-size: clamp(16px, 1.6vw, 19px); line-height: 1.6; color: var(--fig-body);
  max-width: 700px; margin-left: auto; margin-right: auto; text-wrap: pretty;
}
/* the comp sets the header block off from the body by a fixed measure rather
   than the utility spacers, which vary section to section */
#union-inference .fig-sec .spacer-xxlarge { height: clamp(40px, 5.5vw, 72px); }
#union-inference .fig-sec .spacer-xlarge { height: clamp(32px, 4.4vw, 56px); }
/* ── the nocturne family (agents, inference) states its headers inline ────
   Those two pages are authored against union-nocturne.css, the same tokens as
   the home page, so only the type scale needs restating. */
#union-inference .fig-sec > h2, #union-inference .fig-sec > .fig-head > h2 {
  font-size: clamp(28px, 4.6vw, 56px) !important; line-height: 1.12 !important;
  letter-spacing: -0.025em; text-wrap: balance;
}
/* ── the closing CTA on a union-system page ─────────────────────────
   Those pages state the CTA as a bordered card inside the section
   (.sched-cta_band, .sovereign-cta_band, .model-factory-cta_band …). The comp
   makes it a full-bleed yellow block instead, so the card loses its frame and
   the type and buttons invert onto the accent ground. */
#union-inference .fig-cta .padding-section-large, #union-inference .fig-cta .padding-section-medium { padding-top: 0; padding-bottom: 0; }
#union-inference .fig-cta [class*="cta_band"] { border: 0; background: none; padding: 0; text-align: center; }
#union-inference .fig-cta .heading-style-h2, #union-inference .fig-cta .heading-style-h3 {
  font-size: clamp(30px, 5.2vw, 64px); line-height: 1.08; letter-spacing: -0.03em;
  font-weight: 600; color: var(--fig-ink); text-wrap: balance;
}
#union-inference .fig-cta .text-size-medium, #union-inference .fig-cta [class*="cta_band"] p {
  font-size: clamp(16px, 1.8vw, 21px); line-height: 1.6; color: rgba(11, 11, 12, 0.78);
  max-width: 680px; margin-left: auto; margin-right: auto; text-wrap: pretty;
}
#union-inference .fig-cta .text-style-tagline {
  display: block; border: 0; background: none; padding: 0; margin: 0 0 16px;
  font-size: 15px; font-weight: 600; letter-spacing: 0.085em;
  text-transform: uppercase; color: rgba(11, 11, 12, 0.66);
}
#union-inference .fig-cta .button-group { justify-content: center; }
#union-inference .fig-cta .button {
  border-color: var(--fig-ink); background-color: var(--fig-ink);
  color: var(--fig-accent); border-radius: 999px;
}
#union-inference .fig-cta .button:hover { border-color: #1c1c1e; background-color: #1c1c1e; color: var(--fig-accent); }
#union-inference .fig-cta .button.is-secondary {
  border-color: rgba(11, 11, 12, 0.35); background-color: transparent; color: var(--fig-ink);
}
#union-inference .fig-cta .button.is-secondary:hover { background-color: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-inference .fig-cta .cta-note { color: rgba(11, 11, 12, 0.6); }
#union-inference .fig-cta .spacer-large { height: clamp(24px, 3vw, 34px); }
/* ── the Flyte band keeps the comp's purple callback ────────────────
   Home gives "Open source at the core." a dark-violet ground with purple
   hairlines and a purple eyebrow, rather than the alternating grey. */
#union-inference .fig-oss {
  background: #0d0717;
  border-top: 1px solid rgba(139, 92, 246, 0.32);
  border-bottom: 1px solid rgba(139, 92, 246, 0.32);
}
#union-inference .fig-oss .text-style-tagline { color: #8b5cf6; }
#union-inference .fig-oss .flyte-stat { border-left-color: rgba(139, 92, 246, 0.38); }
#union-inference .fig-oss .flyte-stat:first-child { border-left: 0; }
/* ── the nocturne family's section furniture ────────────────────────
   agents/ and inference/ label their sections with a small mono kicker and a
   17px lede. Both become the comp's label and lead. */
#union-inference .fig-sec .ag-kicker, #union-inference .fig-sec .in-kicker {
  display: block; font-family: inherit; font-size: 15px; font-weight: 600;
  letter-spacing: 0.085em; text-transform: uppercase;
  color: var(--fig-accent); margin-bottom: 18px;
}
#union-inference .fig-sec .ag-lede, #union-inference .fig-sec .in-lede {
  font-size: clamp(16px, 1.6vw, 19px); line-height: 1.6; color: var(--fig-body);
  max-width: 760px; text-wrap: pretty;
}
#union-inference .fig-sec .u-wrap > h2 {
  font-size: clamp(28px, 4.6vw, 56px); line-height: 1.12;
  letter-spacing: -0.025em; text-wrap: balance;
}
/* ── CTA sections that state their heading and buttons without the
      Client-First utility classes (durability's section_cta25) ──────── */
#union-inference .fig-cta h2 {
  font-size: clamp(30px, 5.2vw, 64px); line-height: 1.08; letter-spacing: -0.03em;
  color: var(--fig-ink); text-wrap: balance;
}
#union-inference .fig-cta p, #union-inference .fig-cta .text-size-tiny, #union-inference .fig-cta .text-size-small {
  color: rgba(11, 11, 12, 0.72);
}
/* the label may be wrapped in .button_text rather than sitting on the anchor */
#union-inference .fig-cta .button .button_text, #union-inference .fig-cta .button > * { color: inherit; }
#union-inference .fig-cta .button-group { justify-content: center; }
#union-inference .fig-cta .button-stack { display: flex; flex-direction: column; align-items: center; }
/* ── the proof band ─────────────────────────────────────────────────
   Every platform page opens with a "proved in production" list under its own
   heading class (.sched-proof_h, .model-factory-proof_h, .sovereign-proof_h).
   Home centres that block and sets it at the intro scale. */
#union-inference .fig-sec [class*="proof_head"] {
  max-width: 700px; margin-left: auto; margin-right: auto;
  margin-bottom: clamp(32px, 4.5vw, 56px); text-align: center;
}
#union-inference .fig-sec [class*="proof_h"]:not([class*="proof_head"]) {
  font-size: clamp(28px, 4.6vw, 56px); line-height: 1.12;
  letter-spacing: -0.025em; margin: 0 0 18px; text-wrap: balance;
}
#union-inference .fig-sec [class*="proof_head"] p {
  font-size: clamp(16px, 1.6vw, 19px); line-height: 1.6;
  color: var(--fig-body); text-wrap: pretty;
}
/* ── the first section after the hero ───────────────────────────────
   The hero on every platform page is tuned so the next heading just breaks
   the fold. The full 130px of section air pushes that heading under it, so the
   first section runs tighter at the top — the rhythm resumes from there down. */
#union-inference .fig-sec.is-first { padding-top: clamp(36px, 4.6vw, 66px); }
/* the nocturne pages' CTA band (.ag-cta / .in-cta) carries its own gradient
   ground and its own button classes, so both are overridden onto the block */
#union-inference .fig-cta.ag-cta, #union-inference .fig-cta.in-cta { background: var(--fig-accent); color: var(--fig-ink); }
#union-inference .fig-cta.ag-cta h2, #union-inference .fig-cta.in-cta h2 { color: var(--fig-ink); }
#union-inference .fig-cta.ag-cta p, #union-inference .fig-cta.in-cta p { color: rgba(11, 11, 12, 0.78); }
#union-inference .fig-cta .btn.cta-accent {
  background: var(--fig-ink); border-color: var(--fig-ink); color: var(--fig-accent);
}
#union-inference .fig-cta .btn.cta-accent:hover { background: #1c1c1e; border-color: #1c1c1e; color: var(--fig-accent); }
#union-inference .fig-cta .btn.btn-secondary {
  background: transparent; border-color: rgba(11, 11, 12, 0.35); color: var(--fig-ink);
}
#union-inference .fig-cta .btn.btn-secondary:hover { background: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-inference .fig-cta .mono { color: rgba(11, 11, 12, 0.6); }
/* The nocturne CTA states its measure, alignment and every colour inline
   (max-width in ch, a white button label, a mono note, an accent code chip),
   so the block has to out-rank the style attribute to invert onto yellow. */
#union-inference .fig-cta.ag-cta h2, #union-inference .fig-cta.in-cta h2, #union-inference .fig-cta.ag-cta p, #union-inference .fig-cta.in-cta p {
  margin-left: auto !important; margin-right: auto !important;
}
#union-inference .fig-cta.ag-cta > div, #union-inference .fig-cta.in-cta > div { padding-left: 0; padding-right: 0; }
#union-inference .fig-cta.ag-cta > div > div, #union-inference .fig-cta.in-cta > div > div { justify-content: center; }
#union-inference .fig-cta .btn.btn-secondary {
  color: var(--fig-ink) !important;
  box-shadow: inset 0 0 0 1px rgba(11, 11, 12, 0.35) !important;
}
#union-inference .fig-cta .mono { color: rgba(11, 11, 12, 0.6) !important; }
#union-inference .fig-cta code {
  color: rgba(11, 11, 12, 0.82) !important;
  background: rgba(11, 11, 12, 0.08); border-radius: 4px; padding: 0 4px;
}
/* ══════════════════════════════════════════════════════════════════════════
   TOC CARDS + CASE STUDIES — ported from union/home's .cap-grid / .proof-grid.

   The platform pages opened with a two-column proof list: the property on the
   left linking down the page, the customer result on the right linking out to
   a case study. Home splits those two jobs — a grid of contents cards that
   jump down the page, and the case studies gathered below the sections they
   belong to — so the same split is applied here.
   ══════════════════════════════════════════════════════════════════════════ *//* Flex, not grid: a fixed 3-up grid leaves a ragged hole whenever the item
   count isn't a multiple of three (4 items -> 3+1, 5 -> 3+2).
   Every card keeps ONE width — an exact column of --cap-cols — and a partial
   last row centres instead of stretching, so a row of two sits under the row
   of three at the same width rather than widening to fill. */
#union-inference .cap-grid, #union-inference .proof-grid {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: center;
  /* pull the grid back out to the section edge — the cells' own padding would
     otherwise indent the first column past every other heading on the page */
  margin-inline: -22px; text-align: left;
}
#union-inference .cap-grid > *, #union-inference .proof-grid > * {
  /* fixed basis, no grow: (row - the gaps between columns) / columns */
  flex: 0 0 calc((100% - (var(--cap-cols, 3) - 1) * 10px) / var(--cap-cols, 3));
  max-width: calc((100% - (var(--cap-cols, 3) - 1) * 10px) / var(--cap-cols, 3));
}
#union-inference .cap-grid.is-4up, #union-inference .proof-grid.is-4up { --cap-cols: 4; }
#union-inference .cap-grid.is-5up, #union-inference .proof-grid.is-5up { --cap-cols: 5; }
#union-inference .cap-cell, #union-inference .proof-cell {
  position: relative;          /* the hover sweep below is absolutely placed */
  overflow: hidden;            /* so the sweep follows the corner radius */
  display: flex; flex-direction: column;
  padding: 22px 22px 26px;
  border-radius: var(--radius-medium, var(--radius-md, 14px));
  text-decoration: none; color: inherit;
  transition: background-color .18s ease, transform .18s cubic-bezier(.2, .7, .3, 1);
}
/* the two hover layers paint inside the cell, so the content has to sit above
   them — otherwise the accent wash tints the icon and the type */
#union-inference .cap-cell > *, #union-inference .proof-cell > * { position: relative; z-index: 1; }
#union-inference .cap-cell:hover, #union-inference .proof-cell:hover {
  background: color-mix(in srgb, var(--fig-heading) 5%, transparent);
  transform: translateY(-3px);
}
#union-inference .cap-cell:focus-visible, #union-inference .proof-cell:focus-visible { outline: 2px solid var(--fig-accent); outline-offset: -2px; }
#union-inference .cap-cell::before, #union-inference .proof-cell::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--fig-accent) 11%, transparent) 0%, transparent 52%);
  opacity: 0; transition: opacity .28s ease;
}
#union-inference .cap-cell::after, #union-inference .proof-cell::after {
  content: ""; position: absolute; top: 0; left: 0; right: 0; z-index: 0;
  height: 1.5px; pointer-events: none;
  background: linear-gradient(90deg, transparent 0%,
    color-mix(in srgb, var(--fig-accent) 55%, transparent) 14%,
    var(--fig-accent) 42%,
    color-mix(in srgb, var(--fig-accent) 40%, transparent) 78%, transparent 100%);
  transform: scaleX(0); transform-origin: left;
  transition: transform .34s cubic-bezier(.2, .7, .3, 1);
}
#union-inference .cap-cell:hover::before, #union-inference .proof-cell:hover::before { opacity: 1; }
#union-inference .cap-cell:hover::after, #union-inference .proof-cell:hover::after { transform: scaleX(1); }
/* contents card — the glyph is a ↓ because the card jumps down the page */
#union-inference .cap-cell_name {
  font-size: 21px; font-weight: 600; color: var(--fig-heading);
  letter-spacing: -0.01em; margin-bottom: 7px; transition: color .18s ease;
}
#union-inference .cap-cell_desc { font-size: 16px; line-height: 1.5; color: var(--fig-muted); text-wrap: pretty; transition: color .18s ease; }
#union-inference .cap-cell_name::after {
  content: "↓"; display: inline-block; margin-left: 8px;
  font-weight: 400; color: var(--fig-faint);
  transition: color .18s ease, transform .22s cubic-bezier(.2, .7, .3, 1);
}
#union-inference .cap-cell:hover .cap-cell_name { color: var(--fig-accent); }
#union-inference .cap-cell:hover .cap-cell_desc { color: var(--fig-body); }
#union-inference .cap-cell:hover .cap-cell_name::after { color: var(--fig-accent); transform: translateY(-3px); }
/* case-study card — the result leads, the company and the property frame it */
#union-inference .proof-cell_co {
  font-size: 11.5px; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--fig-accent); margin-bottom: 10px;
  transition: transform .22s cubic-bezier(.2, .7, .3, 1); transform-origin: left;
}
#union-inference .proof-cell:hover .proof-cell_co { transform: translateX(2px); }
#union-inference .proof-cell_result {
  font-size: 21px; font-weight: 600; line-height: 1.25; color: var(--fig-heading);
  letter-spacing: -0.01em; text-wrap: pretty;
}
#union-inference .proof-cell_result::after {
  content: "↗"; display: inline-block; margin-left: 9px;
  font-weight: 400; color: var(--fig-faint);
  transition: color .18s ease, transform .22s cubic-bezier(.2, .7, .3, 1);
}
#union-inference .proof-cell:hover .proof-cell_result::after { color: var(--fig-accent); transform: translate(3px, -3px); }
#union-inference .proof-cell_cap { margin-top: auto; padding-top: 14px; font-size: 14px; color: var(--fig-faint); transition: color .18s ease; }
#union-inference .proof-cell:hover .proof-cell_cap { color: var(--fig-muted); }
@media (prefers-reduced-motion: reduce) {
  #union-inference .cap-cell, #union-inference .proof-cell, #union-inference .cap-cell_name, #union-inference .cap-cell_desc, #union-inference .cap-cell_name::after, #union-inference .cap-cell::after, #union-inference .proof-cell::after, #union-inference .proof-cell_co, #union-inference .proof-cell_result::after { transition: none; }
  #union-inference .cap-cell:hover, #union-inference .proof-cell:hover { transform: none; }
  #union-inference .cap-cell:hover .cap-cell_name::after, #union-inference .proof-cell:hover .proof-cell_co, #union-inference .proof-cell:hover .proof-cell_result::after { transform: none; }
  #union-inference .cap-cell::before, #union-inference .proof-cell::before, #union-inference .cap-cell::after, #union-inference .proof-cell::after { display: none; }
}
@media (max-width: 1080px) {
  #union-inference .cap-grid, #union-inference .proof-grid { --cap-cols: 2; }
}
@media (max-width: 860px) {
  #union-inference .cap-grid, #union-inference .proof-grid { margin-inline: 0; }
  #union-inference .cap-cell, #union-inference .proof-cell { padding-left: 0; padding-right: 0; }
}
@media (max-width: 640px) {
  #union-inference .cap-grid, #union-inference .proof-grid { --cap-cols: 1; gap: 4px; }
  #union-inference .cap-grid > *, #union-inference .proof-grid > * { flex-basis: 100%; max-width: 100%; }
  #union-inference .cap-cell, #union-inference .proof-cell { padding: 16px 22px 18px; }
  #union-inference .cap-cell_name, #union-inference .proof-cell_result { font-size: 19px; }
}
/* ── headings inside a staggered row's copy column ──────────────────
   The intro scale (up to 56px) is set for a centred 700px measure; in the
   420px copy column it wraps to five or six lines. The row scale is smaller,
   matching home's .fig-h2 against the same column width. */
#union-inference .fig-copy .heading-style-h2, #union-inference .fig-copy .heading-style-h3 {
  font-size: clamp(25px, 2.7vw, 40px); line-height: 1.12; letter-spacing: -0.02em;
}
#union-inference .fig-copy .text-size-medium, #union-inference .fig-copy .text-size-regular {
  font-size: clamp(15.5px, 1.4vw, 17.5px); line-height: 1.6;
  color: var(--fig-body); max-width: none; margin-left: 0; margin-right: 0;
}
#union-inference .fig-copy .text-style-tagline { margin-bottom: 14px; }
#union-inference .fig-copy > div { max-width: none; }
/* ── anchor landings ────────────────────────────────────────────────
   The navbar is sticky, so a bare #anchor jump puts the section's first line
   underneath it. union-system.css sets this for its own pages; the nocturne
   pages (agents, inference) carry no equivalent, so it is stated here for
   every section the contents cards can target. */
#union-inference .fig-sec[id], #union-inference .fig-cta[id] { scroll-margin-top: 6rem; }
/* durability states this band's heading as a bare <h2> inside a layout3 row,
   so it renders small; the other pages use .heading-style-h2 */
#union-inference .fig-oss h2 {
  font-size: clamp(26px, 4vw, 48px); line-height: 1.12;
  letter-spacing: -0.025em; text-wrap: balance;
}
/* ── one button size across every closing CTA ───────────────────────
   Measured before this rule, at 1440: the union-system pages rendered 42px
   tall (.button, 16px/8-20 padding) while the nocturne pages rendered 39px
   for the primary and 30px for the secondary (.btn, 14px, with padding set
   inline). Three sizes across six pages, and two of them inside one block.
   Everything is pinned to the larger format here — the inline padding and
   font-size on the nocturne anchors need !important to give way. */
#union-inference .fig-cta .button, #union-inference .fig-cta .btn {
  padding: 14px 28px !important;
  font-size: 16px !important;
  font-weight: 600;
  line-height: 1.2;
  border-radius: 999px !important;
  border-width: 1px; border-style: solid;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; white-space: nowrap; text-decoration: none;
}
#union-inference .fig-cta .button .button_text, #union-inference .fig-cta .btn .button_text { font-size: inherit; font-weight: inherit; }
/* the mono note that sits beside them ("pip install flyte") sits on the baseline */
#union-inference .fig-cta .button-group, #union-inference .fig-cta .fig-cta_btns { align-items: center; }
/* ── one content column across the platform pages ──
   container-large's 80rem resolved to 1333px against the site's fluid root.
   Pin it to the measure the home page's .u-wrap produces (1440 less its 64px
   gutters) so every platform page reads at the same width as home.
   (pricing does not load this file.) */
#union-inference .container-large { max-width: 1312px; }
/* ══ the isometric widget (union-iso3d.js) ═══════════════════════════════
   The drawing itself is built in JS; what it needs from CSS is the page's
   own type and neutrals, so the same renderer reads correctly on every
   ground. Font sizes are NOT set here on purpose — union-iso3d.js writes
   font-size and letter-spacing as presentation attributes, scaled to the
   render width, and a CSS rule would beat the attribute and pin the type
   to one size however wide the visual gets.

   Markup each page repeats:

     <div class="fig-factory" id="x-iso">
       <div class="fig-factory_stage" id="x-iso-stage"></div>
       <div class="fig-factory_caps" aria-hidden="true">… legend …</div>
     </div>

   No card: the drawing sits straight on the page ground so the geometry
   gets the whole column instead of paying for a frame and its padding. */
#union-inference .fig-factory { overflow: visible; }
/* Stacked under the copy, a hero row's gap bottoms out at its clamp and the
   plate's top corner ends up crowded against the CTAs. Only the narrow
   layout needs it — beside the copy the drawing is centred and has room. */
#union-inference .fig-factory.is-compact { padding-top: 28px; }
#union-inference .fig-factory_stage { display: block; min-height: 1px; }
#union-inference .fig-factory_stage svg { display: block; width: 100%; height: auto; }
#union-inference .fig-factory_leader {
  fill: none; stroke: var(--brand-gray-500, var(--color-neutral-700, #4a4e52)); stroke-width: 1;
}
#union-inference .fig-factory_anchor {
  fill: var(--fig-heading); stroke: var(--theme-bg, var(--color-bg, #000));
}
#union-inference .fig-factory_lt { font-family: var(--font-code, ui-monospace, monospace); fill: var(--fig-heading); }
#union-inference .fig-factory_ls { font-family: var(--font-body, system-ui, sans-serif); fill: var(--fig-muted); }
/* ── narrow containers ──
   Below 560px the side labels leave the SVG (union-iso3d.js filters them and
   sets .is-compact) and reappear here as captions. Their leader lines are
   laid out in screen units, so at phone widths they ate more of the viewBox
   than the drawing did. */
#union-inference .fig-factory_caps { display: none; }
#union-inference .fig-factory.is-compact .fig-factory_caps { display: grid; gap: 7px; margin: 14px 2px 2px; }
#union-inference .fig-factory_cap {
  display: flex; align-items: baseline; gap: 8px; font-size: 12px; line-height: 1.4;
  color: var(--fig-muted);
}
#union-inference .fig-factory_cap i {
  flex: none; width: 8px; height: 8px; border-radius: 2px;
  transform: translateY(-1px);
  background-color: var(--brand-gray-500, var(--color-neutral-700, #4a4e52));
}
/* yellow is Union, in the legend exactly as in the drawing */
#union-inference .fig-factory_cap i.is-union { background-color: var(--fig-accent); }
/* run state — see N.state in union-iso3d.js. Same three colours the drawing
   uses for a step that fails, retries and succeeds. */
#union-inference .fig-factory_cap i.is-fail { background-color: #e04b4d; }
#union-inference .fig-factory_cap i.is-retry { background-color: #5b90f7; }
#union-inference .fig-factory_cap i.is-ok { background-color: #8bcb6a; }
#union-inference .fig-factory_cap i.is-union-out {
  background-color: transparent;
  box-shadow: inset 0 0 0 1.5px var(--fig-accent);
}
#union-inference .fig-factory_cap i.is-mat { background-color: var(--fig-heading); }
/* The one legend entry standing for something that moves, so it marches
   instead of sitting still: a repeating radial-gradient of dots stepped
   exactly one tile per cycle, which loops seamlessly and mirrors the mote
   stream in the drawing. background-position is compositor-friendly, so this
   costs nothing next to the canvas beside it. */
#union-inference .fig-factory_cap i.is-raw {
  background-color: transparent;
  background-image: radial-gradient(circle at 1.5px 50%, var(--fig-body) 1.4px, transparent 1.6px);
  background-size: 4px 100%;
  background-repeat: repeat-x;
  animation: fig-factory-stream 900ms linear infinite;
}

@keyframes fig-factory-stream { from { background-position-x: 0; } to { background-position-x: 4px; } }
@media (prefers-reduced-motion: reduce) {
  #union-inference .fig-factory_cap i.is-raw { animation: none; }
}
#union-inference .fig-factory_cap-k {
  font-family: var(--font-code, ui-monospace, monospace); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--fig-heading); white-space: nowrap;
}
#union-inference .fig-factory_cap-v { color: var(--fig-muted); }
/* A scene used as a band of its own rather than as a cell in a hero row — the
   durability page, whose hero already spends its right column on a tabbed
   product demo. Capped well short of the container: at the full 1312 the
   drawing outgrew the copy around it and its plate ran under the sticky nav.
   860 keeps the leaders (the compact breakpoint is 560) without letting the
   scene become the page. */
#union-inference .fig-factory.is-band { max-width: 860px; margin: 0 auto; }
#union-inference .fig-factory.is-band .fig-factory_caps { justify-content: center; }
/* ═══ inference/style.css ═══ *//* Union /inference landing page — page styles.
   ../_shared/union-nocturne.css (design tokens + base components) must be linked
   BEFORE this file. Everything here is new; nothing maps onto an existing
   Webflow class.

   The section furniture (`.in-kicker`, `.in-lede`, `.in-fix`, `.in-hero-*`,
   `.in-trow`, `.in-grid-*`) is the same shape as /agents' `.ag-*` set, so the
   two pages read as one system. If the Webflow project adopts either, adopt
   both under one prefix and delete the duplicate. *//* =====================================================================
   Component state classes (Designer-buildable)
   ===================================================================== *//* Content blocks are grounds, not chrome: no ring, and a surface barely lifted
   off the page, so the type and the code panels inside carry the structure.
   `.elev-sm` still sits on the markup — these rules load after
   union-nocturne.css and win. */
#union-inference { --in-soft: color-mix(in srgb, var(--color-surface) 55%, var(--color-bg)); }
#union-inference .in-mini, #union-inference .in-guard, #union-inference .in-console, #union-inference .in-gw_box, #union-inference .in-stat {
  box-shadow: none;
  background: var(--in-soft);
}
/* section furniture */
#union-inference .in-kicker { display: inline-block; font-family: var(--font-code); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-accent); margin-bottom: 10px; }
#union-inference .in-lede { font-size: 17px; line-height: 1.6; color: var(--color-neutral-400); max-width: 820px; margin: 0; text-wrap: pretty; }
#union-inference .in-h3 { font-size: 20px; margin: 0 0 8px; }
#union-inference .in-body { font-size: 15px; line-height: 1.6; color: var(--color-neutral-400); margin: 0 0 14px; text-wrap: pretty; }
#union-inference .in-body-sm { font-size: 13.5px; color: var(--color-neutral-500); margin-top: 14px; margin-bottom: 0; }
#union-inference .in-dim { color: var(--color-neutral-600); }
/* hero */
#union-inference .in-hero-h1 { font-size: 52px; line-height: 1.05; margin: 0 0 16px; max-width: 20ch; }
#union-inference .in-hero-sub { font-size: 19px; line-height: 1.55; color: var(--color-neutral-400); max-width: 56ch; margin: 0 0 12px; text-wrap: pretty; }
/* the third line is a supporting note, not part of the pitch: a step down in
   size and two steps down the neutral ramp, so it reads after the subhead
   rather than alongside it */
#union-inference .in-hero-tert { font-size: 15.5px; line-height: 1.5; color: var(--color-neutral-600); max-width: 56ch; margin: 0 0 24px; text-wrap: pretty; }
#union-inference .in-hero-btns { display: flex; gap: 12px; flex-wrap: wrap; }
#union-inference .in-hero-btns .btn { font-size: 16px; padding: 13px 26px; }
/* The request path in the hero's right column. One 5.4s cycle shared by every
   node and connector, offset per element by the inline --i, so the highlight
   walks from the client down to the endpoint. Keyframes are in the embed
   block below. *//* ── hero widget: the gateway, and the app underneath it ──────────────────
   Two stacked boxes. The gateway holds one row — pre-call guard, the things a
   call can be routed to, post-call guard — and the app below it is joined by
   an arrow up on the left and back down on the right, so the round trip reads
   without a legend. */
#union-inference .in-gw { position: relative; display: flex; flex-direction: column; }
#union-inference .in-gw_box { border: 1px solid var(--color-divider); border-radius: var(--radius-lg); }
#union-inference .in-gw_head, #union-inference .in-gw_app { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
#union-inference .in-gw_gateway { padding: 20px 22px 22px; }
#union-inference .in-gw_app { padding: 28px 22px; }
#union-inference .in-gw_title { font-size: 17px; color: var(--color-neutral-300); }
#union-inference .in-gw_tag { font-size: 11px; color: var(--color-neutral-600); white-space: nowrap; }
/* The guards are a fixed width so the two of them match; the routing targets
   take the rest. minmax(0,…) because the provider names are long. */
#union-inference .in-gw_row { display: grid; align-items: stretch; gap: 10px; margin-top: 18px; min-height: 190px; grid-template-columns: 96px 16px minmax(0, 1fr) 16px 96px; }
#union-inference .in-gw_cell { display: flex; flex-direction: column; justify-content: center; padding: 12px 10px; border-radius: var(--radius-md); border: 1px solid var(--color-divider); background: var(--color-surface); }
#union-inference .in-gw_guard { text-align: center; font-size: 13.5px; line-height: 1.4; color: var(--color-neutral-300); }
#union-inference .in-gw_targets { gap: 18px; padding: 16px 18px; }
#union-inference .in-gw_target { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
#union-inference .in-gw_target-name { font-size: 15px; color: var(--color-neutral-300); }
#union-inference .in-gw_target-meta { font-size: 10.5px; color: var(--color-neutral-600); text-align: right; }
#union-inference .in-gw_arrow { align-self: center; font-size: 13px; line-height: 1; text-align: center; color: var(--color-neutral-700); }
/* The link arrows sit under the guards they belong to: same 84px columns and
   the same 18px frame padding, so they line up with the boxes above and below. */
#union-inference .in-gw_link { display: grid; grid-template-columns: 96px 1fr 96px; padding: 0 22px; height: 46px; }
#union-inference .in-gw_updown { grid-column: 1; align-self: center; text-align: center; font-size: 17px; line-height: 1; color: var(--color-neutral-700); }
#union-inference .in-gw_updown.is-down { grid-column: 3; }
/* problem → answer rows */
#union-inference .in-fix { display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: 24px; padding: 22px 0; border-top: 1px solid var(--color-divider); align-items: start; }
#union-inference .in-fix-q { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 21px; line-height: 1.3; color: var(--color-text); margin: 0; }
#union-inference .in-fix-a { font-size: 15.5px; line-height: 1.6; color: var(--color-neutral-400); margin: 0; text-wrap: pretty; }
/* the tabbed endpoint panel's right column */
#union-inference .in-note { font-size: 15.5px; line-height: 1.6; color: var(--color-neutral-400); margin: 0 0 14px; text-wrap: pretty; min-height: 4.8em; }
#union-inference .in-notebtn { font-size: 13px; white-space: nowrap; }
#union-inference .in-facts { display: flex; flex-direction: column; margin-top: 20px; }
#union-inference .in-fact { display: grid; grid-template-columns: 148px minmax(0, 1fr); gap: 14px; padding: 11px 0; border-top: 1px solid var(--color-divider); font-size: 14px; line-height: 1.5; }
#union-inference .in-fact-k { color: var(--color-text); }
#union-inference .in-fact-v { color: var(--color-neutral-500); }
/* ── the app-console recreation ──
   Not a screenshot: real markup, so it reflows, scales with the type and stays
   legible on a phone. Numbers are illustrative — see README. */
#union-inference .in-console { border-radius: var(--radius-md); border: 1px solid var(--color-divider); overflow: hidden; }
#union-inference .in-console-top { padding: 16px 20px 14px; border-bottom: 1px solid var(--color-divider); background: var(--color-surface); }
#union-inference .in-console-title-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
#union-inference .in-console-title { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 19px; color: var(--color-text); }
#union-inference .in-console-status { font-size: 11.5px; color: var(--color-accent); white-space: nowrap; }
#union-inference .in-console-url { font-size: 11.5px; color: var(--color-neutral-600); overflow-wrap: anywhere; }
#union-inference .in-console-facts { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 10px; font-size: 12.5px; color: var(--color-neutral-400); }
#union-inference .in-console-facts .in-dim { margin-right: 6px; }
#union-inference .in-console-tabs { display: flex; gap: 6px; flex-wrap: wrap; padding: 10px 16px; border-bottom: 1px solid var(--color-divider); }
#union-inference .in-ctab { font: inherit; font-size: 13px; padding: 5px 14px; border: 1px solid transparent; border-radius: 999px; cursor: pointer; background: transparent; color: var(--color-neutral-500); white-space: nowrap; transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease; }
#union-inference .in-ctab.on { background: color-mix(in srgb, var(--color-accent) 16%, transparent); border-color: var(--color-accent); color: var(--acc-icon); }
#union-inference .in-ctab:hover { color: var(--acc-icon); }
#union-inference .in-ctab:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
#union-inference .in-console-body { padding: 20px; }
#union-inference .in-cpane { display: none; }
#union-inference .in-cpane.on { display: block; }
#union-inference .in-cpane-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 26px; }
#union-inference .in-cpane-head { font-family: var(--font-code); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-neutral-600); margin-bottom: 10px; }
#union-inference .in-cpane-note { font-size: 13px; line-height: 1.55; color: var(--color-neutral-500); margin: 14px 0 0; text-wrap: pretty; }
/* the request-rate sparkline */
#union-inference .in-chart { border: 1px solid var(--color-divider); border-radius: var(--radius-sm); padding: 12px; background: var(--color-bg); }
#union-inference .in-chart svg { width: 100%; height: 150px; display: block; }
#union-inference .in-chart-grid { stroke: var(--color-neutral-800); stroke-width: 1; }
#union-inference .in-chart-line { fill: none; stroke: var(--color-accent); stroke-width: 1.8; vector-effect: non-scaling-stroke; }
#union-inference .in-chart-legend { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 11px; color: var(--color-neutral-600); }
#union-inference .in-dot-2xx, #union-inference .in-dot-5xx { width: 7px; height: 7px; border-radius: 999px; }
#union-inference .in-dot-2xx { background: var(--color-accent); }
#union-inference .in-dot-5xx { background: var(--err); margin-left: 10px; }
/* the Details / Spec key-value list */
#union-inference .in-details { display: flex; flex-direction: column; }
#union-inference .in-drow { display: grid; grid-template-columns: 116px minmax(0, 1fr); gap: 14px; padding: 9px 0; border-top: 1px solid var(--color-divider); font-size: 13px; line-height: 1.5; align-items: start; }
#union-inference .in-dkey { color: var(--color-neutral-600); }
#union-inference .in-dval { color: var(--color-neutral-300); font-size: 11.5px; overflow-wrap: anywhere; }
/* log boxes — shared by the console pane and the gateway section.
   Both boxes carry the live state in their own bar rather than as a row of
   chips above them: with Historical logs and Scaling events dropped, a chip
   row would have been a single selected pill with nothing to switch to. */
#union-inference .in-logbox { border: 1px solid var(--color-divider); border-radius: var(--radius-sm); background: var(--color-bg); overflow: hidden; }
#union-inference .in-logbar { display: flex; align-items: center; gap: 12px; padding: 8px 14px; border-bottom: 1px solid var(--color-divider); font-size: 11.5px; color: var(--color-neutral-600); }
#union-inference .in-logbar-right { margin-left: auto; display: inline-flex; align-items: center; gap: 7px; }
#union-inference .in-toggle { width: 22px; height: 12px; border-radius: 999px; background: var(--color-neutral-800); position: relative; }
#union-inference .in-toggle.on { background: color-mix(in srgb, var(--ok) 70%, transparent); }
#union-inference .in-toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 8px; height: 8px; border-radius: 999px; background: var(--color-neutral-400); }
#union-inference .in-toggle.on::after { left: auto; right: 2px; background: #ffffff; }
#union-inference .in-logline { display: flex; gap: 12px; padding: 4px 14px; font-family: var(--font-code); font-size: 11.5px; line-height: 1.55; color: var(--color-neutral-400); }
#union-inference .in-logts { flex: none; color: var(--color-neutral-600); }
/* ── the Metrics pane ──
   Four per-card GPU charts in a 2 x 2, recreated as SVG rather than captured as
   a screenshot: the curves stay crisp at any zoom, the axis labels stay
   selectable, and the whole thing takes the theme's colors. */
#union-inference .in-mfilters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
#union-inference .in-mfilter { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--color-neutral-400); padding: 5px 12px; border-radius: var(--radius-sm); border: 1px solid var(--color-divider); }
#union-inference .in-mcaret { color: var(--color-neutral-600); font-size: 9px; }
#union-inference .in-mgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
#union-inference .in-mcard { border: 1px solid var(--color-divider); border-radius: var(--radius-sm); background: var(--color-bg); padding: 14px 14px 12px; min-width: 0; }
#union-inference .in-mcard-title { font-size: 13px; font-weight: 600; color: var(--color-text); margin-bottom: 8px; }
#union-inference .in-mchart { width: 100%; height: auto; display: block; overflow: visible; }
#union-inference .in-mgrid-line { stroke: var(--color-neutral-800); stroke-width: 1; }
/* non-scaling-stroke keeps every series a true hairline however wide the card
   gets — without it the line thickens with the viewBox scale */
#union-inference .in-mline { fill: none; stroke-width: 1.4; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
#union-inference .in-mtick { fill: var(--color-neutral-600); font-family: var(--font-body); font-size: 8px; }
#union-inference .in-mlegend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; font-size: 11px; color: var(--color-neutral-500); }
#union-inference .in-mleg { display: inline-flex; align-items: center; gap: 5px; }
#union-inference .in-mleg i { width: 7px; height: 7px; border-radius: 999px; flex: none; }
/* the gateway section still lists its metric panes by name and purpose */
#union-inference .in-mlist { display: flex; flex-direction: column; }
#union-inference .in-mrow { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 16px; padding: 12px 0; border-top: 1px solid var(--color-divider); font-size: 14px; line-height: 1.5; align-items: start; }
#union-inference .in-mname { color: var(--color-text); }
#union-inference .in-mdesc { color: var(--color-neutral-500); }
/* the Code pane's file tree + source */
#union-inference .in-code-split { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 16px; }
#union-inference .in-filelist { display: flex; flex-direction: column; gap: 2px; }
#union-inference .in-file { font-family: var(--font-code); font-size: 12px; padding: 6px 10px; border-radius: var(--radius-sm); color: var(--color-neutral-500); }
#union-inference .in-file.on { background: color-mix(in srgb, var(--color-accent) 14%, transparent); color: var(--acc-icon); }
#union-inference .in-codebox { border-radius: var(--radius-sm); background: var(--color-neutral-900); padding: 12px 0 13px; overflow: auto; min-width: 0; }
/* gateway stat cards */
#union-inference .in-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
#union-inference .in-stat { display: flex; flex-direction: column; gap: 4px; padding: 20px; border-radius: var(--radius-md); }
#union-inference .in-stat-k { font-family: var(--font-code); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-neutral-600); }
#union-inference .in-stat-n { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 30px; line-height: 1.1; color: var(--color-text); }
#union-inference .in-stat-d { font-size: 13px; line-height: 1.45; color: var(--color-neutral-500); }
/* the curl block */
#union-inference .in-curl { border-radius: var(--radius-sm); background: var(--color-neutral-900); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-divider) 45%, transparent); padding: 14px 0; overflow: auto; min-width: 0; }
/* the provider chips. Each carries a 17px mark slot: a masked SVG where a
   mark exists, a two-letter monogram where one does not (see script.js's
   PROVIDERS note). Both sit at the same size and color so the row reads as one
   set rather than as logos-plus-leftovers. */
#union-inference .in-provs { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 16px; }
#union-inference .in-prov { display: inline-flex; align-items: center; gap: 7px; padding: 6px 12px 6px 9px; border-radius: 999px; border: 1px solid var(--color-divider); background: var(--in-soft); white-space: nowrap; transition: border-color 0.18s ease, background 0.18s ease; }
/* masked rather than an <img>, so the mark takes the chip's own text color */
#union-inference .in-prov-logo { width: 17px; height: 17px; flex: none; background: var(--color-neutral-400); -webkit-mask: var(--logo) center / contain no-repeat; mask: var(--logo) center / contain no-repeat; transition: background 0.18s ease; }
#union-inference .in-prov-mono { width: 17px; height: 17px; flex: none; display: inline-flex; align-items: center; justify-content: center; border-radius: 5px; background: color-mix(in srgb, var(--color-neutral-400) 18%, transparent); color: var(--color-neutral-400); font-size: 8.5px; letter-spacing: -0.02em; transition: color 0.18s ease, background 0.18s ease; }
#union-inference .in-prov-n { font-size: 13px; color: var(--color-neutral-300); }
#union-inference .in-prov-id { font-size: 10.5px; color: var(--color-neutral-600); }
#union-inference .in-prov:hover { border-color: color-mix(in srgb, var(--color-accent) 45%, transparent); background: var(--color-surface); }
#union-inference .in-prov:hover .in-prov-logo { background: var(--acc-icon); }
#union-inference .in-prov:hover .in-prov-mono { color: var(--acc-icon); background: color-mix(in srgb, var(--color-accent) 16%, transparent); }
/* the virtual-keys table */
#union-inference .in-keys { display: flex; flex-direction: column; border-radius: var(--radius-md); border: 1px solid var(--color-divider); overflow: hidden; }
#union-inference .in-krow { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, .7fr) minmax(0, .8fr); gap: 16px; padding: 14px 20px; border-top: 1px solid var(--color-divider); font-size: 14px; line-height: 1.5; align-items: start; }
#union-inference .in-krow:first-child { border-top: 0; }
#union-inference .in-krow-head { background: var(--color-surface); font-family: var(--font-code); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-neutral-600); }
#union-inference .in-kname { display: flex; flex-direction: column; gap: 2px; font-size: 13px; color: var(--color-text); overflow-wrap: anywhere; }
#union-inference .in-kdesc { font-family: var(--font-body); font-size: 11.5px; color: var(--color-neutral-600); }
#union-inference .in-kdim { color: var(--color-neutral-500); font-size: 13px; }
/* the three budget/attribution cards */
#union-inference .in-mini { display: flex; flex-direction: column; gap: 8px; padding: 22px 20px; border-radius: var(--radius-md); }
#union-inference .in-mini .card-body { flex: none; }
/* guardrail cards */
#union-inference .in-guard { display: flex; flex-direction: column; gap: 9px; padding: 22px 20px; border-radius: var(--radius-md); min-width: 0; }
#union-inference .in-guard .card-body { flex: none; }
#union-inference .in-guard-file { display: flex; align-items: center; gap: 10px; margin-top: 4px; font-size: 11.5px; color: var(--color-neutral-500); }
#union-inference .in-guard-file .tag { font-size: 9.5px; }
#union-inference .in-guard-code {
  border-radius: var(--radius-sm);
  background: var(--color-neutral-900);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-divider) 45%, transparent);
  padding: 12px 0 13px; overflow: auto; min-width: 0;
  /* The two guards are 25 and 18 lines, so left alone the pair sets a card
     height neither of them wants. Fill the card instead and cap the listing at
     roughly a screenful — the grid row already stretches both cards to match,
     so they end up the same height and the longer one scrolls. */
  flex: 1 1 auto; min-height: 0; max-height: 22rem;
}
/* three-column tables */
#union-inference .in-trow { display: grid; grid-template-columns: minmax(0, 0.55fr) minmax(0, 1fr) minmax(0, 1.5fr); gap: 16px; padding: 12px 0; border-top: 1px solid var(--color-divider); font-size: 14px; line-height: 1.5; }
#union-inference .in-trow-head { font-family: var(--font-code); font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-neutral-600); }
#union-inference .in-tcell-1 { color: var(--color-text); }
#union-inference .in-tcell-2, #union-inference .in-tcell-3 { color: var(--color-neutral-500); }
#union-inference .in-trow-head .in-tcell-1, #union-inference .in-trow-head .in-tcell-2, #union-inference .in-trow-head .in-tcell-3 { color: var(--color-neutral-600); }
/* tab pills, shared with /agents so both pages' code panels look identical */
#union-inference .ag-tab { font: inherit; font-size: 13px; padding: 6px 14px; border: 1px solid var(--color-divider); border-radius: 999px; cursor: pointer; background: transparent; color: var(--color-neutral-400); white-space: nowrap; transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease; }
#union-inference .ag-tab.on { background: color-mix(in srgb, var(--color-accent) 16%, transparent); border-color: var(--color-accent); color: var(--acc-icon); }
#union-inference .ag-tab:hover { border-color: var(--color-accent); color: var(--acc-icon); }
#union-inference .ag-tab:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* the filled-yellow CTA — same class the home page uses */
#union-inference .cta-accent { background: var(--color-accent); border: 1px solid var(--color-accent); color: #000; }
#union-inference .cta-accent:hover { background: var(--color-accent-400); border-color: var(--color-accent-400); color: #000; }
#union-inference .cta-accent:active { background: var(--color-accent-600); border-color: var(--color-accent-600); color: #000; }
/* closing CTA band */
#union-inference .in-cta { background: linear-gradient(135deg, #18191a, #241d08); color: #e6e6e8;
  border-top: 1px solid color-mix(in srgb, var(--color-accent) 34%, transparent); }
#union-inference .in-cta h2 { color: #ffffff; }
#union-inference .in-cta p { color: rgba(230, 230, 232, 0.82); }
/* sticky nav */
#union-inference .navbar { transition: background 0.25s ease, box-shadow 0.25s ease, backdrop-filter 0.25s ease; }
#union-inference .navbar-stuck { background: color-mix(in srgb, var(--color-bg) 82%, transparent); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); box-shadow: 0 1px 0 0 var(--color-divider); }
/* =====================================================================
   WEBFLOW: paste into an Embed (base rules, pseudo-states, keyframes and
   media queries — CSS the Designer cannot express)
   ===================================================================== */
#union-inference { margin: 0; background: var(--color-bg); color: var(--color-text); font-size: 17px; }
#union-inference { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
#union-inference a { color: var(--color-accent); }
#union-inference a:hover:not(.cta-accent) { color: var(--color-accent-300); }
#union-inference pre, #union-inference code, #union-inference .mono { font-family: var(--font-code); }
#union-inference :not(pre) > code { font-size: 0.87em; color: var(--color-accent-300); background: none; border: 0; padding: 0; }
#union-inference [id] { scroll-margin-top: 88px; }
/* scrollbars inside code panels */
#union-inference .r-term, #union-inference .mono { scrollbar-width: thin; scrollbar-color: var(--color-neutral-700) transparent; }
#union-inference .r-term::-webkit-scrollbar, #union-inference .mono::-webkit-scrollbar { width: 8px; height: 8px; }
#union-inference .r-term::-webkit-scrollbar-track, #union-inference .mono::-webkit-scrollbar-track { background: transparent; }
#union-inference .r-term::-webkit-scrollbar-thumb, #union-inference .mono::-webkit-scrollbar-thumb { background: var(--color-neutral-700); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
#union-inference .r-term::-webkit-scrollbar-corner, #union-inference .mono::-webkit-scrollbar-corner { background: transparent; }
/* Status colors and the accent tint used by tab pills, file rows and chips.
   The syntax palette is NOT here: it comes from ../_shared/union-code-theme.css,
   the same file ../home/ loads, so all three pages highlight from one source. */
#union-inference { --ok: #8fcb7a; --err: #e8676a; --run: #74b6f2; --acc-icon: #f9d67f; }


/* the code panel's swap animation, fired by script.js on a tab change */
@keyframes coderise { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
#union-inference .code-rise { animation: coderise 0.26s ease both; }


/* the hero widget: one request walked through the gateway and back */
@keyframes ingwlit {
  0%, 12% { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 9%, var(--color-surface)); }
  26%, 100% { border-color: var(--color-divider); background: var(--color-surface); }
}

@keyframes ingwglyph {
  0%, 12% { color: var(--color-accent); }
  26%, 100% { color: var(--color-neutral-700); }
}
#union-inference .in-gw_cell { animation: ingwlit 6.6s calc(var(--i) * 1.1s) infinite; }

/* the app box keeps its own softer ground, so it lights on the border only */
@keyframes ingwlitbox {
  0%, 12% { border-color: var(--color-accent); }
  26%, 100% { border-color: var(--color-divider); }
}
#union-inference .in-gw_app { animation: ingwlitbox 6.6s calc(var(--i) * 1.1s) infinite; }
#union-inference .in-gw_arrow, #union-inference .in-gw_updown { animation: ingwglyph 6.6s calc(var(--i) * 1.1s + 0.55s) infinite; }
@media (prefers-reduced-motion: reduce) {
  #union-inference .code-rise { animation: none; }
  #union-inference .in-gw_cell, #union-inference .in-gw_app, #union-inference .in-gw_arrow, #union-inference .in-gw_updown { animation: none; }
  #union-inference { scroll-behavior: auto; }
}
/* Grid items and code panels must be allowed to shrink below their content, or
   a wide code line pushes its whole column — and with it the page — sideways. */
#union-inference .in-split > *, #union-inference .in-grid-2 > *, #union-inference .in-grid-3 > *, #union-inference .in-grid-4 > *, #union-inference .ag-grid-2 > * { min-width: 0; }
#union-inference .in-guard, #union-inference .in-guard-code, #union-inference .in-curl, #union-inference .in-codebox, #union-inference .in-term { min-width: 0; }
@media (max-width: 1080px) {
  #union-inference .ag-grid-2, #union-inference .in-split, #union-inference .in-grid-2 { grid-template-columns: minmax(0, 1fr) !important; }
  #union-inference .in-hero { gap: 34px !important; }
  #union-inference .in-gw { max-width: 520px; }
  #union-inference .in-hero-h1 { font-size: 42px; }
  #union-inference .in-fix { grid-template-columns: 1fr; gap: 8px; }
  #union-inference .in-cpane-grid { grid-template-columns: minmax(0, 1fr); }
  #union-inference .in-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #union-inference .in-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}
@media (max-width: 860px) {
  #union-inference [data-code-line] { font-size: 11.5px !important; line-height: 1.7 !important; padding-left: 12px !important; padding-right: 12px !important; }
  #union-inference section, #union-inference footer, #union-inference nav, #union-inference .in-cta > div { padding-left: 28px !important; padding-right: 28px !important; }
  #union-inference .in-hero-h1 { font-size: 36px; }
  #union-inference .in-hero-sub { font-size: 17px; }
  #union-inference .in-hero-tert { font-size: 14.5px; }
  #union-inference .in-grid-3, #union-inference .in-grid-4 { grid-template-columns: minmax(0, 1fr) !important; }
  #union-inference .in-stats { grid-template-columns: minmax(0, 1fr); }
  #union-inference .in-fact { grid-template-columns: minmax(0, 1fr); gap: 3px; }
  #union-inference .in-mrow { grid-template-columns: minmax(0, 1fr); gap: 3px; }
  #union-inference .in-mgrid { grid-template-columns: minmax(0, 1fr); }
  #union-inference .in-trow { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  #union-inference .in-trow-head { display: none; }
  #union-inference .in-tcell-2::before { content: "Gets · "; color: var(--color-neutral-700); }
  #union-inference .in-tcell-3::before { content: "Can · "; color: var(--color-neutral-700); }
  #union-inference .in-code-split { grid-template-columns: minmax(0, 1fr); }
  #union-inference .in-filelist { flex-direction: row; flex-wrap: wrap; }
  #union-inference .in-krow { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  #union-inference .in-krow-head { display: none; }
  #union-inference .in-krow > span:nth-child(2)::before { content: "Providers · "; color: var(--color-neutral-700); }
  #union-inference .in-krow > span:nth-child(3)::before { content: "Budget · "; color: var(--color-neutral-700); }
  #union-inference .in-krow > span:nth-child(4)::before { content: "Spend (24h) · "; color: var(--color-neutral-700); }
  #union-inference .in-krow > span:nth-child(5)::before { content: "Rate limit · "; color: var(--color-neutral-700); }
}
@media (max-width: 760px) {
  #union-inference .r-burger { display: inline-flex !important; }
  #union-inference .r-navitems { display: none !important; }
  #union-inference .r-navitems.r-open { display: flex !important; flex-direction: column; align-items: stretch; gap: 12px; flex: 1 1 100%; padding-top: 6px; }
  #union-inference .r-navitems.r-open .btn { justify-content: center; margin-left: 0 !important; }
}
@media (max-width: 640px) {
  #union-inference .in-hero-h1 { font-size: 31px; }
  #union-inference .in-console-body { padding: 14px; }
  #union-inference .in-drow { grid-template-columns: minmax(0, 1fr); gap: 3px; }
}
/* ── section container ───────────────────────────────────────────────
   This page used to state its own 1240/60px measure, narrower than the rest
   of the site. It now inherits .u-wrap from ../_shared/union-fig.css at the
   home page's 1440/64px, and the hero's inline measure was widened to match. */
#union-inference .in-chart-day { stroke: var(--color-neutral-900); stroke-width: 1; }
#union-inference .in-chart-area { fill: color-mix(in srgb, var(--color-accent) 13%, transparent); stroke: none; }
#union-inference .in-chart-line.is-5xx { stroke: var(--err); stroke-width: 1.5; }


/* ═══ port-only: the page's relationship to the host site ═══
   Carried over from the deployed sheet — these have no counterpart
   in the repo, because the standalone prototype has its own navbar
   and no host chrome to clear. */
#union-inference {
  --color-bg: #000000;        /* live --_theme---background */
  --color-surface: #18191a;   /* live --_theme---card */
  --color-text: #ffffff;      /* live --_theme---heading */
  --color-accent: #fcb51f;    /* live --_theme---accent */ /* review round 7 (Barron): the accent moves to
     the product's blurple — OKLCH hue 289.2, the hue of the app's own Pro
     accent (#9a8fe0, --om-accent-pro) — at the same lightness the steel
     accent held (L 0.660, so the documented ratios survive) and chroma
     in the product blurple's own range (its token sits at C 0.118; the
     accent takes 0.125, from the old steel's 0.030):
     the accent now reads as an accent rather than another neutral. */
  --color-accent-2: #f6c54c; /* the machine-derived stand-in follows: same
     hue, same L 0.734, chroma at the same 2:3 proportion it held */
  --color-divider: color-mix(in srgb, #ffffff 12%, transparent); /* live --_theme---border */

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. */
  --color-neutral-100: #ffffff;
  --color-neutral-200: #f2f3f3;  /* live --_brand---gray-100 */
  --color-neutral-300: #e3e5e6;
  --color-neutral-400: #cccfd1;  /* live --_theme---body (paragraphs) */
  --color-neutral-500: #aeb2b5;
  --color-neutral-600: #81858b;  /* live --_brand---gray-350 */
  --color-neutral-700: #72757a;  /* live --_brand---gray-400 */
  --color-neutral-800: #3a3d40;
  --color-neutral-900: #18191a;  /* live --_brand---dark, the card ground */

  --color-accent-100: #fdf4dc;
  --color-accent-200: #fbe7b4;
  --color-accent-300: #f9d67f;
  --color-accent-400: #f6c54c;
  --color-accent-500: #fcb51f;
  --color-accent-600: #ce9712;
  --color-accent-700: #a5780c;
  --color-accent-800: #785607;
  --color-accent-900: #4c3604;

  --color-accent-2-100: #fdf4dc;
  --color-accent-2-200: #fbe7b4;
  --color-accent-2-300: #f9d67f;
  --color-accent-2-400: #f6c54c;
  --color-accent-2-500: #fcb51f;
  --color-accent-2-600: #ce9712;
  --color-accent-2-700: #a5780c;
  --color-accent-2-800: #785607;
  --color-accent-2-900: #4c3604;

  /* Deck section-divider ground — review round 3: saturation as presence.
     Dividers take a saturated deep indigo (hue 277, the neutral ramp's own
     family; C 0.094 — written when the accent held C 0.030, before the
     round-7 blurple raised it past the ground's) with a lighter bloom and
     a ghost tint of the same hue, while the slide grounds stay
     desaturated. Deck-scale fills only — not interface colors. */
  --color-section: #33270a;
  --color-section-glow: #6b5109;
  --color-section-ghost: #b8860f;

  --font-heading: "Yellix", system-ui, sans-serif;
  --font-heading-weight: 600;  /* live h2/h3 weight */
  --font-body: "Yellix", system-ui, sans-serif;
  /* The mono face this file already @font-faces above. It used to be declared
     in home/style.css only, which meant every other page loading these tokens
     resolved var(--font-code) to nothing and rendered code in Yellix. */
  --font-code: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --space-1: 2.8px;
  --space-2: 5.6px;
  --space-3: 8.4px;
  --space-4: 11.2px;
  --space-6: 16.8px;
  --space-8: 22.4px;

  /* Rounder than the original Nocturne values, to sit with union.ai's live
     system (.5rem / 1rem / 1.5rem). Buttons and pills go fully round below. */
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 0 0 1px rgba(255,255,255,0.06);
  --shadow-md: 0 0 0 1px rgba(255,255,255,0.08), 0 6px 18px rgba(0,0,0,0.55);
  --shadow-lg: 0 0 0 1px rgba(255,255,255,0.11), 0 16px 40px rgba(0,0,0,0.65);
}
#union-inference {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
#union-inference code, #union-inference pre, #union-inference kbd, #union-inference samp { font-family: var(--font-code); }
#union-inference { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; }
#union-inference p { margin: 0 0 var(--space-3); }
#union-inference a { color: var(--color-accent); text-underline-offset: 3px; }
#union-inference img { display: block; max-width: 100%; }
#union-inference figure { margin: 0; }
#union-inference figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
/* ═══ _shared/union-code-theme.css ═══ *//* union-code-theme.css — syntax highlighting for every code block in website/union/.
   Tokens lifted verbatim from ../../color-palette/union-code-theme.css
   ("Union Yellow Dark" v1). That file is the source of truth: if the palette
   changes, re-copy sections 1 and 1c below rather than editing them here.

   Every token meets WCAG AA (4.5:1) on its own card background in both themes.
   Section 2 maps the tokens onto the class names the prototypes already use:
     .tok-*      model-factory, advanced-scheduling
     .sov-tok-*  sovereign-ai
     .code-*     home (emitted by script.js)
*//* ── 1. Tokens ─────────────────────────────────────────────────────────── */
#union-inference {
  /* surface */
  --code-bg:            #18191a;  /* = --brand-dark, the design-system card  */
  --code-border:        #ffffff1f;/* = --theme-border                        */
  --code-radius:        1rem;     /* = --radius-medium                       */

  /* neutrals — carry ~70% of the characters in a snippet */
  --code-fg:            #e6e8ea;  /* identifiers, variables, plain text      */
  --code-param:         #c9ced4;  /* keyword-argument + parameter names      */
  --code-punct:         #9aa0a6;  /* = -> , : ( ) [ ] and all operators      */
  --code-comment:       #848c95;  /* italic — the quietest token             */

  /* accents — four hues, nothing else */
  --code-decorator:     #fdb51f;  /* Union Yellow · @env.task, @flyte.trace  */
  --code-keyword:       #b69bf5;  /* async def await return try except for   */
  --code-constant:      #b69bf5;  /* None True False self cls (italic)       */
  --code-function:      #74b6f2;  /* function definitions + call sites       */
  --code-class:         #5fcbc0;  /* classes, type annotations, builtins     */
  --code-string:        #8fcb7a;  /* string + f-string literals              */
  --code-number:        #ef9b55;  /* numeric literals                        */

  /* console / diff extras (terminal blocks, +/- blocks) */
  --code-error:         #e8676a;
  --code-added:         #8fcb7a;
  --code-removed:       #e8676a;
  --code-muted:         #848c95;

  /* chrome */
  --code-selection:     rgba(253, 181, 31, .22);
  --code-line-highlight:rgba(253, 181, 31, .08);
  --code-inline-bg:     #242628;
  --code-scrollbar:     #3a3d40;
}
#union-inference pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
/* the light theme is opt-in: add .u-theme-light to a code block's container *//* ═══ _shared/union-fig.css ═══ *//* ══════════════════════════════════════════════════════════════════════════
   union-fig.css — the home page's design language, shared by the platform
   pages (advanced-scheduling, agents, ai-factory, durability, inference,
   sovereign-ai).

   Source of truth: the "Home — Redesign" comp (Figma L1U2YQLR…, page 14:8)
   as realised in union/home/style.css. The geometry it encodes:

     · 1440 frame, 64px gutters, 1312 of content            (.u-wrap)
     · 130px of air above and below every section           (.fig-sec)
     · alternating grounds, black / near-black              (.is-alt)
     · centred intro pairs — big h2 over a 700px lead       (.fig-intro)
     · content rows as a 420 / 804 split with an 88px gap,
       sides alternating down the page                      (.fig-row .is-flip)
     · each row led by a numbered eyebrow, a yellow
       uppercase label, an h2, a lead, dot points, a link    (.fig-eyebrow …)
     · a full-bleed yellow closing block                     (.fig-cta)

   Two token systems are in play across these pages — union-system.css
   (--theme-* and --brand-*) and union-nocturne.css (--color-*). The two share no
   names, so every colour below reads the theme token first and falls back to
   the nocturne one. Nothing here needs a per-page bridge.
   ══════════════════════════════════════════════════════════════════════════ */
#union-inference {
  --fig-accent:  var(--theme-accent,  var(--color-accent, #fcb51f));
  --fig-heading: var(--theme-heading, var(--color-text, #ffffff));
  --fig-body:    var(--theme-body,    var(--color-neutral-400, #cccfd1));
  --fig-muted:   var(--brand-gray-350, var(--color-neutral-500, #aeb2b5));
  --fig-faint:   var(--brand-gray-400, var(--color-neutral-600, #81858b));
  --fig-border:  var(--theme-border,  var(--color-divider, rgba(255,255,255,.12)));
  --fig-ground:  #0c0c0d;   /* the alternating band, one step off black */
  --fig-ink:     #0b0b0c;   /* type on the yellow block */
}
/* ═══ inference/style.css ═══ *//* Union /inference landing page — page styles.
   ../_shared/union-nocturne.css (design tokens + base components) must be linked
   BEFORE this file. Everything here is new; nothing maps onto an existing
   Webflow class.

   The section furniture (`.in-kicker`, `.in-lede`, `.in-fix`, `.in-hero-*`,
   `.in-trow`, `.in-grid-*`) is the same shape as /agents' `.ag-*` set, so the
   two pages read as one system. If the Webflow project adopts either, adopt
   both under one prefix and delete the duplicate. *//* =====================================================================
   Component state classes (Designer-buildable)
   ===================================================================== *//* Content blocks are grounds, not chrome: no ring, and a surface barely lifted
   off the page, so the type and the code panels inside carry the structure.
   `.elev-sm` still sits on the markup — these rules load after
   union-nocturne.css and win. */
#union-inference { --in-soft: color-mix(in srgb, var(--color-surface) 55%, var(--color-bg)); }
/* =====================================================================
   WEBFLOW: paste into an Embed (base rules, pseudo-states, keyframes and
   media queries — CSS the Designer cannot express)
   ===================================================================== */
#union-inference { margin: 0; background: var(--color-bg); color: var(--color-text); font-size: 17px; }
#union-inference { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
#union-inference a { color: var(--color-accent); }
#union-inference [id] { scroll-margin-top: 88px; }
/* Status colors and the accent tint used by tab pills, file rows and chips.
   The syntax palette is NOT here: it comes from ../_shared/union-code-theme.css,
   the same file ../home/ loads, so all three pages highlight from one source. */
#union-inference { --ok: #8fcb7a; --err: #e8676a; --run: #74b6f2; --acc-icon: #f9d67f; }
@media (prefers-reduced-motion: reduce) {
  #union-inference { scroll-behavior: auto; }
}
/* ═══ port-only: the page's relationship to the host site ═══
   Carried over from the deployed sheet — these have no counterpart
   in the repo, because the standalone prototype has its own navbar
   and no host chrome to clear. */
#union-inference {
  --color-bg: #000000;        /* live --_theme---background */
  --color-surface: #18191a;   /* live --_theme---card */
  --color-text: #ffffff;      /* live --_theme---heading */
  --color-accent: #fcb51f;    /* live --_theme---accent */ /* review round 7 (Barron): the accent moves to
     the product's blurple — OKLCH hue 289.2, the hue of the app's own Pro
     accent (#9a8fe0, --om-accent-pro) — at the same lightness the steel
     accent held (L 0.660, so the documented ratios survive) and chroma
     in the product blurple's own range (its token sits at C 0.118; the
     accent takes 0.125, from the old steel's 0.030):
     the accent now reads as an accent rather than another neutral. */
  --color-accent-2: #f6c54c; /* the machine-derived stand-in follows: same
     hue, same L 0.734, chroma at the same 2:3 proportion it held */
  --color-divider: color-mix(in srgb, #ffffff 12%, transparent); /* live --_theme---border */

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. */
  --color-neutral-100: #ffffff;
  --color-neutral-200: #f2f3f3;  /* live --_brand---gray-100 */
  --color-neutral-300: #e3e5e6;
  --color-neutral-400: #cccfd1;  /* live --_theme---body (paragraphs) */
  --color-neutral-500: #aeb2b5;
  --color-neutral-600: #81858b;  /* live --_brand---gray-350 */
  --color-neutral-700: #72757a;  /* live --_brand---gray-400 */
  --color-neutral-800: #3a3d40;
  --color-neutral-900: #18191a;  /* live --_brand---dark, the card ground */

  --color-accent-100: #fdf4dc;
  --color-accent-200: #fbe7b4;
  --color-accent-300: #f9d67f;
  --color-accent-400: #f6c54c;
  --color-accent-500: #fcb51f;
  --color-accent-600: #ce9712;
  --color-accent-700: #a5780c;
  --color-accent-800: #785607;
  --color-accent-900: #4c3604;

  --color-accent-2-100: #fdf4dc;
  --color-accent-2-200: #fbe7b4;
  --color-accent-2-300: #f9d67f;
  --color-accent-2-400: #f6c54c;
  --color-accent-2-500: #fcb51f;
  --color-accent-2-600: #ce9712;
  --color-accent-2-700: #a5780c;
  --color-accent-2-800: #785607;
  --color-accent-2-900: #4c3604;

  /* Deck section-divider ground — review round 3: saturation as presence.
     Dividers take a saturated deep indigo (hue 277, the neutral ramp's own
     family; C 0.094 — written when the accent held C 0.030, before the
     round-7 blurple raised it past the ground's) with a lighter bloom and
     a ghost tint of the same hue, while the slide grounds stay
     desaturated. Deck-scale fills only — not interface colors. */
  --color-section: #33270a;
  --color-section-glow: #6b5109;
  --color-section-ghost: #b8860f;

  --font-heading: "Yellix", system-ui, sans-serif;
  --font-heading-weight: 600;  /* live h2/h3 weight */
  --font-body: "Yellix", system-ui, sans-serif;
  /* The mono face this file already @font-faces above. It used to be declared
     in home/style.css only, which meant every other page loading these tokens
     resolved var(--font-code) to nothing and rendered code in Yellix. */
  --font-code: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --space-1: 2.8px;
  --space-2: 5.6px;
  --space-3: 8.4px;
  --space-4: 11.2px;
  --space-6: 16.8px;
  --space-8: 22.4px;

  /* Rounder than the original Nocturne values, to sit with union.ai's live
     system (.5rem / 1rem / 1.5rem). Buttons and pills go fully round below. */
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 20px;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 0 0 1px rgba(255,255,255,0.06);
  --shadow-md: 0 0 0 1px rgba(255,255,255,0.08), 0 6px 18px rgba(0,0,0,0.55);
  --shadow-lg: 0 0 0 1px rgba(255,255,255,0.11), 0 16px 40px rgba(0,0,0,0.65);
}
#union-inference {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
#union-inference code, #union-inference pre, #union-inference kbd, #union-inference samp { font-family: var(--font-code); }
#union-inference { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; }
#union-inference p { margin: 0 0 var(--space-3); }
#union-inference a { color: var(--color-accent); text-underline-offset: 3px; }
#union-inference img { display: block; max-width: 100%; }
#union-inference figure { margin: 0; }
#union-inference figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
/* union-code-theme.css — syntax highlighting for every code block in website/union/.
   Tokens lifted verbatim from ../../color-palette/union-code-theme.css
   ("Union Yellow Dark" v1). That file is the source of truth: if the palette
   changes, re-copy sections 1 and 1c below rather than editing them here.

   Every token meets WCAG AA (4.5:1) on its own card background in both themes.
   Section 2 maps the tokens onto the class names the prototypes already use:
     .tok-*      model-factory, advanced-scheduling
     .sov-tok-*  sovereign-ai
     .code-*     home (emitted by script.js)
*/

/* ── 1. Tokens ─────────────────────────────────────────────────────────── */
#union-inference {
  /* surface */
  --code-bg:            #18191a;  /* = --brand-dark, the design-system card  */
  --code-border:        #ffffff1f;/* = --theme-border                        */
  --code-radius:        1rem;     /* = --radius-medium                       */

  /* neutrals — carry ~70% of the characters in a snippet */
  --code-fg:            #e6e8ea;  /* identifiers, variables, plain text      */
  --code-param:         #c9ced4;  /* keyword-argument + parameter names      */
  --code-punct:         #9aa0a6;  /* = -> , : ( ) [ ] and all operators      */
  --code-comment:       #848c95;  /* italic — the quietest token             */

  /* accents — four hues, nothing else */
  --code-decorator:     #fdb51f;  /* Union Yellow · @env.task, @flyte.trace  */
  --code-keyword:       #b69bf5;  /* async def await return try except for   */
  --code-constant:      #b69bf5;  /* None True False self cls (italic)       */
  --code-function:      #74b6f2;  /* function definitions + call sites       */
  --code-class:         #5fcbc0;  /* classes, type annotations, builtins     */
  --code-string:        #8fcb7a;  /* string + f-string literals              */
  --code-number:        #ef9b55;  /* numeric literals                        */

  /* console / diff extras (terminal blocks, +/- blocks) */
  --code-error:         #e8676a;
  --code-added:         #8fcb7a;
  --code-removed:       #e8676a;
  --code-muted:         #848c95;

  /* chrome */
  --code-selection:     rgba(253, 181, 31, .22);
  --code-line-highlight:rgba(253, 181, 31, .08);
  --code-inline-bg:     #242628;
  --code-scrollbar:     #3a3d40;
}
#union-inference pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
/* the light theme is opt-in: add .u-theme-light to a code block's container */

/* Union /inference landing page — page styles.
   ../_shared/union-nocturne.css (design tokens + base components) must be linked
   BEFORE this file. Everything here is new; nothing maps onto an existing
   Webflow class.

   The section furniture (`.in-kicker`, `.in-lede`, `.in-fix`, `.in-hero-*`,
   `.in-trow`, `.in-grid-*`) is the same shape as /agents' `.ag-*` set, so the
   two pages read as one system. If the Webflow project adopts either, adopt
   both under one prefix and delete the duplicate. */

/* =====================================================================
   Component state classes (Designer-buildable)
   ===================================================================== */

/* Content blocks are grounds, not chrome: no ring, and a surface barely lifted
   off the page, so the type and the code panels inside carry the structure.
   `.elev-sm` still sits on the markup — these rules load after
   union-nocturne.css and win. */
#union-inference { --in-soft: color-mix(in srgb, var(--color-surface) 55%, var(--color-bg)); }
/* =====================================================================
   WEBFLOW: paste into an Embed (base rules, pseudo-states, keyframes and
   media queries — CSS the Designer cannot express)
   ===================================================================== */

#union-inference { margin: 0; background: var(--color-bg); color: var(--color-text); font-size: 17px; }
#union-inference { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
#union-inference a { color: var(--color-accent); }
#union-inference [id] { scroll-margin-top: 88px; }
/* Status colors and the accent tint used by tab pills, file rows and chips.
   The syntax palette is NOT here: it comes from ../_shared/union-code-theme.css,
   the same file ../home/ loads, so all three pages highlight from one source. */
#union-inference { --ok: #8fcb7a; --err: #e8676a; --run: #74b6f2; --acc-icon: #f9d67f; }
@media (prefers-reduced-motion: reduce) {
  #union-inference { scroll-behavior: auto; }
}
/* ── logo masks (Webflow port only) ───────────────────────────────
   The prototype bakes each mark into the markup as a data: URI so the
   page works opened off disk. Here each one is defined once as a custom
   property and the markup references it, which keeps 11 KB of duplicated
   URI out of the per-embed payload. Generated by build_page.py. */
#union-inference {
  --logo-1: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M22.2819%209.8211a5.9847%205.9847%200%200%200-.5157-4.9108%206.0462%206.0462%200%200%200-6.5098-2.9A6.0651%206.0651%200%200%200%204.9807%204.1818a5.9847%205.9847%200%200%200-3.9977%202.9%206.0462%206.0462%200%200%200%20.7427%207.0966%205.98%205.98%200%200%200%20.511%204.9107%206.051%206.051%200%200%200%206.5146%202.9001A5.9847%205.9847%200%200%200%2013.2599%2024a6.0557%206.0557%200%200%200%205.7718-4.2058%205.9894%205.9894%200%200%200%203.9977-2.9001%206.0557%206.0557%200%200%200-.7475-7.0729zm-9.022%2012.6081a4.4755%204.4755%200%200%201-2.8764-1.0408l.1419-.0804%204.7783-2.7582a.7948.7948%200%200%200%20.3927-.6813v-6.7369l2.02%201.1686a.071.071%200%200%201%20.038.052v5.5826a4.504%204.504%200%200%201-4.4945%204.4944zm-9.6607-4.1254a4.4708%204.4708%200%200%201-.5346-3.0137l.142.0852%204.783%202.7582a.7712.7712%200%200%200%20.7806%200l5.8428-3.3685v2.3324a.0804.0804%200%200%201-.0332.0615L9.74%2019.9502a4.4992%204.4992%200%200%201-6.1408-1.6464zM2.3408%207.8956a4.485%204.485%200%200%201%202.3655-1.9728V11.6a.7664.7664%200%200%200%20.3879.6765l5.8144%203.3543-2.0201%201.1685a.0757.0757%200%200%201-.071%200l-4.8303-2.7865A4.504%204.504%200%200%201%202.3408%207.872zm16.5963%203.8558L13.1038%208.364%2015.1192%207.2a.0757.0757%200%200%201%20.071%200l4.8303%202.7913a4.4944%204.4944%200%200%201-.6765%208.1042v-5.6772a.79.79%200%200%200-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759%200%200%200-.7854%200L9.409%209.2297V6.8974a.0662.0662%200%200%201%20.0284-.0615l4.8303-2.7866a4.4992%204.4992%200%200%201%206.6802%204.66zM8.3065%2012.863l-2.02-1.1638a.0804.0804%200%200%201-.038-.0567V6.0742a4.4992%204.4992%200%200%201%207.3757-3.4537l-.142.0805L8.704%205.459a.7948.7948%200%200%200-.3927.6813zm1.0976-2.3654l2.602-1.4998%202.6069%201.4998v2.9994l-2.5974%201.4997-2.6067-1.4997Z%22%2F%3E%3C%2Fsvg%3E");
  --logo-2: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M12.19%202.38a9.344%209.344%200%200%200-9.234%206.893c.053-.02-.055.013%200%200-3.875%202.551-3.922%208.11-.247%2010.941l.006-.007-.007.03a6.717%206.717%200%200%200%204.077%201.356h5.173l.03.03h5.192c6.687.053%209.376-8.605%203.835-12.35a9.365%209.365%200%200%200-2.821-4.552l-.043.043.006-.05A9.344%209.344%200%200%200%2012.19%202.38zm-.358%204.146c1.244-.04%202.518.368%203.486%201.15a5.186%205.186%200%200%201%201.862%204.078v.518c3.53-.07%203.53%205.262%200%205.193h-5.193l-.008.009v-.04H6.785a2.59%202.59%200%200%201-1.067-.23h.001a2.597%202.597%200%201%201%203.437-3.437l3.013-3.012A6.747%206.747%200%200%200%208.11%208.24c.018-.01.04-.026.054-.023a5.186%205.186%200%200%201%203.67-1.69z%22%2F%3E%3C%2Fsvg%3E");
  --logo-3: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M11.04%2019.32Q12%2021.51%2012%2024q0-2.49.93-4.68.96-2.19%202.58-3.81t3.81-2.55Q21.51%2012%2024%2012q-2.49%200-4.68-.93a12.3%2012.3%200%200%201-3.81-2.58%2012.3%2012.3%200%200%201-2.58-3.81Q12%202.49%2012%200q0%202.49-.96%204.68-.93%202.19-2.55%203.81a12.3%2012.3%200%200%201-3.81%202.58Q2.49%2012%200%2012q2.49%200%204.68.96%202.19.93%203.81%202.55t2.55%203.81%22%2F%3E%3C%2Fsvg%3E");
  --logo-4: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M17.143%203.429v3.428h-3.429v3.429h-3.428V6.857H6.857V3.43H3.43v13.714H0v3.428h10.286v-3.428H6.857v-3.429h3.429v3.429h3.429v-3.429h3.428v3.429h-3.428v3.428H24v-3.428h-3.43V3.429z%22%2F%3E%3C%2Fsvg%3E");
  --logo-5: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M23.748%204.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434%201.202-.422%201.84.027%201.436.633%202.58%201.838%203.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5%205.5%200%200%201-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12%2012%200%200%200-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3%203%200%200%201-.465.136%209.6%209.6%200%200%200-2.883-.101c-1.885.21-3.39%201.1-4.497%202.622C.082%208.776-.231%2010.854.152%2013.02c.403%202.284%201.568%204.175%203.36%205.653%201.857%201.533%203.997%202.284%206.438%202.14%201.482-.085%203.132-.284%204.994-1.86.47.234.962.328%201.78.398.629.058%201.235-.031%201.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926%201.095-1.295%202.768-3.598%203.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2%204.2%200%200%200%201.545-.475c1.397-.763%201.96-2.016%202.093-3.517.02-.23-.004-.467-.247-.588M11.58%2018.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7%204.7%200%200%201%201.53-.038c2.131.311%203.946%201.264%205.467%202.774.868.86%201.525%201.887%202.202%202.89.72%201.066%201.494%202.082%202.48%202.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306%200%200%201%20.415-.287.3.3%200%200%201%20.113.074.3.3%200%200%201%20.086.214c0%20.17-.136.307-.308.307a.303.303%200%200%201-.306-.307m3.11%201.596c-.2.081-.4.151-.591.16a1.25%201.25%200%200%201-.798-.254c-.274-.23-.47-.358-.551-.758a1.7%201.7%200%200%201%20.015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6%200%200%201-.254-.078.253.253%200%200%201-.114-.358%201%201%200%200%201%20.192-.21c.356-.202.767-.136%201.146.016.352.144.618.408%201.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45%22%2F%3E%3C%2Fsvg%3E");
  --logo-6: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M14.234%2010.162%2022.977%200h-2.072l-7.591%208.824L7.251%200H.258l9.168%2013.343L.258%2024H2.33l8.016-9.318L16.749%2024h6.993zm-2.837%203.299-.929-1.329L3.076%201.56h3.182l5.965%208.532.929%201.329%207.754%2011.09h-3.182z%22%2F%3E%3C%2Fsvg%3E");
  --logo-7: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M22.3977%207.0896h-2.3106V.0676l-7.5094%206.3542V.1577h-1.1554v6.1966L4.4904%200v7.0896H1.6023v10.3976h2.8882V24l6.932-6.3591v6.2005h1.1554v-6.0469l6.9318%206.1807v-6.4879h2.8882V7.0896zm-3.4657-4.531v4.531h-5.355l5.355-4.531zm-13.2862.0676%204.8691%204.4634H5.6458V2.6262zM2.7576%2016.332V8.245h7.8476l-6.1149%206.1147v1.9723H2.7576zm2.8882%205.0404v-3.8852h.0001v-2.6488l5.7763-5.7764v7.0111l-5.7764%205.2993zm12.7086.0248-5.7766-5.1509V9.0618l5.7766%205.7766v6.5588zm2.8882-5.0652h-1.733v-1.9723L13.3948%208.245h7.8478v8.087z%22%2F%3E%3C%2Fsvg%3E");
  --logo-8: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M16.778%201.844v1.919q-.569-.026-1.138-.032-.708-.008-1.415.037c-1.93.126-4.023.728-6.149%202.237-2.911%202.066-2.731%201.95-4.14%202.75-.396.223-1.342.574-2.185.798-.841.225-1.753.333-1.751.333v4.229s.768.108%201.61.333c.842.224%201.789.575%202.185.799%201.41.798%201.228.683%204.14%202.75%202.126%201.509%204.22%202.11%206.148%202.236.88.058%201.716.041%202.555.005v1.918l7.222-4.168-7.222-4.17v2.176c-.86.038-1.611.065-2.278.021-1.364-.09-2.417-.357-3.979-1.465-2.244-1.593-2.866-2.027-3.68-2.508.889-.518%201.449-.906%203.822-2.59%201.56-1.109%202.614-1.377%203.978-1.466.667-.044%201.418-.017%202.278.02v2.176L24%206.014Z%22%2F%3E%3C%2Fsvg%3E");
  --logo-9: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M12.025%201.13c-5.77%200-10.449%204.647-10.449%2010.378%200%201.112.178%202.181.503%203.185.064-.222.203-.444.416-.577a.96.96%200%200%201%20.524-.15c.293%200%20.584.124.84.284.278.173.48.408.71.694.226.282.458.611.684.951v-.014c.017-.324.106-.622.264-.874s.403-.487.762-.543c.3-.047.596.06.787.203s.31.313.4.467c.15.257.212.468.233.542.01.026.653%201.552%201.657%202.54.616.605%201.01%201.223%201.082%201.912.055.537-.096%201.059-.38%201.572.637.121%201.294.187%201.967.187.657%200%201.298-.063%201.921-.178-.287-.517-.44-1.041-.384-1.581.07-.69.465-1.307%201.081-1.913%201.004-.987%201.647-2.513%201.657-2.539.021-.074.083-.285.233-.542.09-.154.208-.323.4-.467a1.08%201.08%200%200%201%20.787-.203c.359.056.604.29.762.543s.247.55.265.874v.015c.225-.34.457-.67.683-.952.23-.286.432-.52.71-.694.257-.16.547-.284.84-.285a.97.97%200%200%201%20.524.151c.228.143.373.388.43.625l.006.04a10.3%2010.3%200%200%200%20.534-3.273c0-5.731-4.678-10.378-10.449-10.378M8.327%206.583a1.5%201.5%200%200%201%20.713.174%201.487%201.487%200%200%201%20.617%202.013c-.183.343-.762-.214-1.102-.094-.38.134-.532.914-.917.71a1.487%201.487%200%200%201%20.69-2.803m7.486%200a1.487%201.487%200%200%201%20.689%202.803c-.385.204-.536-.576-.916-.71-.34-.12-.92.437-1.103.094a1.487%201.487%200%200%201%20.617-2.013%201.5%201.5%200%200%201%20.713-.174m-10.68%201.55a.96.96%200%201%201%200%201.921.96.96%200%200%201%200-1.92m13.838%200a.96.96%200%201%201%200%201.92.96.96%200%200%201%200-1.92M8.489%2011.458c.588.01%201.965%201.157%203.572%201.164%201.607-.007%202.984-1.155%203.572-1.164.196-.003.305.12.305.454%200%20.886-.424%202.328-1.563%203.202-.22-.756-1.396-1.366-1.63-1.32q-.011.001-.02.006l-.044.026-.01.008-.03.024q-.018.017-.035.036l-.032.04a1%201%200%200%200-.058.09l-.014.025q-.049.088-.11.19a1%201%200%200%201-.083.116%201.2%201.2%200%200%201-.173.18q-.035.029-.075.058a1.3%201.3%200%200%201-.251-.243%201%201%200%200%201-.076-.107c-.124-.193-.177-.363-.337-.444-.034-.016-.104-.008-.2.022q-.094.03-.216.087-.06.028-.125.063l-.13.074q-.067.04-.136.086a3%203%200%200%200-.135.096%203%203%200%200%200-.26.219%202%202%200%200%200-.12.121%202%202%200%200%200-.106.128l-.002.002a2%202%200%200%200-.09.132l-.001.001a1.2%201.2%200%200%200-.105.212q-.013.036-.024.073c-1.139-.875-1.563-2.317-1.563-3.203%200-.334.109-.457.305-.454m.836%2010.354c.824-1.19.766-2.082-.365-3.194-1.13-1.112-1.789-2.738-1.789-2.738s-.246-.945-.806-.858-.97%201.499.202%202.362c1.173.864-.233%201.45-.685.64-.45-.812-1.683-2.896-2.322-3.295s-1.089-.175-.938.647%202.822%202.813%202.562%203.244-1.176-.506-1.176-.506-2.866-2.567-3.49-1.898.473%201.23%202.037%202.16c1.564.932%201.686%201.178%201.464%201.53s-3.675-2.511-4-1.297c-.323%201.214%203.524%201.567%203.287%202.405-.238.839-2.71-1.587-3.216-.642-.506.946%203.49%202.056%203.522%202.064%201.29.33%204.568%201.028%205.713-.624m5.349%200c-.824-1.19-.766-2.082.365-3.194%201.13-1.112%201.789-2.738%201.789-2.738s.246-.945.806-.858.97%201.499-.202%202.362c-1.173.864.233%201.45.685.64.451-.812%201.683-2.896%202.322-3.295s1.089-.175.938.647-2.822%202.813-2.562%203.244%201.176-.506%201.176-.506%202.866-2.567%203.49-1.898-.473%201.23-2.037%202.16c-1.564.932-1.686%201.178-1.464%201.53s3.675-2.511%204-1.297c.323%201.214-3.524%201.567-3.287%202.405.238.839%202.71-1.587%203.216-.642.506.946-3.49%202.056-3.522%202.064-1.29.33-4.568%201.028-5.713-.624%22%2F%3E%3C%2Fsvg%3E");
  --logo-10: url("data:image/svg+xml;utf8,%3Csvg%20fill%3D%22currentColor%22%20role%3D%22img%22%20viewBox%3D%220%200%2024%2024%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M4.6035%200v24h4.9317V0zm9.8613%200v24h4.9317V0z%22%2F%3E%3C%2Fsvg%3E");
}
/* ══════════════════════════════════════════════════════════════════════════
   WEBFLOW PORT ONLY — none of this is in the repo's style.css.
   ══════════════════════════════════════════════════════════════════════════ */

/* This page was duplicated from Home, so it carries Home's stock sections and
   the "section - cta" ComponentInstance ("Start today and scale with
   confidence" / "Chat with an engineer") above the prototype. set_visibility is
   unsupported on ComponentInstances and remove_element is irreversible, so it
   is suppressed here. This stylesheet loads only on this page, so the unscoped
   rules below are page-scoped by virtue of that. */
.main-wrapper > section.section_cta25 { display: none; }
/* The host site styles BARE elements, and those rules reach inside embeds — a
   scoped rule only wins for properties it actually declares. Same trap the
   /signup port hit with blockquote and figcaption. */
#union-inference figure, #union-inference blockquote, #union-inference figcaption {
  margin: 0; padding: 0; border: 0; text-align: inherit;
}
#union-inference ul, #union-inference ol { margin: 0; padding: 0; }
#union-inference button { font: inherit; color: inherit; }
/* The site's .navigation is position:fixed (~8rem tall), so page content starts
   underneath it and the hero collides with the nav links. Clear it the way the
   site's own first section does (.section_header26 { padding-top: 8rem }), and
   keep anchor targets from landing under the bar. The 8.5rem matches the 136px
   the port shim subtracts in its click handler — change both together. */
#union-inference { padding-top: 8rem; }
#union-inference [id] { scroll-margin-top: 8.5rem; }
/* ── host navbar CTA (port only) ──────────────────────────────────────────
   Deliberately UNSCOPED: the site's navbar renders outside the wrapper. The
   shim relabels the navbar's "Chat with an engineer" to "Get Started" and flips
   the attribute once the hero scrolls away. Hidden from FIRST PAINT so the
   wrong label never flashes before the deferred script runs; visibility (not
   display) keeps the navbar from reflowing when it appears. */
.navigation .navbar2_button-wrapper > a.button { opacity: 0; visibility: hidden; }
.navigation a[data-nav-signup] {
  opacity: 0; visibility: hidden;
  transition: opacity 240ms ease, visibility 0s linear 240ms;
}
.navigation a[data-nav-signup][data-nav-signup-on="1"] {
  opacity: 1; visibility: visible;
  transition: opacity 240ms ease, visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .navigation a[data-nav-signup] { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════════
   PORT-ONLY RULES — these lived in a <style> tag inside the stylesheet
   embed until now. Same rules, same order, same place in the cascade:
   they sat immediately after the <link>, so appending them to the end of
   the sheet it loads keeps them winning the same ties. Moving them here
   leaves that embed a single <link> line and puts every rule the page
   uses into one versioned file.
   ══════════════════════════════════════════════════════════════════════ */
/* Hold the fixed nav's height open; the next embed replaces it with the
     measured value. Keep this embed free of script tags, including inside
     comments — Webflow flags any embed whose code contains that token and
     renders none of its contents on the Designer canvas. */
  #union-inference { padding-top: 138px; }
  @media (max-width: 991px) { #union-inference { padding-top: 96px; } }

  /* ── host navbar ────────────────────────────────────────────
     Unscoped on purpose: the bar renders outside the wrapper above.
     Nav rules that apply site-wide now live in the navbar component. */
  .navigation .navbar2_button-wrapper > a.navbar2_link {
    padding: 0;
    margin-right: .75rem;
    color: rgba(255, 255, 255, .62);
    white-space: nowrap;
    text-decoration: none;
    transition: color .18s ease;
  }
  .navigation .navbar2_button-wrapper > a.navbar2_link:hover,
  .navigation .navbar2_button-wrapper > a.navbar2_link:focus-visible { color: #fff; }
  .navigation .navbar2_button-wrapper > a.button,
  .navigation .navbar2_button-wrapper > a.button .button_text { white-space: nowrap; }
  .navigation .navbar2_button-wrapper > a.button {
    opacity: 0;
    visibility: hidden;
    transition: opacity 240ms ease, visibility 0s linear 240ms;
  }
  .navigation .navbar2_button-wrapper > a.button[data-nav-cta-on="1"] {
    opacity: 1;
    visibility: visible;
    transition: opacity 240ms ease, visibility 0s;
  }
  @media (prefers-reduced-motion: reduce) {
    .navigation .navbar2_button-wrapper > a.button,
    .navigation .navbar2_button-wrapper > a.navbar2_link { transition: none; }
  }

  /* ── mobile code type ──────────────────────────────────────
     The page stylesheet clamps every code line to 11.5px with !important
     below 860px, which beats even the inline sizes on the lines themselves.
     Same breakpoint here so the replacement is clean. */
  @media (max-width: 860px) {
    #union-inference [data-code-line],
    #union-inference .mono {
      font-size: 12.5px !important;
      line-height: 1.65 !important;
    }
  }

  /* ── mobile widgets ────────────────────────────────────────
     Drawn at desktop density, so on a phone the labels land at 9.5–12px.
     Raise the floor to 13px, 12.5px for the monospace runs. */
  @media (max-width: 767px) {

    /* The gateway is drawn as one left-to-right run:
       guard -> providers -> guard, on a 96px 16px 1fr 16px 96px grid. The
       fixed columns alone eat 264 of the 284 available, leaving the
       providers box 20px and its copy spilling across the guards either
       side. Stack the five parts instead and turn the arrows to match the
       new reading direction. */
    #union-inference .in-gw_row {
      grid-template-columns: minmax(0, 1fr);
      gap: 8px;
    }
    #union-inference .in-gw_cell { height: auto; min-height: 0; }
    #union-inference .in-gw_arrow { transform: rotate(90deg); justify-self: center; }

    #union-inference .card-kicker,
    #union-inference .in-chart-legend,
    #union-inference .in-console-status,
    #union-inference .in-console-url,
    #union-inference .in-cpane-head,
    #union-inference .in-dval,
    #union-inference .in-file,
    #union-inference .in-guard-file,
    #union-inference .in-kdesc,
    #union-inference .in-kicker,
    #union-inference .in-krow,
    #union-inference .in-mcaret,
    #union-inference .in-mfilter,
    #union-inference .in-mlegend,
    #union-inference .in-prov-id,
    #union-inference .in-stat-k,
    #union-inference .in-trow { font-size: 13px; }

    /* .tag-outline sets its own size and outranks the .tag rule. */
    #union-inference .tag,
    #union-inference .tag.tag-outline { font-size: 12.5px; }

    #union-inference .in-console-facts,
    #union-inference .in-logbar,
    #union-inference .in-logline,
    #union-inference .in-prov-mono { font-size: 12.5px; }

    /* Inline font-size attributes below the floor — the prototypes set
       these per element, so a class rule cannot reach them. */
    #union-inference [style*="font-size:9.5px"],
    #union-inference [style*="font-size:12px"] { font-size: 12.5px !important; }

    /* A little more room now that the type is bigger. */
    #union-inference .in-krow,
    #union-inference .in-trow { padding: 10px 12px; }
  }
