/* ═══ _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-agents {
  --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-agents {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
#union-agents h1, #union-agents h2, #union-agents h3, #union-agents h4 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }
#union-agents code, #union-agents pre, #union-agents kbd, #union-agents samp { font-family: var(--font-code); }
#union-agents .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-agents *, #union-agents *::before, #union-agents *::after { box-sizing: border-box; }
#union-agents { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; }
#union-agents h1, #union-agents h2, #union-agents h3, #union-agents h4, #union-agents h5, #union-agents 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-agents h1 { font-size: 42px; }
#union-agents h2 { font-size: 32px; }
#union-agents h3 { font-size: 25px; }
#union-agents h4 { font-size: 20px; }
#union-agents h5 { font-size: 16px; }
#union-agents h6 { font-size: 13px; }
#union-agents h6 { letter-spacing: 0.08em; text-transform: uppercase; }
#union-agents p { margin: 0 0 var(--space-3); }
#union-agents a { color: var(--color-accent); text-underline-offset: 3px; }
#union-agents img { display: block; max-width: 100%; }
#union-agents figure { margin: 0; }
#union-agents figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
#union-agents .text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
#union-agents :focus { outline: none; }
#union-agents :focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
#union-agents ::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-agents .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-agents .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-agents .btn svg { display: block; }
#union-agents .btn:disabled { opacity: 0.45; cursor: not-allowed; }
#union-agents .btn-primary { color: var(--color-accent); border-color: var(--color-accent); }
#union-agents .btn-primary:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
#union-agents .btn-primary:active { background: color-mix(in srgb, var(--color-accent) 22%, transparent); }
#union-agents .btn-secondary { border-color: var(--color-divider); }
#union-agents .btn-secondary:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
#union-agents .btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
#union-agents .btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
#union-agents .btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
#union-agents .btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
#union-agents .btn-icon { width: 36px; height: 36px; padding: 0; }
#union-agents .btn-block { width: 100%; margin-top: var(--space-2); }
/* — forms — */
#union-agents .field > label {
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
#union-agents .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-agents .input:hover { border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }
#union-agents .input:focus-visible { border-color: var(--color-accent); outline-offset: 0; }
#union-agents textarea.input { min-height: 90px; resize: vertical; }
#union-agents .radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
#union-agents .radio input, #union-agents .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
#union-agents .radio .dot {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}
#union-agents .radio:hover .dot { border-color: var(--color-accent); }
#union-agents .radio input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}
#union-agents .radio input:focus-visible + .dot { outline: 2px solid var(--color-accent); outline-offset: 2px; }
#union-agents .seg {
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
#union-agents .seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; font-size: 14px; cursor: pointer;
}
#union-agents .seg-opt + .seg-opt { border-left: 1px solid var(--color-divider); }
#union-agents .seg-opt:has(input:checked) { color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent); }
#union-agents .seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
#union-agents .seg-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: -2px; }
/* — cards — */
#union-agents .card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}
#union-agents .card-kicker { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
#union-agents .card-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 19px; line-height: 1.2;
}
#union-agents .card-body { margin: 0; font-size: 15.5px; opacity: 0.8; flex: 1; }
#union-agents .card-meta {
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
}
#union-agents .elev-sm { box-shadow: var(--shadow-sm); }
#union-agents .elev-md { box-shadow: var(--shadow-md); }
#union-agents .elev-lg { box-shadow: var(--shadow-lg); }
/* — tags — */
#union-agents .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-agents .tag-accent { background: var(--color-accent-800); color: var(--color-accent-100); }
#union-agents .tag-accent-2 { background: var(--color-accent-2-800); color: var(--color-accent-2-100); }
#union-agents .tag-neutral { background: var(--color-neutral-800); color: var(--color-neutral-100); }
#union-agents .tag-outline { border: 1px solid var(--color-accent); color: var(--color-accent); }
/* — navigation — */
#union-agents .nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: none;
}
#union-agents .nav-brand {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; margin-right: auto;
}
#union-agents .nav a { color: inherit; text-decoration: none; font-size: 15.5px; }
#union-agents .nav a:hover, #union-agents .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-agents .nav a.nav-utility { color: var(--color-neutral-500); }
#union-agents .nav a.nav-utility:hover { color: var(--color-accent); }
/* — tables — */
#union-agents .table { width: 100%; border-collapse: collapse; font-size: 14px; }
#union-agents .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-agents .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-agents .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-agents .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-agents .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-agents .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-agents .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-agents .dialog-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px;
}
#union-agents .dialog-body { font-size: 14px; opacity: 0.85; }
#union-agents .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-agents {
  /* 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-agents .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-agents pre, #union-agents pre code, #union-agents .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-agents pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
#union-agents pre ::selection, #union-agents pre::selection { background: var(--code-selection); }
#union-agents pre::-webkit-scrollbar-thumb { background: var(--code-scrollbar); border-radius: 4px; }
/* inline `code` inside body copy */
#union-agents :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-agents .tok-kw, #union-agents .sov-tok-kw, #union-agents .code-kw { color: var(--code-keyword); }
#union-agents .tok-str, #union-agents .sov-tok-str, #union-agents .code-str { color: var(--code-string); }
#union-agents .tok-title, #union-agents .sov-tok-title, #union-agents .code-title { color: var(--code-function); }
#union-agents .tok-param, #union-agents .code-param { color: var(--code-param); }
#union-agents .tok-meta, #union-agents .sov-tok-meta, #union-agents .code-meta { color: var(--code-decorator); }
#union-agents .tok-comment, #union-agents .code-comment { color: var(--code-comment); font-style: italic; }
#union-agents .tok-num, #union-agents .sov-tok-num, #union-agents .code-num { color: var(--code-number); }
#union-agents .tok-class, #union-agents .sov-tok-class, #union-agents .code-class { color: var(--code-class); }
#union-agents .code-punct { color: var(--code-punct); }
#union-agents .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-agents {
  --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-agents .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-agents .fig-sec { padding-top: clamp(56px, 9vw, 130px); padding-bottom: clamp(56px, 9vw, 130px); }
#union-agents .fig-sec.is-alt { background: var(--fig-ground); }
#union-agents .fig-sec.is-tight { padding-top: clamp(40px, 6vw, 84px); padding-bottom: clamp(40px, 6vw, 84px); }
/* ── centred intro pair ────────────────────────────────────────────── */
#union-agents .fig-intro { text-align: center; }
#union-agents .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-agents .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-agents .fig-intro_body { margin-top: clamp(40px, 5.5vw, 72px); text-align: left; }
/* ── content row: copy one side, visual the other ──────────────────── */
#union-agents .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-agents .fig-row.is-flip { grid-template-columns: minmax(0, 804fr) minmax(0, 420fr); }
#union-agents .fig-row.is-flip .fig-copy { order: 2; }
#union-agents .fig-row.is-flip .fig-visual { order: 1; }
/* for rows whose visual is denser than the comp's 470px placeholder */
#union-agents .fig-row.is-roomy { grid-template-columns: minmax(0, 360fr) minmax(0, 864fr); }
#union-agents .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-agents .fig-row.is-even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
#union-agents .fig-copy { min-width: 0; }
#union-agents .fig-visual { min-width: 0; }
/* ── row furniture ─────────────────────────────────────────────────── */
#union-agents .fig-eyebrow { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
#union-agents .fig-eyebrow_n { font-size: 13px; letter-spacing: 0.06em; color: var(--fig-faint); }
#union-agents .fig-eyebrow_rule { display: block; width: 24px; height: 1px; background: var(--fig-border); }
#union-agents .fig-label {
  font-size: 15px; font-weight: 600; letter-spacing: 0.085em; text-transform: uppercase;
  color: var(--fig-accent); margin-bottom: 18px;
}
#union-agents .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-agents .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-agents .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-agents .fig-lead:last-child { margin-bottom: 0; }
#union-agents .fig-points { list-style: none; margin: 0 0 30px; padding: 0; display: grid; gap: 12px; }
#union-agents .fig-points li {
  position: relative; padding-left: 18px; font-size: 16px; line-height: 1.6;
  color: var(--fig-body); text-wrap: pretty;
}
#union-agents .fig-points li::before {
  content: ""; position: absolute; left: 0; top: 0.58em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--fig-accent);
}
#union-agents .fig-points li b, #union-agents .fig-points li strong { color: var(--fig-heading); font-weight: 600; }
#union-agents .fig-link {
  display: inline-block; font-size: 15px; font-weight: 500;
  color: var(--fig-accent); text-decoration: none;
}
#union-agents .fig-link:hover { opacity: 0.8; }
/* caption under a visual — the comp puts a title + note inside the placeholder */
#union-agents .fig-cap { margin-top: 18px; display: flex; flex-direction: column; gap: 5px; }
#union-agents .fig-cap_t { font-size: 15.5px; font-weight: 600; color: var(--fig-heading); }
#union-agents .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-agents .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-agents .fig-cta.has-strip { padding-bottom: clamp(40px, 5vw, 64px); }
#union-agents .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-agents .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-agents .fig-cta_btns { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
#union-agents .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-agents .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-agents .fig-cta a:not(.fig-cta_btn):not(.button):not(.btn), #union-agents .fig-cta a:not(.fig-cta_btn):not(.button):not(.btn):hover { color: var(--fig-ink); }
#union-agents .fig-cta a.fig-cta_btn { color: var(--fig-accent); }
#union-agents .fig-cta a.fig-cta_btn.is-ghost { color: var(--fig-ink); }
#union-agents .fig-cta a.fig-cta_btn:hover { background: #1c1c1e; border-color: #1c1c1e; color: var(--fig-accent); }
#union-agents .fig-cta a.fig-cta_btn.is-ghost:hover { background: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-agents .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-agents .fig-strip_text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
#union-agents .fig-strip_h { font-size: clamp(17px, 1.9vw, 22px); font-weight: 600; letter-spacing: -0.015em; color: var(--fig-ink); }
#union-agents .fig-strip_p { font-size: 15px; color: rgba(11, 11, 12, 0.7); text-wrap: pretty; }
@media (max-width: 1080px) {
  #union-agents .fig-row, #union-agents .fig-row.is-flip, #union-agents .fig-row.is-roomy, #union-agents .fig-row.is-roomy.is-flip, #union-agents .fig-row.is-even {
    grid-template-columns: minmax(0, 1fr); gap: clamp(28px, 5vw, 44px);
  }
  #union-agents .fig-row.is-flip .fig-copy, #union-agents .fig-row.is-flip .fig-visual { order: 0; }
  #union-agents .fig-points { margin-bottom: 24px; }
}
@media (max-width: 640px) {
  #union-agents .fig-eyebrow { margin-bottom: 10px; }
  #union-agents .fig-label { margin-bottom: 12px; font-size: 13.5px; }
  #union-agents .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-agents .fig-sec .padding-section-large, #union-agents .fig-sec .padding-section-medium { padding-top: 0; padding-bottom: 0; }
/* the tagline chip becomes the comp's yellow uppercase label */
#union-agents .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-agents .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-agents .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-agents .fig-sec .text-align-center .text-size-medium, #union-agents .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-agents .fig-sec .spacer-xxlarge { height: clamp(40px, 5.5vw, 72px); }
#union-agents .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-agents .fig-sec > h2, #union-agents .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-agents .fig-cta .padding-section-large, #union-agents .fig-cta .padding-section-medium { padding-top: 0; padding-bottom: 0; }
#union-agents .fig-cta [class*="cta_band"] { border: 0; background: none; padding: 0; text-align: center; }
#union-agents .fig-cta .heading-style-h2, #union-agents .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-agents .fig-cta .text-size-medium, #union-agents .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-agents .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-agents .fig-cta .button-group { justify-content: center; }
#union-agents .fig-cta .button {
  border-color: var(--fig-ink); background-color: var(--fig-ink);
  color: var(--fig-accent); border-radius: 999px;
}
#union-agents .fig-cta .button:hover { border-color: #1c1c1e; background-color: #1c1c1e; color: var(--fig-accent); }
#union-agents .fig-cta .button.is-secondary {
  border-color: rgba(11, 11, 12, 0.35); background-color: transparent; color: var(--fig-ink);
}
#union-agents .fig-cta .button.is-secondary:hover { background-color: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-agents .fig-cta .cta-note { color: rgba(11, 11, 12, 0.6); }
#union-agents .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-agents .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-agents .fig-oss .text-style-tagline { color: #8b5cf6; }
#union-agents .fig-oss .flyte-stat { border-left-color: rgba(139, 92, 246, 0.38); }
#union-agents .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-agents .fig-sec .ag-kicker, #union-agents .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-agents .fig-sec .ag-lede, #union-agents .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-agents .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-agents .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-agents .fig-cta p, #union-agents .fig-cta .text-size-tiny, #union-agents .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-agents .fig-cta .button .button_text, #union-agents .fig-cta .button > * { color: inherit; }
#union-agents .fig-cta .button-group { justify-content: center; }
#union-agents .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-agents .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-agents .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-agents .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-agents .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-agents .fig-cta.ag-cta, #union-agents .fig-cta.in-cta { background: var(--fig-accent); color: var(--fig-ink); }
#union-agents .fig-cta.ag-cta h2, #union-agents .fig-cta.in-cta h2 { color: var(--fig-ink); }
#union-agents .fig-cta.ag-cta p, #union-agents .fig-cta.in-cta p { color: rgba(11, 11, 12, 0.78); }
#union-agents .fig-cta .btn.cta-accent {
  background: var(--fig-ink); border-color: var(--fig-ink); color: var(--fig-accent);
}
#union-agents .fig-cta .btn.cta-accent:hover { background: #1c1c1e; border-color: #1c1c1e; color: var(--fig-accent); }
#union-agents .fig-cta .btn.btn-secondary {
  background: transparent; border-color: rgba(11, 11, 12, 0.35); color: var(--fig-ink);
}
#union-agents .fig-cta .btn.btn-secondary:hover { background: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-agents .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-agents .fig-cta.ag-cta h2, #union-agents .fig-cta.in-cta h2, #union-agents .fig-cta.ag-cta p, #union-agents .fig-cta.in-cta p {
  margin-left: auto !important; margin-right: auto !important;
}
#union-agents .fig-cta.ag-cta > div, #union-agents .fig-cta.in-cta > div { padding-left: 0; padding-right: 0; }
#union-agents .fig-cta.ag-cta > div > div, #union-agents .fig-cta.in-cta > div > div { justify-content: center; }
#union-agents .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-agents .fig-cta .mono { color: rgba(11, 11, 12, 0.6) !important; }
#union-agents .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-agents .cap-grid, #union-agents .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-agents .cap-grid > *, #union-agents .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-agents .cap-grid.is-4up, #union-agents .proof-grid.is-4up { --cap-cols: 4; }
#union-agents .cap-grid.is-5up, #union-agents .proof-grid.is-5up { --cap-cols: 5; }
#union-agents .cap-cell, #union-agents .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-agents .cap-cell > *, #union-agents .proof-cell > * { position: relative; z-index: 1; }
#union-agents .cap-cell:hover, #union-agents .proof-cell:hover {
  background: color-mix(in srgb, var(--fig-heading) 5%, transparent);
  transform: translateY(-3px);
}
#union-agents .cap-cell:focus-visible, #union-agents .proof-cell:focus-visible { outline: 2px solid var(--fig-accent); outline-offset: -2px; }
#union-agents .cap-cell::before, #union-agents .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-agents .cap-cell::after, #union-agents .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-agents .cap-cell:hover::before, #union-agents .proof-cell:hover::before { opacity: 1; }
#union-agents .cap-cell:hover::after, #union-agents .proof-cell:hover::after { transform: scaleX(1); }
/* contents card — the glyph is a ↓ because the card jumps down the page */
#union-agents .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-agents .cap-cell_desc { font-size: 16px; line-height: 1.5; color: var(--fig-muted); text-wrap: pretty; transition: color .18s ease; }
#union-agents .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-agents .cap-cell:hover .cap-cell_name { color: var(--fig-accent); }
#union-agents .cap-cell:hover .cap-cell_desc { color: var(--fig-body); }
#union-agents .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-agents .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-agents .proof-cell:hover .proof-cell_co { transform: translateX(2px); }
#union-agents .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-agents .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-agents .proof-cell:hover .proof-cell_result::after { color: var(--fig-accent); transform: translate(3px, -3px); }
#union-agents .proof-cell_cap { margin-top: auto; padding-top: 14px; font-size: 14px; color: var(--fig-faint); transition: color .18s ease; }
#union-agents .proof-cell:hover .proof-cell_cap { color: var(--fig-muted); }
@media (prefers-reduced-motion: reduce) {
  #union-agents .cap-cell, #union-agents .proof-cell, #union-agents .cap-cell_name, #union-agents .cap-cell_desc, #union-agents .cap-cell_name::after, #union-agents .cap-cell::after, #union-agents .proof-cell::after, #union-agents .proof-cell_co, #union-agents .proof-cell_result::after { transition: none; }
  #union-agents .cap-cell:hover, #union-agents .proof-cell:hover { transform: none; }
  #union-agents .cap-cell:hover .cap-cell_name::after, #union-agents .proof-cell:hover .proof-cell_co, #union-agents .proof-cell:hover .proof-cell_result::after { transform: none; }
  #union-agents .cap-cell::before, #union-agents .proof-cell::before, #union-agents .cap-cell::after, #union-agents .proof-cell::after { display: none; }
}
@media (max-width: 1080px) {
  #union-agents .cap-grid, #union-agents .proof-grid { --cap-cols: 2; }
}
@media (max-width: 860px) {
  #union-agents .cap-grid, #union-agents .proof-grid { margin-inline: 0; }
  #union-agents .cap-cell, #union-agents .proof-cell { padding-left: 0; padding-right: 0; }
}
@media (max-width: 640px) {
  #union-agents .cap-grid, #union-agents .proof-grid { --cap-cols: 1; gap: 4px; }
  #union-agents .cap-grid > *, #union-agents .proof-grid > * { flex-basis: 100%; max-width: 100%; }
  #union-agents .cap-cell, #union-agents .proof-cell { padding: 16px 22px 18px; }
  #union-agents .cap-cell_name, #union-agents .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-agents .fig-copy .heading-style-h2, #union-agents .fig-copy .heading-style-h3 {
  font-size: clamp(25px, 2.7vw, 40px); line-height: 1.12; letter-spacing: -0.02em;
}
#union-agents .fig-copy .text-size-medium, #union-agents .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-agents .fig-copy .text-style-tagline { margin-bottom: 14px; }
#union-agents .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-agents .fig-sec[id], #union-agents .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-agents .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-agents .fig-cta .button, #union-agents .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-agents .fig-cta .button .button_text, #union-agents .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-agents .fig-cta .button-group, #union-agents .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-agents .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-agents .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-agents .fig-factory.is-compact { padding-top: 28px; }
#union-agents .fig-factory_stage { display: block; min-height: 1px; }
#union-agents .fig-factory_stage svg { display: block; width: 100%; height: auto; }
#union-agents .fig-factory_leader {
  fill: none; stroke: var(--brand-gray-500, var(--color-neutral-700, #4a4e52)); stroke-width: 1;
}
#union-agents .fig-factory_anchor {
  fill: var(--fig-heading); stroke: var(--theme-bg, var(--color-bg, #000));
}
#union-agents .fig-factory_lt { font-family: var(--font-code, ui-monospace, monospace); fill: var(--fig-heading); }
#union-agents .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-agents .fig-factory_caps { display: none; }
#union-agents .fig-factory.is-compact .fig-factory_caps { display: grid; gap: 7px; margin: 14px 2px 2px; }
#union-agents .fig-factory_cap {
  display: flex; align-items: baseline; gap: 8px; font-size: 12px; line-height: 1.4;
  color: var(--fig-muted);
}
#union-agents .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-agents .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-agents .fig-factory_cap i.is-fail { background-color: #e04b4d; }
#union-agents .fig-factory_cap i.is-retry { background-color: #5b90f7; }
#union-agents .fig-factory_cap i.is-ok { background-color: #8bcb6a; }
#union-agents .fig-factory_cap i.is-union-out {
  background-color: transparent;
  box-shadow: inset 0 0 0 1.5px var(--fig-accent);
}
#union-agents .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-agents .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-agents .fig-factory_cap i.is-raw { animation: none; }
}
#union-agents .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-agents .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-agents .fig-factory.is-band { max-width: 860px; margin: 0 auto; }
#union-agents .fig-factory.is-band .fig-factory_caps { justify-content: center; }
/* ═══ agents/style.css ═══ *//* Union /agents 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. *//* =====================================================================
   Component state classes (Designer-buildable)
   ===================================================================== *//* The card grids are content blocks, not chrome: no ring, and a ground 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-agents { --ag-soft: color-mix(in srgb, var(--color-surface) 55%, var(--color-bg)); }
#union-agents .ag-devex, #union-agents .ag-build, #union-agents .ag-fw, #union-agents .ag-prod {
  box-shadow: none;
  background: var(--ag-soft);
  transition: background 0.18s ease;
}
#union-agents .ag-fw:hover { box-shadow: none; background: var(--color-surface); }
/* section furniture */
#union-agents .ag-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-agents .ag-lede { font-size: 17px; line-height: 1.6; color: var(--color-neutral-400); max-width: 760px; margin: 0; text-wrap: pretty; }
/* in-card doc links are a footnote, not a call to action — the section CTAs
   carry the accent */
#union-agents .ag-doclink { align-self: flex-start; font-size: 12.5px; padding-left: 0; padding-right: 0; font-weight: 400; color: var(--color-neutral-500); }
#union-agents .ag-doclink:hover { color: var(--color-text); background: transparent; text-decoration: underline; text-underline-offset: 3px; }
#union-agents .ag-doclink:active { background: transparent; }
/* hero */
#union-agents .ag-hero-h1 { font-size: 58px; margin: 0 0 16px; max-width: 16ch; }
#union-agents .ag-hero-sub { font-size: 19px; line-height: 1.55; color: var(--color-neutral-400); max-width: 54ch; margin: 0 0 24px; text-wrap: pretty; }
#union-agents .ag-hero-btns { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 26px; }
#union-agents .ag-hero-btns .btn { font-size: 16px; padding: 13px 26px; }
/* The Reason → Act → Observe ring in the hero's right column. One 4.8s cycle
   shared by every node and connector, offset per element by the inline --i, so
   the highlight walks the loop. Keyframes are in the embed block below. */
#union-agents .ag-loop { position: relative; display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 26px 26px 22px; border-radius: var(--radius-lg); background: var(--ag-soft); }
#union-agents .ag-loop-node { position: relative; display: flex; align-items: center; gap: 12px; padding: 14px 20px; border-radius: 999px; border: 1px solid var(--color-divider); background: var(--color-surface); }
#union-agents .ag-loop-dot { width: 9px; height: 9px; flex: none; border-radius: 999px; background: var(--color-neutral-700); }
#union-agents .ag-loop-name { font-size: 17px; color: var(--color-neutral-300); }
#union-agents .ag-loop-api { font-size: 11px; color: var(--color-neutral-600); margin-left: auto; white-space: nowrap; }
#union-agents .ag-loop-arrow { align-self: flex-start; margin-left: 46px; padding: 5px 0; font-size: 14px; line-height: 1; color: var(--color-neutral-700); }
#union-agents .ag-loop-return { display: flex; align-items: flex-start; gap: 9px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--color-divider); font-size: 13px; line-height: 1.45; color: var(--color-neutral-500); }
#union-agents .ag-loop-return-glyph { color: var(--color-accent); font-size: 15px; line-height: 1.2; flex: none; }
/* "Run any harness" marquee under the hero. The track holds the list twice, so
   translating it -50% loops seamlessly; keyframes are in the embed block. */
#union-agents .ag-harness { margin-top: 44px; padding-top: 26px; border-top: 1px solid var(--color-divider); }
#union-agents .ag-harness-label { display: block; font-family: var(--font-code); font-size: 10.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-neutral-600); margin-bottom: 14px; }
#union-agents .ag-harness-viewport { overflow: hidden; -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent); mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent); }
#union-agents .ag-harness-track { display: flex; align-items: center; gap: 12px; width: max-content; }
#union-agents .ag-harness-item { display: inline-flex; align-items: center; gap: 9px; flex: none; padding: 10px 17px; border-radius: 999px; border: 1px solid var(--color-divider); background: var(--ag-soft); text-decoration: none; white-space: nowrap; transition: border-color 0.18s ease, background 0.18s ease; }
#union-agents .ag-harness-logo { width: 18px; height: 18px; 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-agents .ag-harness-name { font-size: 14px; color: var(--color-neutral-300); }
#union-agents .ag-harness-item:hover { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 8%, var(--color-surface)); }
#union-agents .ag-harness-item:hover .ag-harness-logo { background: var(--acc-icon); }
#union-agents .ag-harness-item:hover .ag-harness-name { color: var(--color-text); }
/* problem → answer rows */
#union-agents .ag-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-agents .ag-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-agents .ag-fix-a { font-size: 15.5px; line-height: 1.6; color: var(--color-neutral-400); margin: 0; text-wrap: pretty; }
/* "build the loop your way" cards — same shape as the devex cards: the code
   cell is a panel inset in the card, not a full-bleed pane */
#union-agents .ag-build { gap: 9px; padding: 22px 20px; }
#union-agents .ag-build .card-body { flex: none; }
/* pattern panel — a tab row over one code cell. The six patterns differ only
   in control flow, so showing them side by side as cards buried the thing that
   actually varies; one panel lets you flip between them in place. */
#union-agents .ag-tabwrap { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
#union-agents .ag-tablabel { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-neutral-600); white-space: nowrap; }
#union-agents .ag-tabrow { display: flex; flex-wrap: wrap; gap: 8px; }
#union-agents .ag-patpanel { border-radius: var(--radius-lg); background: var(--ag-soft); overflow: hidden; }
#union-agents .ag-patpanel-head { display: flex; gap: 10px; align-items: center; padding: 11px 18px; border-bottom: 1px solid var(--color-divider); }
#union-agents .ag-patpanel-file { font-size: 12px; color: var(--color-neutral-400); }
#union-agents .ag-patpanel-code { padding: 16px 0 18px; overflow: auto; background: var(--color-neutral-900); }
#union-agents .ag-patpanel-note { margin: 0; padding: 14px 18px; border-top: 1px solid var(--color-divider); font-size: 14.5px; line-height: 1.55; color: var(--color-neutral-400); text-wrap: pretty; }
#union-agents .ag-tab-use { color: var(--color-neutral-600); }
#union-agents .ag-tab-use::before { content: " · "; }
/* tool-source table */
#union-agents .ag-trow { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr) minmax(0, 1.3fr); gap: 16px; padding: 12px 0; border-top: 1px solid var(--color-divider); font-size: 14px; line-height: 1.5; }
#union-agents .ag-tcell-1 { color: var(--color-text); }
#union-agents .ag-tcell-2, #union-agents .ag-tcell-3 { color: var(--color-neutral-500); }
/* tabbed code panels (sandboxing, shipping) */
#union-agents .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-agents .ag-tab.on { background: color-mix(in srgb, var(--color-accent) 16%, transparent); border-color: var(--color-accent); color: var(--acc-icon); }
#union-agents .ag-tab:hover { border-color: var(--color-accent); color: var(--acc-icon); }
#union-agents .ag-tab:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* devex cards */
#union-agents .ag-devex { gap: 9px; padding: 22px 20px; }
#union-agents .ag-devex .card-body { flex: none; }
#union-agents .ag-devex-code, #union-agents .ag-build-code {
  border-radius: var(--radius-sm);
  background: var(--color-neutral-900);
  /* a hair of separation, not a frame */
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-divider) 45%, transparent);
  padding: 12px 0 13px; overflow: auto; margin-top: 4px; min-width: 0;
}
/* framework cards */
#union-agents .ag-fw { gap: 6px; padding: 18px 18px 16px; text-decoration: none; }
#union-agents .ag-fw-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* masked rather than an <img>, so the mark takes the theme's text color */
#union-agents .ag-fw-logo { width: 20px; height: 20px; 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-agents .ag-fw:hover .ag-fw-logo { background: var(--color-accent); }
#union-agents .ag-fw-name { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-size: 16.5px; color: var(--color-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#union-agents .ag-fw-desc { font-size: 13.5px; line-height: 1.5; color: var(--color-neutral-500); flex: 1; }
#union-agents .ag-fw-pkg { font-size: 10.5px; color: var(--color-neutral-600); overflow-wrap: anywhere; }
#union-agents .ag-fw:hover .ag-fw-name { color: var(--color-accent); }
/* tutorial links */
#union-agents .ag-tut { display: flex; flex-direction: column; gap: 5px; padding: 16px 0; border-top: 1px solid var(--color-divider); text-decoration: none; }
#union-agents .ag-tut-name { font-size: 15.5px; color: var(--color-text); }
#union-agents .ag-tut-arrow { color: var(--color-accent); opacity: 0; transition: opacity 0.18s ease, transform 0.18s ease; display: inline-block; }
#union-agents .ag-tut-desc { font-size: 13.5px; line-height: 1.5; color: var(--color-neutral-500); }
#union-agents .ag-tut:hover .ag-tut-name { color: var(--color-accent); }
#union-agents .ag-tut:hover .ag-tut-arrow { opacity: 1; transform: translateX(3px); }
/* closing CTA band */
#union-agents .ag-cta { background: linear-gradient(135deg, #18191a, #241d08); color: #e6e6e8;
  border-top: 1px solid color-mix(in srgb, var(--color-accent) 34%, transparent); }
#union-agents .ag-cta h2 { color: #ffffff; }
#union-agents .ag-cta p { color: rgba(230, 230, 232, 0.82); }
/* =====================================================================
   WEBFLOW: paste into an Embed (base rules, pseudo-states, keyframes and
   media queries — CSS the Designer cannot express)
   ===================================================================== */
#union-agents { margin: 0; background: var(--color-bg); color: var(--color-text); font-size: 17px; }
#union-agents { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
#union-agents a { color: var(--color-accent); }
#union-agents a:hover { color: var(--color-accent-300); }
#union-agents pre, #union-agents code, #union-agents .mono { font-family: var(--font-code); }
#union-agents :not(pre) > code { font-size: 0.87em; color: var(--color-accent-300); background: none; border: 0; padding: 0; }
#union-agents [id] { scroll-margin-top: 88px; }
/* scrollbars inside code panels */
#union-agents .r-term, #union-agents .mono { scrollbar-width: thin; scrollbar-color: var(--color-neutral-700) transparent; }
#union-agents .r-term::-webkit-scrollbar, #union-agents .mono::-webkit-scrollbar { width: 8px; height: 8px; }
#union-agents .r-term::-webkit-scrollbar-track, #union-agents .mono::-webkit-scrollbar-track { background: transparent; }
#union-agents .r-term::-webkit-scrollbar-thumb, #union-agents .mono::-webkit-scrollbar-thumb { background: var(--color-neutral-700); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; }
#union-agents .r-term::-webkit-scrollbar-corner, #union-agents .mono::-webkit-scrollbar-corner { background: transparent; }
/* sticky nav *//* the filled-yellow CTA — same class the home page uses */
#union-agents .cta-accent { background: var(--color-accent); border: 1px solid var(--color-accent); color: #000; }
#union-agents .cta-accent:hover { background: var(--color-accent-400); border-color: var(--color-accent-400); color: #000; }
#union-agents .cta-accent:active { background: var(--color-accent-600); border-color: var(--color-accent-600); color: #000; }
#union-agents .navbar { transition: background 0.25s ease, box-shadow 0.25s ease, backdrop-filter 0.25s ease; }
#union-agents .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); }
#union-agents .nav a { color: var(--color-neutral-300); text-decoration: none; font-size: 14px; }
#union-agents .nav a:hover { color: var(--color-text); }
#union-agents .nav a.btn { color: var(--color-text); }


@keyframes coderise { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
#union-agents .code-rise { animation: coderise 380ms cubic-bezier(0.22, 0.8, 0.2, 1); }


/* the harness marquee — the track is the list twice, so -50% is one full lap */
@keyframes agmarquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
#union-agents .ag-harness-track { animation: agmarquee 46s linear infinite; }
#union-agents .ag-harness:hover .ag-harness-track { animation-play-state: paused; }


/* the hero loop cycle — 4.8s, one node lit at a time, offset by --i */
@keyframes agloopnode {
  0%, 27% { border-color: var(--color-accent); background: color-mix(in srgb, var(--color-accent) 12%, var(--color-surface));
            box-shadow: 0 0 26px 1px color-mix(in srgb, var(--color-accent) 26%, transparent); }
  38%, 100% { border-color: var(--color-divider); background: var(--color-surface); box-shadow: none; }
}

@keyframes agloopdot {
  0%, 27% { background: var(--color-accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent) 22%, transparent); }
  38%, 100% { background: var(--color-neutral-700); box-shadow: none; }
}

@keyframes agloopname {
  0%, 27% { color: var(--color-text); }
  38%, 100% { color: var(--color-neutral-300); }
}

@keyframes agloopapi {
  0%, 27% { color: var(--acc-icon); }
  38%, 100% { color: var(--color-neutral-600); }
}

@keyframes aglooparrow {
  0%, 18% { color: var(--color-accent); transform: translateY(2px); }
  30%, 100% { color: var(--color-neutral-700); transform: none; }
}

@keyframes agloopreturn {
  0%, 12% { color: var(--color-accent); transform: rotate(-120deg); }
  40%, 100% { color: var(--color-accent); transform: none; }
}
#union-agents .ag-loop-node { animation: agloopnode 4.8s calc(var(--i) * 1.6s) infinite; }
#union-agents .ag-loop-dot { animation: agloopdot 4.8s calc(var(--i) * 1.6s) infinite; }
#union-agents .ag-loop-name { animation: agloopname 4.8s calc(var(--i) * 1.6s) infinite; }
#union-agents .ag-loop-api { animation: agloopapi 4.8s calc(var(--i) * 1.6s) infinite; }
/* each arrow fires just after the node above it lights */
#union-agents .ag-loop-arrow { animation: aglooparrow 4.8s calc(var(--i) * 1.6s + 0.75s) infinite; }
#union-agents .ag-loop-return-glyph { display: inline-block; animation: agloopreturn 4.8s 4s infinite; }
@media (prefers-reduced-motion: reduce) {
  #union-agents .code-rise { animation: none; }
  #union-agents .ag-loop-node, #union-agents .ag-loop-dot, #union-agents .ag-loop-name, #union-agents .ag-loop-api, #union-agents .ag-loop-arrow, #union-agents .ag-loop-return-glyph, #union-agents .ag-harness-track { animation: none; }
  #union-agents .ag-harness-viewport { overflow-x: auto; }
  #union-agents { scroll-behavior: auto; }
}
/* 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/ and ../inference/ load, so all three highlight from
   one source. */
#union-agents { --ok: #8fcb7a; --err: #e8676a; --run: #74b6f2; --acc-icon: #f9d67f; }
/* 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.
   Every collapsed template below uses minmax(0, 1fr) for the same reason. */
#union-agents .ag-grid-2 > *, #union-agents .ag-grid-3 > *, #union-agents .ag-grid-4 > * { min-width: 0; }
#union-agents .ag-build, #union-agents .ag-devex, #union-agents .ag-build-code, #union-agents .ag-devex-code, #union-agents [data-gen="rightsize"] { min-width: 0; }
@media (max-width: 1080px) {
  #union-agents .ag-grid-2 { grid-template-columns: minmax(0, 1fr) !important; }
  #union-agents .ag-hero { gap: 34px !important; }
  #union-agents .ag-loop { max-width: 460px; }
  #union-agents .ag-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  #union-agents .ag-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  #union-agents .ag-hero-h1 { font-size: 46px; }
  #union-agents .ag-fix { grid-template-columns: 1fr; gap: 8px; }
}
@media (max-width: 860px) {
  #union-agents [data-code-line] { font-size: 11.5px !important; line-height: 1.7 !important; padding-left: 12px !important; padding-right: 12px !important; }
  #union-agents [data-screen-label] { padding-left: 24px !important; padding-right: 24px !important; }
  #union-agents .ag-hero-h1 { font-size: 38px; letter-spacing: -0.015em; }
  #union-agents .ag-hero-sub { font-size: 17px; }
  #union-agents h2 { font-size: 27px !important; }
  #union-agents h3 { font-size: 21px !important; }
  #union-agents .ag-trow { grid-template-columns: 1fr; gap: 4px; }
  #union-agents .ag-tcell-1 { font-weight: 500; }
  #union-agents .ag-trow-head { display: none; }
  #union-agents #sandboxing .ag-tcell-2::before { content: "Workflow · "; color: var(--color-neutral-600); }
  #union-agents #sandboxing .ag-tcell-3::before { content: "Code · "; color: var(--color-neutral-600); }
  #union-agents .nav { flex-wrap: wrap; gap: 14px !important; align-items: center; }
  #union-agents .r-burger { display: inline-flex !important; }
  #union-agents .r-navitems { display: none !important; }
  #union-agents .r-navitems.r-open { display: flex !important; flex-direction: column; align-items: stretch; gap: 12px; flex: 1 1 100%; padding-top: 6px; }
  #union-agents .r-navitems.r-open .btn { justify-content: center; margin-left: 0 !important; }
}
@media (max-width: 640px) {
  #union-agents [data-screen-label] { padding-left: 18px !important; padding-right: 18px !important; }
  #union-agents .ag-grid-3, #union-agents .ag-grid-4 { grid-template-columns: minmax(0, 1fr) !important; }
  #union-agents .ag-hero-h1 { font-size: 32px; }
}
/* ── build section: four ways to build the loop, as a scroll stack ────
   The four approaches used to sit in a 2×2 grid of cards, which made the page
   scroll past three snippets nobody asked for; then as tabs, which hid three
   of them behind a click. As a stack each card pins under the nav a little
   lower than the one before it, so scrolling deals them over each other and
   every approach still gets read on the way past.

   The stack — not the item — is the sticky containing block, which is what
   keeps the earlier cards pinned instead of scrolling away one by one. */
#union-agents .ag-build-stack { display: flex; flex-direction: column; gap: 28px; }
#union-agents .ag-stack_item { position: sticky; top: calc(104px + var(--i) * 18px); }
#union-agents .ag-stack_item > .ag-build {
  /* opaque, or the card underneath shows straight through the overlap */
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  transform-origin: 50% 0;
  /* --recede is written by initBuildStack(): how far the next card has
     covered this one. No JS → it stays 0 and the card just sits there. */
  transform: scale(calc(1 - var(--recede, 0) * 0.05));
  filter: brightness(calc(1 - var(--recede, 0) * 0.3));
  will-change: transform;
}
#union-agents .ag-build_head { display: flex; align-items: center; gap: 12px; }
#union-agents .ag-build_step {
  font-size: 10.5px; letter-spacing: .14em; color: var(--color-neutral-600);
  padding: 3px 8px; border-radius: 999px; border: 1px solid var(--color-divider);
}
#union-agents .ag-build .card-title { font-size: 21px; }
@media (max-width: 991px) {
  #union-agents .ag-build-stack { gap: 18px; }
  #union-agents .ag-stack_item { top: calc(76px + var(--i) * 10px); }
  #union-agents .ag-stack_item > .ag-build { transform: scale(calc(1 - var(--recede, 0) * 0.03)); }
}
@media (max-width: 767px) {
  #union-agents .ag-stack_item { top: calc(68px + var(--i) * 8px); }
  #union-agents .ag-build-code { max-height: 42vh; overflow: auto; }
}
@media (prefers-reduced-motion: reduce) {
  #union-agents .ag-stack_item > .ag-build { transform: none; filter: none; }
}
/* ── 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. *//* the stacked build panes take their width from the widest code line, which
   pushed the page past a 390px viewport — let the code scroll inside instead */
#union-agents .ag-build-stack, #union-agents .ag-stack_item { min-width: 0; }
#union-agents .ag-build-code { overflow-x: auto; }
/* the pattern/devex code blocks that aren't .ag-*-code have no scroll container
   of their own, so their longest line set the page width on a phone */
#union-agents .code-rise { overflow-x: auto; min-width: 0; }


/* ═══ 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-agents {
  --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-agents {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
#union-agents code, #union-agents pre, #union-agents kbd, #union-agents samp { font-family: var(--font-code); }
#union-agents { margin: 0; font-size: 18px; line-height: 1.5; font-weight: 500; }
#union-agents p { margin: 0 0 var(--space-3); }
#union-agents a { color: var(--color-accent); text-underline-offset: 3px; }
#union-agents img { display: block; max-width: 100%; }
#union-agents figure { margin: 0; }
#union-agents 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-agents {
  /* 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-agents 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-agents {
  --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 */
}
/* ═══ agents/style.css ═══ *//* Union /agents 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. *//* =====================================================================
   Component state classes (Designer-buildable)
   ===================================================================== *//* The card grids are content blocks, not chrome: no ring, and a ground 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-agents { --ag-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-agents { margin: 0; background: var(--color-bg); color: var(--color-text); font-size: 17px; }
#union-agents { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
#union-agents a { color: var(--color-accent); }
#union-agents [id] { scroll-margin-top: 88px; }
@media (prefers-reduced-motion: reduce) {
  #union-agents { scroll-behavior: auto; }
}
/* 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/ and ../inference/ load, so all three highlight from
   one source. */
#union-agents { --ok: #8fcb7a; --err: #e8676a; --run: #74b6f2; --acc-icon: #f9d67f; }
/* ══════════════════════════════════════════════════════════════════════════
   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-agents figure, #union-agents blockquote, #union-agents figcaption {
  margin: 0; padding: 0; border: 0; text-align: inherit;
}
#union-agents ul, #union-agents ol { margin: 0; padding: 0; }
#union-agents 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-agents { padding-top: 8rem; }
#union-agents [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-agents { padding-top: 138px; }
  @media (max-width: 991px) { #union-agents { padding-top: 96px; } }

  /* ── host navbar ────────────────────────────────────────────
     Unscoped on purpose: the bar renders outside the wrapper above. */
  .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 rather than leaving a
     768–860px band at the old size. */
  @media (max-width: 860px) {
    #union-agents [data-code-line],
    #union-agents .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. This page has
     no SVG diagrams — its widgets are all HTML. */
  @media (max-width: 767px) {

    /* The tutorial arrow is a hover affordance with no touch equivalent;
       leaving it faded reads as a broken glyph, so pin it on. */
    #union-agents .ag-tut-arrow { opacity: 1; transform: none; transition: none; }

    #union-agents .ag-build_step,
    #union-agents .ag-harness-label,
    #union-agents .ag-kicker,
    #union-agents .ag-tablabel,
    #union-agents .btn,
    #union-agents .card-kicker { font-size: 13px; }

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

    /* A little more room now that the type is bigger. */
    #union-agents .ag-build { padding: 20px 18px; }
    #union-agents .ag-tablabel { padding: 8px 12px; }
  }
