@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-system.css — union.ai design system for Webflow-handoff prototypes.
   Tokens extracted from the live Webflow CSS bundle (Sept 2026).
   Every class below already exists in the union.ai Webflow project —
   prototypes reuse these names so the dev maps elements 1:1. */

@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-system.css ═══ */
/* union-system.css — union.ai design system for Webflow-handoff prototypes.
   Tokens extracted from the live Webflow CSS bundle (Sept 2026).
   Every class below already exists in the union.ai Webflow project —
   prototypes reuse these names so the dev maps elements 1:1. */

@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-system.css ═══ */
/* union-system.css — union.ai design system for Webflow-handoff prototypes.
   Tokens extracted from the live Webflow CSS bundle (Sept 2026).
   Every class below already exists in the union.ai Webflow project —
   prototypes reuse these names so the dev maps elements 1:1. */

@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-factory {
  /* brand */
  --brand-dark: #18191a;
  --brand-gray-100: #f2f3f3;
  --brand-gray-300: #cccfd1;
  --brand-gray-350: #81858b;
  --brand-gray-400: #72757a;
  --brand-yellow-500: #fcb51f;
  --brand-purple: #6f2aef;
  --brand-red: #cd3234;
  --brand-green: #78b856;
  --brand-orange: #e8883a;
  --brand-blue: #3378f5;
  --brand-pink: #ad3abb;
  --brand-brown: #a65a17;
  --brand-blue-dark: #1648b8;
  --brand-green-dark: #008013;
  --brand-red-dark: #980202;
  --white-12: #ffffff1f;
  /* theme roles */
  --theme-background: #000000;
  --theme-heading: #ffffff;
  --theme-body: var(--brand-gray-300);
  --theme-accent: var(--brand-yellow-500);
  --theme-border: var(--white-12);
  --theme-card: var(--brand-dark);
  /* type */
  --font-body: "Yellix", Arial, sans-serif;
  --font-heading: "Yellix", Arial, sans-serif;
  --font-code: "IBM Plex Mono", Tahoma, sans-serif;
  --heading-weight: 600;
  --heading-line-height: 1.05;
  /* ui — note: tighter radii than flyte.org */
  --radius-small: .5rem;
  --radius-medium: 1rem;
  --radius-large: 1.5rem;
  --border-width: 1px;
}
#union-factory *, #union-factory *::before, #union-factory *::after { box-sizing: border-box; }
#union-factory {
  margin: 0;
  background-color: var(--theme-background);
  color: var(--theme-body);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
#union-factory h1, #union-factory h2, #union-factory h3, #union-factory h4, #union-factory h5, #union-factory h6 {
  margin: 0;
  color: var(--theme-heading);
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  line-height: var(--heading-line-height);
}
#union-factory p { margin: 0; }
#union-factory a { color: inherit; }
#union-factory img { max-width: 100%; display: block; }
#union-factory code, #union-factory pre { font-family: var(--font-code); }
/* ---- Client-First structure ---- */
#union-factory .padding-global { padding-left: 5%; padding-right: 5%; }
#union-factory .container-large { width: 100%; max-width: 80rem; margin-left: auto; margin-right: auto; }
#union-factory .container-medium { width: 100%; max-width: 64rem; margin-left: auto; margin-right: auto; }
#union-factory .container-small { width: 100%; max-width: 48rem; margin-left: auto; margin-right: auto; }
#union-factory .padding-section-large { padding-top: 7rem; padding-bottom: 7rem; }
#union-factory .padding-section-medium { padding-top: 5rem; padding-bottom: 5rem; }
#union-factory .padding-section-small { padding-top: 3rem; padding-bottom: 3rem; }
/* Client-First directional modifiers — pair with a padding-section-* class to keep
   the padding on one side only (e.g. `padding-section-large padding-top`). */
#union-factory .padding-top { padding-right: 0 !important; padding-bottom: 0 !important; padding-left: 0 !important; }
#union-factory .padding-bottom { padding-top: 0 !important; padding-right: 0 !important; padding-left: 0 !important; }
/* ---- headings ---- */
#union-factory .heading-style-h1 { font-size: 3.5rem; line-height: 1.2; font-weight: 700; }
#union-factory .heading-style-h2 { font-size: 3rem; line-height: var(--heading-line-height); font-weight: 700; }
#union-factory .heading-style-h3 { font-size: 2.5rem; line-height: 1.1; font-weight: var(--heading-weight); }
#union-factory .heading-style-h4 { font-size: 2rem; line-height: 1.2; font-weight: var(--heading-weight); }
#union-factory .heading-style-h5 { font-size: 1.5rem; line-height: 1.3; font-weight: var(--heading-weight); }
#union-factory .heading-style-h6 { font-size: 1.25rem; line-height: 1.4; font-weight: var(--heading-weight); }
/* ---- text utilities ---- */
#union-factory .text-size-large { font-size: 1.25rem; }
#union-factory .text-size-medium { font-size: 1.125rem; }
#union-factory .text-size-regular { font-size: 1rem; }
#union-factory .text-size-small { font-size: .875rem; }
#union-factory .text-weight-normal { font-weight: 400; }
#union-factory .text-weight-medium { font-weight: 500; }
#union-factory .text-weight-semibold { font-weight: 600; }
#union-factory .text-align-center { text-align: center; }
#union-factory .max-width-small { max-width: 30rem; }
#union-factory .max-width-medium { max-width: 42rem; }
#union-factory .max-width-large { max-width: 56rem; }
#union-factory .align-center { margin-left: auto; margin-right: auto; }
#union-factory .hide { display: none; }
/* tagline = bordered pill chip (unlike flyte.org's bare text tagline) */
#union-factory .text-style-tagline {
  display: inline-block;
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-large);
  background-color: var(--theme-border);
  padding: .5rem 1rem;
  margin-bottom: 1rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--theme-heading);
  text-decoration: none;
}
/* ---- spacers (empty divs, height only) ---- */
#union-factory .spacer-tiny { height: .25rem; }
#union-factory .spacer-xxsmall { height: .5rem; }
#union-factory .spacer-xsmall { height: .75rem; }
#union-factory .spacer-small { height: 1rem; }
#union-factory .spacer-medium { height: 1.5rem; }
#union-factory .spacer-large { height: 2.5rem; }
#union-factory .spacer-xlarge { height: 3.5rem; }
#union-factory .spacer-xxlarge { height: 5rem; }
/* ---- buttons ---- */
#union-factory .button {
  display: flex;
  justify-content: center;
  align-items: center;
  column-gap: .375rem;
  row-gap: .375rem;
  border: 1px solid var(--theme-accent);
  border-radius: var(--radius-large);
  background-color: var(--theme-accent);
  color: #000000;
  text-align: center;
  padding: .5rem 1.25rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
#union-factory .button.is-secondary {
  border-color: var(--theme-border);
  background-color: transparent;
  color: var(--theme-accent);
}
#union-factory .button-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 1rem;
  row-gap: 1rem;
}
/* ---- dark card — the site's signature surface ---- */
#union-factory .card {
  background-color: var(--theme-card);
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-medium);
}
@media (max-width: 991px) {
  #union-factory .heading-style-h1 { font-size: 3.25rem; }
  #union-factory .heading-style-h2 { font-size: 2.75rem; }
  #union-factory .heading-style-h3 { font-size: 2.25rem; }
  #union-factory .padding-section-large { padding-top: 6rem; padding-bottom: 6rem; }
}
@media (max-width: 767px) {
  #union-factory .heading-style-h1 { font-size: 2.5rem; }
  #union-factory .heading-style-h2 { font-size: 2.25rem; }
  #union-factory .heading-style-h3 { font-size: 2rem; }
  #union-factory .heading-style-h4 { font-size: 1.75rem; }
  #union-factory .padding-section-large { padding-top: 4rem; padding-bottom: 4rem; }
  #union-factory .padding-section-medium { padding-top: 3rem; padding-bottom: 3rem; }
}
/* ── prototype deviation: body-text legibility ──
   The values above are extracted from the live Webflow bundle. These four
   utilities carry almost all the non-heading prose on the three platform
   pages, and at the extracted sizes they read small on the dark ground, so
   each is bumped 1px. Headings are untouched. If the Webflow project adopts
   this, fold the values in above and delete this block. */
#union-factory .text-size-large { font-size: 1.3125rem; }
/* was 1.25rem  / 20px → 21px */
#union-factory .text-size-medium { font-size: 1.1875rem; }
/* was 1.125rem / 18px → 19px */
#union-factory .text-size-regular { font-size: 1.0625rem; }
/* was 1rem     / 16px → 17px */
#union-factory .text-size-small { font-size: .9375rem; }
/* was .875rem  / 14px → 15px *//* ── prototype deviation: scrollbars ──
   The default light scrollbars sit badly on the dark code panels and console
   recreations — they are the first thing you notice in a snippet that scrolls
   sideways. Thin, low-contrast, brighter on hover. Firefox takes the standard
   properties; WebKit the pseudo-elements. Same treatment as ../home/. */
#union-factory * { scrollbar-width: thin; scrollbar-color: rgba(236,234,228,.18) transparent; }
#union-factory ::-webkit-scrollbar { width: 10px; height: 10px; }
#union-factory ::-webkit-scrollbar-track { background: transparent; }
#union-factory ::-webkit-scrollbar-thumb {
  background: rgba(236,234,228,.16);
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: content-box;
}
#union-factory ::-webkit-scrollbar-thumb:hover { background: rgba(236,234,228,.30); background-clip: content-box; }
#union-factory ::-webkit-scrollbar-corner { background: transparent; }
/* ── prototype deviation: in-page anchor behaviour ──
   The hero's secondary CTA and the proof rows link to sections on the same
   page. Without these two rules the browser jumps instantly and lands with
   the heading underneath the sticky navbar. Smooth scroll is disabled for
   visitors who asked for reduced motion. */
#union-factory { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  #union-factory { scroll-behavior: auto; }
}
#union-factory [id] { scroll-margin-top: 6rem; }
/* some anchors target widgets, not sections *//* ═══ _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-factory {
  /* 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-factory .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-factory pre, #union-factory pre code, #union-factory .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-factory pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
#union-factory pre ::selection, #union-factory pre::selection { background: var(--code-selection); }
#union-factory pre::-webkit-scrollbar-thumb { background: var(--code-scrollbar); border-radius: 4px; }
/* inline `code` inside body copy */
#union-factory :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-factory .tok-kw, #union-factory .sov-tok-kw, #union-factory .code-kw { color: var(--code-keyword); }
#union-factory .tok-str, #union-factory .sov-tok-str, #union-factory .code-str { color: var(--code-string); }
#union-factory .tok-title, #union-factory .sov-tok-title, #union-factory .code-title { color: var(--code-function); }
#union-factory .tok-param, #union-factory .code-param { color: var(--code-param); }
#union-factory .tok-meta, #union-factory .sov-tok-meta, #union-factory .code-meta { color: var(--code-decorator); }
#union-factory .tok-comment, #union-factory .code-comment { color: var(--code-comment); font-style: italic; }
#union-factory .tok-num, #union-factory .sov-tok-num, #union-factory .code-num { color: var(--code-number); }
#union-factory .tok-class, #union-factory .sov-tok-class, #union-factory .code-class { color: var(--code-class); }
#union-factory .code-punct { color: var(--code-punct); }
#union-factory .code-plain { color: var(--code-fg); }
/* the light theme is opt-in: add .u-theme-light to a code block's container *//* ═══ _shared/union-flyte-band.css ═══ *//* ══════════════════════════════════════════════════════════════════════════
   union-flyte-band.css — the "Open source at the core" proof band
   Shared by sovereign-ai/, model-factory/ and advanced-scheduling/.

   Ported from union/home/, which authors it against the Nocturne tokens in
   home/union.css. Re-expressed here in union-system's --theme-* names so the
   platform pages need no token bridge for it. The markup is identical on all
   three pages — one HTML Embed, or a Webflow symbol, at port time.
   ══════════════════════════════════════════════════════════════════════════ */
#union-factory .flyte-band {
  display: grid; grid-template-columns: 1fr 1.05fr;
  column-gap: clamp(2rem, 5vw, 4.5rem); row-gap: 2rem; align-items: center;
}
#union-factory .flyte-band_text { min-width: 0; }
#union-factory .flyte-band_lede { max-width: 35rem; }
#union-factory .flyte-band_stats { display: grid; grid-template-columns: repeat(3, 1fr); align-items: center; }
#union-factory .flyte-stat {
  padding: .5rem clamp(.875rem, 2vw, 1.625rem);
  border-left: 1px solid var(--theme-border);
  display: flex; flex-direction: column; gap: .375rem;
}
#union-factory .flyte-stat:first-child { border-left: 0; padding-left: 0; }
#union-factory .flyte-stat_n { font-size: clamp(1.875rem, 4.6vw, 2.875rem); line-height: 1; letter-spacing: -.02em; color: var(--theme-heading); }
#union-factory .flyte-stat_k { font-size: .9375rem; color: var(--theme-body); text-wrap: pretty; }
/* 1776×244 white-on-transparent lockup, so it needs no colour treatment on
   the dark ground; capped by width and left-aligned in its column. */
#union-factory .flyte-stat_lf { display: block; width: 100%; max-width: 11.875rem; height: auto; }
@media (max-width: 991px) {
  #union-factory .flyte-band { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  #union-factory .flyte-band_stats { grid-template-columns: 1fr; row-gap: 1.25rem; }
  #union-factory .flyte-stat { border-left: 0; padding-left: 0; border-top: 1px solid var(--theme-border); padding-top: 1.125rem; }
  #union-factory .flyte-stat:first-child { border-top: 0; padding-top: 0; }
}
/* ═══ _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-factory {
  --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-factory .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-factory .fig-sec { padding-top: clamp(56px, 9vw, 130px); padding-bottom: clamp(56px, 9vw, 130px); }
#union-factory .fig-sec.is-alt { background: var(--fig-ground); }
#union-factory .fig-sec.is-tight { padding-top: clamp(40px, 6vw, 84px); padding-bottom: clamp(40px, 6vw, 84px); }
/* ── centred intro pair ────────────────────────────────────────────── */
#union-factory .fig-intro { text-align: center; }
#union-factory .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-factory .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-factory .fig-intro_body { margin-top: clamp(40px, 5.5vw, 72px); text-align: left; }
/* ── content row: copy one side, visual the other ──────────────────── */
#union-factory .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-factory .fig-row.is-flip { grid-template-columns: minmax(0, 804fr) minmax(0, 420fr); }
#union-factory .fig-row.is-flip .fig-copy { order: 2; }
#union-factory .fig-row.is-flip .fig-visual { order: 1; }
/* for rows whose visual is denser than the comp's 470px placeholder */
#union-factory .fig-row.is-roomy { grid-template-columns: minmax(0, 360fr) minmax(0, 864fr); }
#union-factory .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-factory .fig-row.is-even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
#union-factory .fig-copy { min-width: 0; }
#union-factory .fig-visual { min-width: 0; }
/* ── row furniture ─────────────────────────────────────────────────── */
#union-factory .fig-eyebrow { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
#union-factory .fig-eyebrow_n { font-size: 13px; letter-spacing: 0.06em; color: var(--fig-faint); }
#union-factory .fig-eyebrow_rule { display: block; width: 24px; height: 1px; background: var(--fig-border); }
#union-factory .fig-label {
  font-size: 15px; font-weight: 600; letter-spacing: 0.085em; text-transform: uppercase;
  color: var(--fig-accent); margin-bottom: 18px;
}
#union-factory .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-factory .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-factory .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-factory .fig-lead:last-child { margin-bottom: 0; }
#union-factory .fig-points { list-style: none; margin: 0 0 30px; padding: 0; display: grid; gap: 12px; }
#union-factory .fig-points li {
  position: relative; padding-left: 18px; font-size: 16px; line-height: 1.6;
  color: var(--fig-body); text-wrap: pretty;
}
#union-factory .fig-points li::before {
  content: ""; position: absolute; left: 0; top: 0.58em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--fig-accent);
}
#union-factory .fig-points li b, #union-factory .fig-points li strong { color: var(--fig-heading); font-weight: 600; }
#union-factory .fig-link {
  display: inline-block; font-size: 15px; font-weight: 500;
  color: var(--fig-accent); text-decoration: none;
}
#union-factory .fig-link:hover { opacity: 0.8; }
/* caption under a visual — the comp puts a title + note inside the placeholder */
#union-factory .fig-cap { margin-top: 18px; display: flex; flex-direction: column; gap: 5px; }
#union-factory .fig-cap_t { font-size: 15.5px; font-weight: 600; color: var(--fig-heading); }
#union-factory .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-factory .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-factory .fig-cta.has-strip { padding-bottom: clamp(40px, 5vw, 64px); }
#union-factory .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-factory .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-factory .fig-cta_btns { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
#union-factory .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-factory .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-factory .fig-cta a:not(.fig-cta_btn):not(.button):not(.btn), #union-factory .fig-cta a:not(.fig-cta_btn):not(.button):not(.btn):hover { color: var(--fig-ink); }
#union-factory .fig-cta a.fig-cta_btn { color: var(--fig-accent); }
#union-factory .fig-cta a.fig-cta_btn.is-ghost { color: var(--fig-ink); }
#union-factory .fig-cta a.fig-cta_btn:hover { background: #1c1c1e; border-color: #1c1c1e; color: var(--fig-accent); }
#union-factory .fig-cta a.fig-cta_btn.is-ghost:hover { background: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-factory .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-factory .fig-strip_text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
#union-factory .fig-strip_h { font-size: clamp(17px, 1.9vw, 22px); font-weight: 600; letter-spacing: -0.015em; color: var(--fig-ink); }
#union-factory .fig-strip_p { font-size: 15px; color: rgba(11, 11, 12, 0.7); text-wrap: pretty; }
@media (max-width: 1080px) {
  #union-factory .fig-row, #union-factory .fig-row.is-flip, #union-factory .fig-row.is-roomy, #union-factory .fig-row.is-roomy.is-flip, #union-factory .fig-row.is-even {
    grid-template-columns: minmax(0, 1fr); gap: clamp(28px, 5vw, 44px);
  }
  #union-factory .fig-row.is-flip .fig-copy, #union-factory .fig-row.is-flip .fig-visual { order: 0; }
  #union-factory .fig-points { margin-bottom: 24px; }
}
@media (max-width: 640px) {
  #union-factory .fig-eyebrow { margin-bottom: 10px; }
  #union-factory .fig-label { margin-bottom: 12px; font-size: 13.5px; }
  #union-factory .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-factory .fig-sec .padding-section-large, #union-factory .fig-sec .padding-section-medium { padding-top: 0; padding-bottom: 0; }
/* the tagline chip becomes the comp's yellow uppercase label */
#union-factory .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-factory .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-factory .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-factory .fig-sec .text-align-center .text-size-medium, #union-factory .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-factory .fig-sec .spacer-xxlarge { height: clamp(40px, 5.5vw, 72px); }
#union-factory .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-factory .fig-sec > h2, #union-factory .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-factory .fig-cta .padding-section-large, #union-factory .fig-cta .padding-section-medium { padding-top: 0; padding-bottom: 0; }
#union-factory .fig-cta [class*="cta_band"] { border: 0; background: none; padding: 0; text-align: center; }
#union-factory .fig-cta .heading-style-h2, #union-factory .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-factory .fig-cta .text-size-medium, #union-factory .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-factory .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-factory .fig-cta .button-group { justify-content: center; }
#union-factory .fig-cta .button {
  border-color: var(--fig-ink); background-color: var(--fig-ink);
  color: var(--fig-accent); border-radius: 999px;
}
#union-factory .fig-cta .button:hover { border-color: #1c1c1e; background-color: #1c1c1e; color: var(--fig-accent); }
#union-factory .fig-cta .button.is-secondary {
  border-color: rgba(11, 11, 12, 0.35); background-color: transparent; color: var(--fig-ink);
}
#union-factory .fig-cta .button.is-secondary:hover { background-color: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-factory .fig-cta .cta-note { color: rgba(11, 11, 12, 0.6); }
#union-factory .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-factory .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-factory .fig-oss .text-style-tagline { color: #8b5cf6; }
#union-factory .fig-oss .flyte-stat { border-left-color: rgba(139, 92, 246, 0.38); }
#union-factory .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-factory .fig-sec .ag-kicker, #union-factory .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-factory .fig-sec .ag-lede, #union-factory .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-factory .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-factory .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-factory .fig-cta p, #union-factory .fig-cta .text-size-tiny, #union-factory .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-factory .fig-cta .button .button_text, #union-factory .fig-cta .button > * { color: inherit; }
#union-factory .fig-cta .button-group { justify-content: center; }
#union-factory .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-factory .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-factory .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-factory .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-factory .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-factory .fig-cta.ag-cta, #union-factory .fig-cta.in-cta { background: var(--fig-accent); color: var(--fig-ink); }
#union-factory .fig-cta.ag-cta h2, #union-factory .fig-cta.in-cta h2 { color: var(--fig-ink); }
#union-factory .fig-cta.ag-cta p, #union-factory .fig-cta.in-cta p { color: rgba(11, 11, 12, 0.78); }
#union-factory .fig-cta .btn.cta-accent {
  background: var(--fig-ink); border-color: var(--fig-ink); color: var(--fig-accent);
}
#union-factory .fig-cta .btn.cta-accent:hover { background: #1c1c1e; border-color: #1c1c1e; color: var(--fig-accent); }
#union-factory .fig-cta .btn.btn-secondary {
  background: transparent; border-color: rgba(11, 11, 12, 0.35); color: var(--fig-ink);
}
#union-factory .fig-cta .btn.btn-secondary:hover { background: rgba(11, 11, 12, 0.08); border-color: var(--fig-ink); }
#union-factory .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-factory .fig-cta.ag-cta h2, #union-factory .fig-cta.in-cta h2, #union-factory .fig-cta.ag-cta p, #union-factory .fig-cta.in-cta p {
  margin-left: auto !important; margin-right: auto !important;
}
#union-factory .fig-cta.ag-cta > div, #union-factory .fig-cta.in-cta > div { padding-left: 0; padding-right: 0; }
#union-factory .fig-cta.ag-cta > div > div, #union-factory .fig-cta.in-cta > div > div { justify-content: center; }
#union-factory .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-factory .fig-cta .mono { color: rgba(11, 11, 12, 0.6) !important; }
#union-factory .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-factory .cap-grid, #union-factory .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-factory .cap-grid > *, #union-factory .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-factory .cap-grid.is-4up, #union-factory .proof-grid.is-4up { --cap-cols: 4; }
#union-factory .cap-grid.is-5up, #union-factory .proof-grid.is-5up { --cap-cols: 5; }
#union-factory .cap-cell, #union-factory .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-factory .cap-cell > *, #union-factory .proof-cell > * { position: relative; z-index: 1; }
#union-factory .cap-cell:hover, #union-factory .proof-cell:hover {
  background: color-mix(in srgb, var(--fig-heading) 5%, transparent);
  transform: translateY(-3px);
}
#union-factory .cap-cell:focus-visible, #union-factory .proof-cell:focus-visible { outline: 2px solid var(--fig-accent); outline-offset: -2px; }
#union-factory .cap-cell::before, #union-factory .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-factory .cap-cell::after, #union-factory .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-factory .cap-cell:hover::before, #union-factory .proof-cell:hover::before { opacity: 1; }
#union-factory .cap-cell:hover::after, #union-factory .proof-cell:hover::after { transform: scaleX(1); }
/* contents card — the glyph is a ↓ because the card jumps down the page */
#union-factory .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-factory .cap-cell_desc { font-size: 16px; line-height: 1.5; color: var(--fig-muted); text-wrap: pretty; transition: color .18s ease; }
#union-factory .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-factory .cap-cell:hover .cap-cell_name { color: var(--fig-accent); }
#union-factory .cap-cell:hover .cap-cell_desc { color: var(--fig-body); }
#union-factory .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-factory .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-factory .proof-cell:hover .proof-cell_co { transform: translateX(2px); }
#union-factory .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-factory .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-factory .proof-cell:hover .proof-cell_result::after { color: var(--fig-accent); transform: translate(3px, -3px); }
#union-factory .proof-cell_cap { margin-top: auto; padding-top: 14px; font-size: 14px; color: var(--fig-faint); transition: color .18s ease; }
#union-factory .proof-cell:hover .proof-cell_cap { color: var(--fig-muted); }
@media (prefers-reduced-motion: reduce) {
  #union-factory .cap-cell, #union-factory .proof-cell, #union-factory .cap-cell_name, #union-factory .cap-cell_desc, #union-factory .cap-cell_name::after, #union-factory .cap-cell::after, #union-factory .proof-cell::after, #union-factory .proof-cell_co, #union-factory .proof-cell_result::after { transition: none; }
  #union-factory .cap-cell:hover, #union-factory .proof-cell:hover { transform: none; }
  #union-factory .cap-cell:hover .cap-cell_name::after, #union-factory .proof-cell:hover .proof-cell_co, #union-factory .proof-cell:hover .proof-cell_result::after { transform: none; }
  #union-factory .cap-cell::before, #union-factory .proof-cell::before, #union-factory .cap-cell::after, #union-factory .proof-cell::after { display: none; }
}
@media (max-width: 1080px) {
  #union-factory .cap-grid, #union-factory .proof-grid { --cap-cols: 2; }
}
@media (max-width: 860px) {
  #union-factory .cap-grid, #union-factory .proof-grid { margin-inline: 0; }
  #union-factory .cap-cell, #union-factory .proof-cell { padding-left: 0; padding-right: 0; }
}
@media (max-width: 640px) {
  #union-factory .cap-grid, #union-factory .proof-grid { --cap-cols: 1; gap: 4px; }
  #union-factory .cap-grid > *, #union-factory .proof-grid > * { flex-basis: 100%; max-width: 100%; }
  #union-factory .cap-cell, #union-factory .proof-cell { padding: 16px 22px 18px; }
  #union-factory .cap-cell_name, #union-factory .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-factory .fig-copy .heading-style-h2, #union-factory .fig-copy .heading-style-h3 {
  font-size: clamp(25px, 2.7vw, 40px); line-height: 1.12; letter-spacing: -0.02em;
}
#union-factory .fig-copy .text-size-medium, #union-factory .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-factory .fig-copy .text-style-tagline { margin-bottom: 14px; }
#union-factory .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-factory .fig-sec[id], #union-factory .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-factory .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-factory .fig-cta .button, #union-factory .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-factory .fig-cta .button .button_text, #union-factory .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-factory .fig-cta .button-group, #union-factory .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-factory .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-factory .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-factory .fig-factory.is-compact { padding-top: 28px; }
#union-factory .fig-factory_stage { display: block; min-height: 1px; }
#union-factory .fig-factory_stage svg { display: block; width: 100%; height: auto; }
#union-factory .fig-factory_leader {
  fill: none; stroke: var(--brand-gray-500, var(--color-neutral-700, #4a4e52)); stroke-width: 1;
}
#union-factory .fig-factory_anchor {
  fill: var(--fig-heading); stroke: var(--theme-bg, var(--color-bg, #000));
}
#union-factory .fig-factory_lt { font-family: var(--font-code, ui-monospace, monospace); fill: var(--fig-heading); }
#union-factory .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-factory .fig-factory_caps { display: none; }
#union-factory .fig-factory.is-compact .fig-factory_caps { display: grid; gap: 7px; margin: 14px 2px 2px; }
#union-factory .fig-factory_cap {
  display: flex; align-items: baseline; gap: 8px; font-size: 12px; line-height: 1.4;
  color: var(--fig-muted);
}
#union-factory .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-factory .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-factory .fig-factory_cap i.is-fail { background-color: #e04b4d; }
#union-factory .fig-factory_cap i.is-retry { background-color: #5b90f7; }
#union-factory .fig-factory_cap i.is-ok { background-color: #8bcb6a; }
#union-factory .fig-factory_cap i.is-union-out {
  background-color: transparent;
  box-shadow: inset 0 0 0 1.5px var(--fig-accent);
}
#union-factory .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-factory .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-factory .fig-factory_cap i.is-raw { animation: none; }
}
#union-factory .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-factory .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-factory .fig-factory.is-band { max-width: 860px; margin: 0 auto; }
#union-factory .fig-factory.is-band .fig-factory_caps { justify-content: center; }
/* ═══ ai-factory/style.css ═══ *//* AI Factory page styles.
   Everything ABOVE the "WEBFLOW: paste into an Embed" banner is Designer-expressible:
   one plain rule per class, no descendant selectors, Webflow breakpoints only.
   Site-system classes (buttons, headings, spacers, taglines) come from
   ../_shared/union-system.css and already exist in the Webflow project. *//* ---- pills: page override of the site tagline chip — bare uppercase yellow eyebrow ---- */
#union-factory .text-style-tagline { border-style: none; background-color: transparent; padding: 0; color: var(--brand-yellow-500); font-family: var(--font-code); font-size: .8125rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; }
/* ---- nav / footer placeholders (replace with global symbols) ---- *//* kept: the footer placeholder reuses this */
#union-factory .nav-placeholder_logo { color: var(--theme-heading); font-weight: 600; font-size: 1.125rem; }
#union-factory .footer-placeholder { border-top: 1px solid var(--theme-border); }
#union-factory .footer-placeholder_note { color: var(--brand-gray-400); }
#union-factory .footer-placeholder_row { display: flex; align-items: center; justify-content: space-between; padding-top: 2rem; padding-bottom: 2rem; }
/* ---- hero ---- */
#union-factory .model-factory-hero_component { display: grid; grid-template-columns: .98fr 1.02fr; column-gap: 4rem; row-gap: 3rem; align-items: center; }
#union-factory .model-factory-hero_content { max-width: 36rem; }
/* ---- logo strip ---- *//* ---- stations ---- */
#union-factory .model-factory-stations_grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
#union-factory .model-factory-stations_head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .75rem; }
#union-factory .model-factory-stations_num { color: var(--brand-yellow-500); font-family: var(--font-code); font-size: .875rem; }
#union-factory .model-factory-stations_pillar { color: var(--brand-yellow-500); font-family: var(--font-code); font-size: .6875rem; letter-spacing: .08em; text-transform: uppercase; }
#union-factory .model-factory-stations_io { border-top: 1px solid var(--theme-border); padding-top: 1rem; display: flex; flex-direction: column; row-gap: .5rem; margin-top: auto; }
#union-factory .model-factory-stations_io-row { display: flex; align-items: center; flex-wrap: wrap; column-gap: .5rem; row-gap: .5rem; }
#union-factory .model-factory-stations_io-label { color: var(--brand-gray-400); font-family: var(--font-code); font-size: .75rem; min-width: 5.5rem; }
#union-factory .artifact-chip { border: 1px solid var(--theme-border); border-radius: var(--radius-large); background-color: var(--theme-border); color: var(--brand-yellow-500); font-family: var(--font-code); font-size: .75rem; padding: .25rem .75rem; }
#union-factory .artifact-chip.is-consume { color: var(--brand-gray-300); background-color: transparent; }
#union-factory .text-code { font-family: var(--font-code); font-size: .9em; color: var(--brand-gray-100); }
/* ---- product showcase: full-width rows, text one side / screenshot the other, staggered ---- */
#union-factory .model-factory-product_grid { display: flex; flex-direction: column; row-gap: 4rem; }
#union-factory .model-factory-product_card { display: grid; grid-template-columns: 1fr 1.7fr; align-items: center; column-gap: 3rem; }
#union-factory .model-factory-product_card.is-flip { grid-template-columns: 1.7fr 1fr; }
#union-factory .model-factory-product_media { background-color: #000000; border: 1px solid var(--theme-border); border-radius: var(--radius-small); overflow: hidden; }
#union-factory .model-factory-product_img { display: block; width: 100%; height: auto; }
#union-factory .model-factory-product_body { padding: 0; }
/* ---- code section ---- */
#union-factory .model-factory-code_tabs { display: flex; flex-wrap: wrap; justify-content: center; column-gap: .5rem; row-gap: .5rem; }
#union-factory .model-factory-code_tab { border: 1px solid var(--theme-border); border-radius: var(--radius-large); background-color: transparent; color: var(--brand-gray-300); font-family: var(--font-body); font-size: .875rem; font-weight: 500; padding: .5rem 1.25rem; cursor: pointer; transition: color .3s, border-color .3s, background-color .3s; }
#union-factory .model-factory-code_tab:hover { color: #ffffff; }
#union-factory .model-factory-code_tab.is-active { border-color: var(--brand-yellow-500); color: var(--brand-yellow-500); background-color: color-mix(in srgb, var(--brand-yellow-500) 10%, transparent); }
#union-factory .model-factory-code_pane { display: none; }
#union-factory .model-factory-code_pane.is-active { display: block; }
#union-factory .model-factory-code_source-note { color: var(--brand-gray-400); }
/* the same implicit `auto` min-size on an fr track: the panel and the notes
   column were 408px inside a 351px component at vw=390 */
#union-factory .model-factory-code_component { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); column-gap: 3rem; row-gap: 3rem; align-items: start; }
#union-factory .model-factory-code_panel, #union-factory .model-factory-code_notes, #union-factory .model-factory-code_note { min-width: 0; }
/* the note is a flex row (number + text); without this the text column keeps
   its max-content width and the pair ran 16px past a 390px viewport */
#union-factory .model-factory-code_note > * { min-width: 0; }
#union-factory .model-factory-code_note-title, #union-factory .model-factory-code_note p { overflow-wrap: anywhere; }
#union-factory .model-factory-code_notes { display: flex; flex-direction: column; row-gap: 1rem; }
#union-factory .model-factory-code_note { display: flex; column-gap: 1rem; align-items: baseline; cursor: pointer; border: 1px solid transparent; border-radius: var(--radius-medium); padding: 1rem 1.25rem; transition: border-color .25s, background-color .25s; }
#union-factory .model-factory-code_note:hover { border-color: var(--brand-yellow-500); }
#union-factory .model-factory-code_note.is-active { border-color: var(--brand-yellow-500); background-color: var(--theme-card); }
#union-factory .model-factory-code_note-num { color: var(--brand-yellow-500); font-family: var(--font-code); font-size: .875rem; }
#union-factory .model-factory-code_note-title { font-family: var(--font-code); font-size: .9375rem; color: var(--theme-heading); margin-bottom: .375rem; }
#union-factory .model-factory-code_source { border-top: 1px solid var(--theme-border); padding-top: 1.5rem; color: var(--brand-gray-400); }
#union-factory .model-factory-code_link { color: var(--brand-yellow-500); text-decoration: none; font-family: var(--font-code); }
/* ---- sovereign ---- */
#union-factory .model-factory-sovereign_band { border: 1px solid var(--theme-border); border-radius: var(--radius-large); background-color: var(--theme-card); padding: 5rem 3rem; }
#union-factory .model-factory-sovereign_grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1.5rem; }
#union-factory .model-factory-sovereign_icon { display: flex; align-items: center; justify-content: center; width: 2.75rem; height: 2.75rem; border: 1px solid var(--theme-border); border-radius: var(--radius-small); background-color: color-mix(in srgb, var(--brand-yellow-500) 8%, transparent); color: var(--brand-yellow-500); margin-bottom: 1.25rem; }
/* ---- reference ---- */
#union-factory .model-factory-reference_grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
#union-factory .model-factory-reference_card { display: flex; flex-direction: column; background-color: var(--theme-card); border: 1px solid var(--theme-border); border-radius: var(--radius-medium); padding: 2rem; text-decoration: none; color: var(--theme-body); }
#union-factory .model-factory-reference_repo { color: var(--brand-gray-400); font-family: var(--font-code); font-size: .75rem; margin-bottom: .75rem; }
#union-factory .model-factory-reference_cta { color: var(--brand-yellow-500); font-weight: 600; margin-top: auto; }
/* ---- cta band ---- */
#union-factory .model-factory-cta_band { border: 1px solid var(--theme-border); border-radius: var(--radius-large); padding: 5rem 3rem; }
#union-factory .model-factory-cta_buttons { justify-content: center; }
@media (max-width: 991px) {
  #union-factory .model-factory-hero_component { grid-template-columns: 1fr; }
  #union-factory .model-factory-hero_content { max-width: 42rem; }
  #union-factory .model-factory-code_component { grid-template-columns: minmax(0, 1fr); }
  #union-factory .model-factory-sovereign_grid { grid-template-columns: 1fr; }
  #union-factory .model-factory-product_card { grid-template-columns: 1fr; row-gap: 1.5rem; }
  #union-factory .model-factory-product_card.is-flip { grid-template-columns: 1fr; }
  #union-factory .model-factory-product_media { order: -1; }
}
@media (max-width: 767px) {
  #union-factory .model-factory-stations_grid { grid-template-columns: 1fr; }
  #union-factory .model-factory-reference_grid { grid-template-columns: 1fr; }
  #union-factory .model-factory-sovereign_band { padding: 3rem 1.5rem; }
  #union-factory .model-factory-cta_band { padding: 3rem 1.5rem; }
}
/* ============================================
   WEBFLOW: paste into an Embed / page <head>
   (not expressible in the Designer)
   ============================================
   Two embeds:
   (A) hero widget — everything .mf-widget_* below, plus the SVG markup
       and script.js, ship together as ONE HTML Embed element placed in
       the hero's right grid cell.
   (B) code panel — .model-factory-code_panel/.tok-* rules plus the
       <pre> markup ship as a second HTML Embed in the code section. *//* ---- (A) the pillar widget ----
   Named for the hero because it used to be the hero. It now lives in the
   "One loop, four properties" section; the hero is the isometric scene. */
#union-factory .model-factory-hero_widget {
  display: flex; flex-direction: column; row-gap: .75rem; min-width: 0;
  /* width:100% is load-bearing. margin-left:auto opts the item out of grid
     stretch, so without it the widget sizes to fit-content (~474px) and never
     reaches max-width — which read as a wide gap between the hero columns.
     36rem matches .model-factory-hero_content and fills the .95fr column. */
  width: 100%; max-width: 36rem; margin-left: auto;
}
/* …but in its own section there is no second column to hug, and margin-left
   auto alone parked it against the right edge with a column of dead space
   beside it. Centre it there. */
#union-factory .section_model-factory-pillars .model-factory-hero_widget {
  max-width: 44rem; margin-left: auto; margin-right: auto;
}
#union-factory .mf-widget_frame {
  background-color: var(--theme-card);
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-large);
  padding: .75rem .75rem 0;
  overflow: hidden;
}
#union-factory .mf-widget_svg { display: block; width: 100%; height: auto; }
#union-factory .mf-widget_perimeter {
  fill: none;
  stroke: var(--theme-border);
  stroke-width: 1.5;
  stroke-dasharray: 6 6;
  transition: stroke .6s, stroke-width .6s, filter .6s;
}
#union-factory .mf-widget_perimeter-chip { fill: color-mix(in srgb, var(--brand-yellow-500) 8%, transparent); stroke: var(--theme-border); }
#union-factory .mf-widget_perimeter-text { fill: var(--brand-gray-300); font-family: var(--font-code); font-size: 13px; letter-spacing: .12em; }
#union-factory .mf-widget_lock { stroke: var(--brand-yellow-500); transition: stroke .6s; }
#union-factory .mf-widget_pipe { fill: none; stroke: #3a3c3f; stroke-width: 1.5; }
#union-factory .mf-widget_pipe.is-return { stroke-dasharray: 4 5; }
#union-factory .mf-widget_station rect {
  fill: #000000;
  stroke: var(--theme-border);
  stroke-width: 1;
  transition: stroke .5s, stroke-width .5s, filter .5s;
}
#union-factory .mf-widget_station-title { fill: #ffffff; font-family: var(--font-body); font-weight: 600; font-size: 18.5px; letter-spacing: .04em; }
/* Collapsed, the title is the only thing in the box, so it sits on the box's
   vertical centre (baseline 24px below the authored y). On hover it lifts back
   to that authored y and the detail lines fade in underneath. */
#union-factory .mf-widget_station-title {
  transform: translateY(24px); transform-box: fill-box;
  transition: transform .22s cubic-bezier(.2,.7,.3,1);
}
#union-factory .mf-widget_station:hover .mf-widget_station-title, #union-factory .mf-widget_station:focus-within .mf-widget_station-title, #union-factory .mf-widget_station.is-open .mf-widget_station-title { transform: none; }
@media (prefers-reduced-motion: reduce) {
  #union-factory .mf-widget_station-title { transition: none; }
}
#union-factory .mf-widget_station-sub { fill: var(--brand-gray-300); font-family: var(--font-code); font-size: 14px; }
/* Each station shows only its all-caps title until you point at it; the detail
   lines fade and lift in. `.mf-widget_station` is an SVG <g>, so :hover works
   on it directly, and :focus-within covers keyboard and the synthetic focus a
   tap produces on touch (the group carries tabindex in the markup). */
#union-factory .mf-widget_station-sub {
  opacity: 0; transform: translateY(3px); transform-box: fill-box;
  transition: opacity .22s ease, transform .22s cubic-bezier(.2,.7,.3,1);
}
#union-factory .mf-widget_station:hover .mf-widget_station-sub, #union-factory .mf-widget_station:focus-within .mf-widget_station-sub, #union-factory .mf-widget_station.is-open .mf-widget_station-sub { opacity: 1; transform: none; }
#union-factory .mf-widget_station { cursor: pointer; }
#union-factory .mf-widget_station:focus-visible { outline: none; }
#union-factory .mf-widget_station:focus-visible rect { stroke: var(--brand-yellow-500); }
@media (prefers-reduced-motion: reduce) {
  #union-factory .mf-widget_station-sub { transition: none; }
}
/* the boxes were widened to 256u to carry this; the longest
     label, "ingest · filter · synthesize" at 28 chars, needs 235u of the 242u
     interior, so re-measure before growing either the type or the copy.
     Superseded note: 11.5px overflowed the old 200u boxes; the win there was the
     contrast lift (brand-gray-400 → -300, 3.8:1 → 11.2:1), not the size. */
#union-factory .mf-widget_station-flash { fill: var(--brand-red); font-family: var(--font-code); font-size: 13px; }
#union-factory .mf-widget_status { fill: var(--brand-green); transition: fill .4s; }
#union-factory .mf-widget_artifact rect { fill: #000000; stroke: var(--theme-border); transition: stroke .5s, fill .5s, filter .5s; }
#union-factory .mf-widget_artifact text { fill: var(--brand-yellow-500); font-family: var(--font-code); font-size: 13.5px; }
#union-factory .mf-widget_artifact.is-return text { fill: var(--brand-gray-300); }
#union-factory .mf-widget_dot { fill: var(--brand-yellow-500); }
#union-factory .mf-widget_dot.is-return { fill: var(--brand-gray-400); }
#union-factory .mf-widget_center-title { fill: var(--brand-yellow-500); font-family: var(--font-code); font-size: 19px; }
#union-factory .mf-widget_center-sub { fill: var(--brand-gray-300); font-family: var(--font-code); font-size: 14.5px; }
#union-factory .mf-widget_chips { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin-top: 1.25rem; }
#union-factory .mf-widget_chip {
  appearance: none;
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-large);
  background-color: transparent;
  color: var(--brand-gray-300);
  font-family: var(--font-code);
  font-size: .75rem;
  line-height: 1.2;
  letter-spacing: .04em;
  padding: .35rem .75rem;
  cursor: pointer;
  transition: color .2s, border-color .2s, background-color .2s;
}
#union-factory .mf-widget_chip:hover { color: #ffffff; }
#union-factory .mf-widget_chip.is-active {
  border-color: var(--brand-yellow-500);
  color: var(--brand-yellow-500);
  background-color: color-mix(in srgb, var(--brand-yellow-500) 10%, transparent);
}
/* scene: events — the artifact hand-offs light up */
#union-factory .mf-scene-events .mf-widget_artifact:not(.is-return) rect { stroke: var(--brand-yellow-500); fill: color-mix(in srgb, var(--brand-yellow-500) 10%, #000000); filter: drop-shadow(0 0 3px rgba(252, 181, 31, .8)) drop-shadow(0 0 14px rgba(252, 181, 31, .45)); }
#union-factory .mf-scene-events .mf-widget_artifact:not(.is-return) text { filter: drop-shadow(0 0 7px rgba(252, 181, 31, .8)); }
#union-factory .mf-scene-events .mf-widget_center-title { filter: drop-shadow(0 0 3px rgba(252, 181, 31, .9)) drop-shadow(0 0 10px rgba(252, 181, 31, .55)); }
#union-factory .mf-scene-events .mf-widget_dot:not(.is-return) { filter: drop-shadow(0 0 3px rgba(252, 181, 31, 1)) drop-shadow(0 0 10px rgba(252, 181, 31, .65)); }
/* scene: durable — foundry fails, then recovers */
#union-factory .mf-scene-durable #mf-st-train rect { animation: mf-fail-recover 5.5s ease-in-out infinite; }

@keyframes mf-fail-recover {
  0%, 8%   { stroke: var(--theme-border); }
  12%, 34% { stroke: var(--brand-red); stroke-width: 2; filter: drop-shadow(0 0 4px rgba(205, 50, 52, .95)) drop-shadow(0 0 18px rgba(205, 50, 52, .6)); }
  44%, 96% { stroke: var(--brand-green); stroke-width: 2; filter: drop-shadow(0 0 4px rgba(120, 184, 86, .9)) drop-shadow(0 0 18px rgba(120, 184, 86, .55)); }
  100%     { stroke: var(--theme-border); }
}
/* scene: infra-aware — foundry upgrades hardware */
#union-factory .mf-scene-infra #mf-st-train rect { stroke: var(--brand-yellow-500); stroke-width: 2; filter: drop-shadow(0 0 4px rgba(252, 181, 31, .9)) drop-shadow(0 0 18px rgba(252, 181, 31, .55)); }
/* scene: sovereign — perimeter lights up */
#union-factory .mf-scene-sovereign .mf-widget_perimeter {
  stroke: var(--brand-yellow-500);
  stroke-width: 2;
  filter: drop-shadow(0 0 4px rgba(252, 181, 31, .85)) drop-shadow(0 0 20px rgba(252, 181, 31, .5));
}
#union-factory .mf-scene-sovereign .mf-widget_perimeter-chip { stroke: var(--brand-yellow-500); fill: color-mix(in srgb, var(--brand-yellow-500) 15%, transparent); filter: drop-shadow(0 0 10px rgba(252, 181, 31, .5)); }
#union-factory .mf-scene-sovereign .mf-widget_perimeter-text { fill: var(--brand-yellow-500); }
#union-factory .mf-scene-sovereign .mf-widget_lock { filter: drop-shadow(0 0 6px rgba(252, 181, 31, .95)); }
#union-factory .mf-scene-sovereign .mf-widget_station rect { stroke: color-mix(in srgb, var(--brand-yellow-500) 40%, var(--theme-border)); }
@media (prefers-reduced-motion: reduce) {
  #union-factory .mf-widget_dots { display: none; }
}
/* ---- (B) code panel ---- */
#union-factory .model-factory-code_panel {
  background-color: var(--theme-card);
  border: 1px solid var(--theme-border);
  border-radius: var(--radius-medium);
  overflow: hidden;
}
#union-factory .model-factory-code_titlebar {
  display: flex; align-items: center; column-gap: .5rem;
  border-bottom: 1px solid var(--theme-border);
  padding: .75rem 1.5rem;
}
#union-factory .model-factory-code_filename { font-family: var(--font-code); font-size: .8125rem; color: var(--brand-gray-350); }
#union-factory .model-factory-code_pre {
  margin: 0;
  padding: 1.5rem;
  overflow: auto;
  font-family: var(--font-code);
  font-size: .75rem;
  line-height: 1.65;
  /* every tab the same height: the panes are grid-stacked, so without a cap the
     tallest one (serve.py, four notes) sets the height for all four and the
     short tabs open onto a screen of dead space. */
  max-height: 24rem;
  color: var(--brand-gray-100);
}
/* code lines: hovering a numbered note highlights its lines (see script.js) */
#union-factory .model-factory-code_pre code { display: block; width: max-content; min-width: 100%; }
#union-factory .model-factory-code_line { display: block; margin: 0 -1.5rem; padding: 0 1.5rem; border-left: 2px solid transparent; transition: background-color .25s, border-left-color .25s; }
#union-factory .model-factory-code_line.is-highlight { background-color: color-mix(in srgb, var(--brand-yellow-500) 8%, transparent); border-left-color: var(--brand-yellow-500); }
/* ---- (C) why-a-factory loop visual (HTML Embed) ---- */
#union-factory .model-factory-why_visual { background-color: var(--theme-card); border: 1px solid var(--theme-border); border-radius: var(--radius-large); padding: 1.5rem 1.5rem 1rem; }
/* Delays are derived from where the dot actually is, not from an even split.
   `animateMotion` defaults to calcMode="paced" — constant SPEED along the path —
   so on a 1531-unit path run in 8s the dot covers 0.0052s per unit. Measuring
   each box's leading edge along that path gives entry at 1.07s / 3.32s / 5.07s /
   7.32s; the 0.08s below is the keyframe's own 1% ramp, subtracted so the glow
   lands ON entry rather than after it.

   The old values were a flat 2s apart (1.09 / 3.09 / 5.09 / 7.09), which happens
   to be right for the two boxes on the long top and bottom edges and 0.23s early
   for the two on the short side edges — the dot reaches those later than an even
   split implies, because the 540-unit edges take 5.4x as long as the 100-unit
   sides. That mismatch is what read as "the box lights up too early".

   Recompute all four if the path, the box positions or `dur` change. *//* ---- (D) product showcase console mocks (one HTML Embed per card) ----
   Interactive recreations of the Union console screenshots: artifacts list,
   lineage graph, triggers list, training report, eval report. Series colors
   on the chart (#3378f5 / #3f7d2c / #c78500) are contrast- and CVD-validated
   against the dark card surface. *//* shared chrome */
#union-factory .mfc { background-color: #0c0d0f; font-family: var(--font-body); font-size: .8125rem; color: var(--brand-gray-300); text-align: left; }
#union-factory .mfc_head { display: flex; align-items: center; justify-content: space-between; column-gap: 1rem; padding: 1rem 1.25rem .75rem; }
#union-factory .mfc_title { color: #ffffff; font-weight: 600; font-size: 1.0625rem; }
#union-factory .mfc_sub { color: var(--brand-gray-400); font-size: .75rem; margin-top: .125rem; }
#union-factory .mfc_search { background-color: #17181b; border: 1px solid var(--theme-border); border-radius: var(--radius-large); color: var(--brand-gray-100); font-family: var(--font-body); font-size: .8125rem; padding: .375rem .875rem; width: 11rem; outline: none; }
#union-factory .mfc_search:focus { border-color: var(--brand-yellow-500); }
#union-factory .mfc_search::placeholder { color: var(--brand-gray-400); }
#union-factory .mfc_filters { display: flex; column-gap: .375rem; padding: 0 1.25rem .75rem; }
#union-factory .mfc_filter { border: 1px solid var(--theme-border); border-radius: var(--radius-large); background-color: transparent; color: var(--brand-gray-400); font-family: var(--font-body); font-size: .75rem; padding: .1875rem .75rem; cursor: pointer; transition: color .2s, border-color .2s; }
#union-factory .mfc_filter:hover { color: #ffffff; }
#union-factory .mfc_filter.is-active { border-color: var(--brand-yellow-500); color: var(--brand-yellow-500); background-color: color-mix(in srgb, var(--brand-yellow-500) 10%, transparent); }
#union-factory .mfc_chip-key { border: 1px solid var(--theme-border); border-radius: 999px 0 0 999px; background-color: #1f2023; color: var(--brand-gray-400); font-family: var(--font-code); font-size: .625rem; padding: .0625rem .375rem; }
#union-factory .mfc_chip-val { border: 1px solid var(--theme-border); border-left-style: none; border-radius: 0 999px 999px 0; color: var(--brand-gray-300); font-family: var(--font-code); font-size: .625rem; padding: .0625rem .375rem; }
#union-factory .mfc_footer { border-top: 1px solid var(--theme-border); padding: .75rem 1.25rem; font-family: var(--font-code); font-size: .71875rem; color: var(--brand-gray-400); min-height: 2.4em; }
#union-factory .mfc_empty { padding: 1.5rem 1.25rem; font-family: var(--font-code); font-size: .75rem; color: var(--brand-gray-400); }
#union-factory .mfc_pill-ok { color: var(--brand-green); background-color: color-mix(in srgb, var(--brand-green) 12%, transparent); border-radius: var(--radius-large); font-size: .6875rem; font-weight: 600; padding: .1875rem .625rem; white-space: nowrap; }
#union-factory .mfc button:focus-visible { outline: 2px solid var(--brand-yellow-500); outline-offset: 1px; }
/* artifacts list */
#union-factory .mfc-art_cols, #union-factory .mfc-art_row { display: grid; grid-template-columns: 1fr 10rem 6.5rem; align-items: center; column-gap: 1rem; padding: 0 1.25rem; }
#union-factory .mfc-art_cols { border-bottom: 1px solid var(--theme-border); padding-bottom: .5rem; color: var(--brand-gray-400); font-size: .6875rem; }
#union-factory .mfc-art_row { border-bottom: 1px solid #ffffff0a; padding-top: .5625rem; padding-bottom: .5625rem; transition: background-color .15s; }
#union-factory .mfc-art_row:hover { background-color: #ffffff08; }
#union-factory .mfc-art_row:last-child { border-bottom-style: none; }
#union-factory .mfc-art_label { display: block; color: var(--brand-gray-100); font-weight: 500; margin-bottom: .25rem; }
#union-factory .mfc-art_run { color: var(--brand-gray-400); font-family: var(--font-code); font-size: .71875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#union-factory .mfc-art_age { color: var(--brand-gray-300); font-size: .75rem; text-align: right; }
/* lineage graph */
#union-factory .mfc-lineage { background-image: radial-gradient(#ffffff14 1px, transparent 1px); background-size: 22px 22px; }
#union-factory .mfc-lin_svg { display: block; width: 100%; height: auto; }
#union-factory .mfc-lin_node { cursor: pointer; transition: opacity .3s; }
#union-factory .mfc-lin_node:focus { outline: none; }
#union-factory .mfc-lin_box { fill: #141518; stroke: #2c2e33; stroke-width: 1; transition: stroke .3s; }
#union-factory .mfc-lin_node:hover .mfc-lin_box, #union-factory .mfc-lin_node.is-focus .mfc-lin_box, #union-factory .mfc-lin_node:focus-visible .mfc-lin_box { stroke: var(--brand-yellow-500); }
#union-factory .mfc-lin_title { fill: #ffffff; font-family: var(--font-body); font-weight: 600; font-size: 15px; }
#union-factory .mfc-lin_badge { fill: #26282c; }
#union-factory .mfc-lin_badgetext { fill: var(--brand-gray-300); font-family: var(--font-code); font-size: 11px; }
#union-factory .mfc-lin_name { fill: #9aa0a6; font-family: var(--font-code); font-size: 11.5px; }
#union-factory .mfc-lin_ready { fill: color-mix(in srgb, var(--brand-green) 14%, transparent); }
#union-factory .mfc-lin_readytext { fill: var(--brand-green); font-family: var(--font-body); font-weight: 600; font-size: 10.5px; }
#union-factory .mfc-lin_latest { fill: #6f737a; font-family: var(--font-code); font-size: 10.5px; }
#union-factory .mfc-lin_run { fill: #6ea3ff; font-family: var(--font-code); font-size: 10.5px; }
#union-factory .mfc-lin_edge { fill: none; stroke: #3a3c3f; stroke-width: 1.5; transition: stroke .3s, opacity .3s; }
#union-factory .mfc-lin_edgelabel { fill: var(--brand-gray-400); font-family: var(--font-code); font-size: 10px; transition: opacity .3s; }
#union-factory .mfc-lin_dot { fill: var(--brand-yellow-500); }
#union-factory .mfc-lineage.has-focus .mfc-lin_node.is-dim, #union-factory .mfc-lineage.has-focus .mfc-lin_edge.is-dim, #union-factory .mfc-lineage.has-focus .mfc-lin_edgelabel.is-dim { opacity: .22; }
#union-factory .mfc-lineage.has-focus .mfc-lin_edge:not(.is-dim) { stroke: var(--brand-yellow-500); }
/* triggers list */
#union-factory .mfc-trig_cols, #union-factory .mfc-trig_row { display: grid; grid-template-columns: 3rem 1fr 15rem 5.5rem; align-items: center; column-gap: 1rem; padding: 0 1.25rem; }
#union-factory .mfc-trig_cols { border-bottom: 1px solid var(--theme-border); padding-bottom: .5rem; color: var(--brand-gray-400); font-size: .6875rem; }
#union-factory .mfc-trig_row { border-bottom: 1px solid #ffffff0a; padding-top: .625rem; padding-bottom: .625rem; transition: opacity .3s; }
#union-factory .mfc-trig_row.is-paused { opacity: .45; }
#union-factory .mfc-trig_name { color: var(--brand-gray-100); font-weight: 500; margin-bottom: .25rem; }
#union-factory .mfc-trig_cond { color: var(--brand-gray-400); font-size: .71875rem; }
#union-factory .mfc-trig_task { color: var(--brand-gray-300); font-family: var(--font-code); font-size: .71875rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#union-factory .mfc-trig_age { color: var(--brand-gray-300); font-size: .75rem; text-align: right; }
#union-factory .mfc-trig_toggle { position: relative; width: 2.25rem; height: 1.25rem; border-style: none; border-radius: .625rem; background-color: #3a3c3f; cursor: pointer; padding: 0; transition: background-color .25s; }
#union-factory .mfc-trig_toggle.is-on { background-color: var(--brand-green); }
#union-factory .mfc-trig_knob { position: absolute; top: .125rem; left: .125rem; width: 1rem; height: 1rem; border-radius: 50%; background-color: #ffffff; transition: transform .25s; }
#union-factory .mfc-trig_toggle.is-on .mfc-trig_knob { transform: translateX(1rem); }
/* run-report chrome (training + evals) */
#union-factory .mfc-run_bar { display: flex; align-items: center; flex-wrap: wrap; column-gap: .75rem; row-gap: .375rem; padding: .875rem 1.25rem; border-bottom: 1px solid var(--theme-border); }
#union-factory .mfc-run_name { color: #ffffff; font-weight: 600; font-size: .9375rem; }
#union-factory .mfc-run_meta { color: var(--brand-gray-400); font-size: .71875rem; }
#union-factory .mfc-run_meta b { color: var(--brand-gray-100); font-weight: 500; }
#union-factory .mfc-run_tabs { display: flex; column-gap: .25rem; padding: .5rem 1.25rem 0; border-bottom: 1px solid var(--theme-border); }
#union-factory .mfc-run_tabs span { color: var(--brand-gray-400); font-size: .75rem; padding: .375rem .625rem .5rem; border-bottom: 2px solid transparent; }
#union-factory .mfc-run_tabs span.is-active { color: #ffffff; border-bottom-color: var(--theme-accent); }
#union-factory .mfc_report { background-color: var(--theme-card); border: 1px solid var(--theme-border); border-radius: .5rem .5rem 0 0; margin: 1rem 1rem 0; padding: 1.125rem 1.25rem 1rem; }
#union-factory .mfc_report-head { display: flex; align-items: center; justify-content: space-between; column-gap: 1rem; flex-wrap: wrap; row-gap: .5rem; margin-bottom: .625rem; }
#union-factory .mfc_report-title { color: #ffffff; font-weight: 600; font-size: 1rem; }
#union-factory .mfc_report-status { color: var(--brand-green); font-family: var(--font-code); font-size: .71875rem; }
#union-factory .mfc_report-status.is-running { color: var(--brand-yellow-500); }
#union-factory .mfc_report-config { border: 1px solid var(--theme-border); border-radius: .625rem; background-color: #0c0d0f; padding: .5rem .75rem; font-family: var(--font-code); font-size: .65625rem; color: var(--brand-gray-400); margin-bottom: .875rem; line-height: 1.8; }
#union-factory .mfc_report-config b { color: var(--brand-gray-100); font-weight: 500; }
#union-factory .mfc_tiles { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
#union-factory .mfc_tile { flex: 1 1 6rem; border: 1px solid var(--theme-border); border-radius: .625rem; background-color: #0c0d0f; padding: .625rem .75rem; min-width: 0; }
#union-factory .mfc_tile-val { color: #ffffff; font-weight: 600; font-size: 1.1875rem; line-height: 1.2; white-space: nowrap; }
#union-factory .mfc_tile-delta { color: var(--brand-gray-400); font-family: var(--font-code); font-size: .625rem; margin-top: .125rem; white-space: nowrap; }
#union-factory .mfc_tile-delta.is-up { color: var(--brand-green); }
#union-factory .mfc_tile-delta.is-down { color: #e06c6e; }
#union-factory .mfc_tile-label { color: var(--brand-gray-400); font-size: .6875rem; margin-top: .375rem; }
/* training chart + controls */
#union-factory .mfc_chart-head { display: flex; align-items: baseline; justify-content: space-between; column-gap: 1rem; flex-wrap: wrap; row-gap: .25rem; margin-bottom: .375rem; }
#union-factory .mfc_chart-title { color: var(--brand-gray-100); font-size: .75rem; font-weight: 500; }
#union-factory .mfc_legend { display: flex; column-gap: .875rem; flex-wrap: wrap; }
#union-factory .mfc_legend-item { display: inline-flex; align-items: center; column-gap: .3125rem; color: var(--brand-gray-400); font-family: var(--font-code); font-size: .625rem; }
#union-factory .mfc_swatch { display: inline-block; width: .625rem; height: .625rem; border-radius: .1875rem; }
#union-factory .mfc_chart { position: relative; }
#union-factory .mfc_chart svg { display: block; width: 100%; height: auto; }
#union-factory .mfc_tip { position: absolute; pointer-events: none; background-color: #26282c; border: 1px solid #3a3c3f; border-radius: .625rem; padding: .375rem .625rem; font-family: var(--font-code); font-size: .625rem; line-height: 1.7; color: var(--brand-gray-100); white-space: nowrap; transform: translate(-50%, -100%); opacity: 0; transition: opacity .15s; z-index: 2; }
#union-factory .mfc_tip.is-show { opacity: 1; }
#union-factory .mfc_controls { display: flex; align-items: center; column-gap: .875rem; border-top: 1px solid var(--theme-border); margin-top: .75rem; padding-top: .75rem; }
#union-factory .mfc_play { border: 1px solid var(--brand-yellow-500); border-radius: var(--radius-large); background-color: color-mix(in srgb, var(--brand-yellow-500) 10%, transparent); color: var(--brand-yellow-500); font-family: var(--font-body); font-size: .75rem; font-weight: 600; padding: .3125rem .875rem; cursor: pointer; white-space: nowrap; }
#union-factory .mfc_play:hover { background-color: color-mix(in srgb, var(--brand-yellow-500) 20%, transparent); }
#union-factory .mfc_scrub { flex: 1; accent-color: var(--brand-yellow-500); min-width: 0; }
#union-factory .mfc_controls-label { color: var(--brand-gray-400); font-family: var(--font-code); font-size: .6875rem; white-space: nowrap; }
/* eval report */
#union-factory .mfc_verpick { display: inline-flex; align-items: center; column-gap: .25rem; }
#union-factory .mfc_verpick-label { color: var(--brand-gray-400); font-family: var(--font-code); font-size: .65625rem; margin-right: .25rem; }
#union-factory .mfc_verpick button { border: 1px solid var(--theme-border); border-radius: 999px; background-color: transparent; color: var(--brand-gray-300); font-family: var(--font-code); font-size: .71875rem; padding: .25rem .625rem; cursor: pointer; transition: color .2s, border-color .2s; }
#union-factory .mfc_verpick button:hover { color: #ffffff; }
#union-factory .mfc_verpick button.is-active { border-color: var(--brand-yellow-500); color: var(--brand-yellow-500); background-color: color-mix(in srgb, var(--brand-yellow-500) 10%, transparent); }
#union-factory .mfc_gate { border-radius: 999px; font-size: .9375rem; font-weight: 700; padding: .125rem .625rem; }
#union-factory .mfc_gate.is-pass { color: var(--brand-green); background-color: color-mix(in srgb, var(--brand-green) 14%, transparent); }
#union-factory .mfc_gate.is-hold { color: #e06c6e; background-color: color-mix(in srgb, var(--brand-red) 18%, transparent); }
#union-factory .mfc-ev_tablewrap { overflow-x: auto; border: 1px solid var(--theme-border); border-radius: .625rem; }
#union-factory .mfc-ev_table { width: 100%; border-collapse: collapse; font-size: .71875rem; }
#union-factory .mfc-ev_table th { text-align: left; color: var(--brand-gray-400); font-weight: 500; font-size: .65625rem; background-color: #0c0d0f; padding: .4375rem .75rem; border-bottom: 1px solid var(--theme-border); }
#union-factory .mfc-ev_table td { color: var(--brand-gray-300); font-family: var(--font-code); padding: .375rem .75rem; border-bottom: 1px solid #ffffff0a; white-space: nowrap; }
#union-factory .mfc-ev_table tr:last-child td { border-bottom-style: none; }
#union-factory .mfc_pill-pass { color: var(--brand-green); background-color: color-mix(in srgb, var(--brand-green) 12%, transparent); border-radius: .625rem; font-family: var(--font-body); font-size: .625rem; font-weight: 600; padding: .0625rem .5rem; }
#union-factory .mfc_pill-fail { color: #e06c6e; background-color: color-mix(in srgb, var(--brand-red) 15%, transparent); border-radius: .625rem; font-family: var(--font-body); font-size: .625rem; font-weight: 600; padding: .0625rem .5rem; }
#union-factory .mfc-ev-cand.is-changed { animation: mfc-cell-flash 1.2s ease-out; }

@keyframes mfc-cell-flash { 0% { background-color: color-mix(in srgb, var(--brand-yellow-500) 25%, transparent); } 100% { background-color: transparent; } }
#union-factory .mfc_footer.is-hold { color: #e06c6e; }
#union-factory .mfc_footer.is-pass { color: var(--brand-green); }
@media (max-width: 767px) {
  #union-factory .mfc-art_cols, #union-factory .mfc-art_row { grid-template-columns: 1fr 6.5rem; }
  #union-factory .mfc-art_run, #union-factory .mfc-art_cols span:nth-child(2) { display: none; }
  #union-factory .mfc-trig_cols, #union-factory .mfc-trig_row { grid-template-columns: 3rem 1fr 5.5rem; }
  #union-factory .mfc-trig_task, #union-factory .mfc-trig_cols span:nth-child(3) { display: none; }
  #union-factory .mfc_search { width: 8rem; }
  #union-factory .mfc_report { margin: .75rem .5rem 0; padding: .875rem .75rem .75rem; }
}
@media (prefers-reduced-motion: reduce) {
  #union-factory .mfc-lin_dot { display: none; }
  #union-factory .mfc-ev-cand.is-changed { animation: none; }
}
/* Union hljs palette on the dark card *//* ══════════════════════════════════════════════════════════════════════════
   ADDED: inference section + sovereign band CTA
   (page expansion per the self-serve launch structure doc)
   ══════════════════════════════════════════════════════════════════════════ */
#union-factory .model-factory-sovereign_cta { justify-content: center; }
/* ── cross-links ──
   Same closing pattern as ../sovereign-ai/ and ../advanced-scheduling/: three
   cards to the other platform pages, sitting between the last content section
   and the CTA. Keep the three in step. */
#union-factory .model-factory-more_grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
#union-factory .model-factory-more_card {
  display: block; text-decoration: none;
  background-color: var(--theme-card); border: 1px solid var(--theme-border);
  border-radius: var(--radius-medium); padding: 1.5rem 1.75rem;
  transition: border-color .18s ease;
}
#union-factory .model-factory-more_kicker { font-size: .6875rem; letter-spacing: .06em; text-transform: uppercase; color: var(--brand-gray-400); margin-bottom: .5rem; }
#union-factory .model-factory-more_card p { margin-top: .625rem; color: var(--brand-gray-350); }
#union-factory .model-factory-more_go { display: inline-block; margin-top: 1rem; font-size: .875rem; font-weight: 600; color: var(--theme-accent); }
#union-factory .model-factory-more_card:hover { border-color: var(--theme-accent); }
@media (prefers-reduced-motion: reduce) {
  #union-factory .model-factory-more_card { transition: none; }
}
@media (max-width: 991px) {
  #union-factory .model-factory-more_grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 767px) {
  #union-factory .model-factory-more_grid { grid-template-columns: 1fr; }
}
/* the cross-links block gets the same centred header as every other section */
#union-factory .model-factory-more_head p { color: var(--brand-gray-350); }
/* ── primary CTA sub-note ──
   Mirrors ../home/: "Try for free" sits under Get Started, so the button group
   aligns to the top and the primary CTA becomes a small column of its own. */
#union-factory .cta-stack { display: flex; flex-direction: column; align-items: center; row-gap: .4375rem; }
#union-factory .cta-note { font-size: .875rem; color: var(--brand-gray-350); }
#union-factory .button-group { align-items: flex-start; }
/* ── value props + proof ──
   Mirrors ../home/'s "How teams own their AI stack": one row per claim, with
   the customer that proves it. Left half links to the section on this page,
   right half to that customer's case study. Two sibling links, not nested. */
#union-factory .model-factory-proof_list { display: flex; flex-direction: column; }
#union-factory .model-factory-proof_row {
  display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  align-items: stretch; column-gap: clamp(1.25rem, 3vw, 3rem);
  border-top: 1px solid var(--theme-border);
}
#union-factory .model-factory-proof_row:last-child { border-bottom: 1px solid var(--theme-border); }
#union-factory .model-factory-proof_main {
  display: block; padding: 1.375rem .25rem; text-decoration: none; color: inherit;
  transition: background-color .16s ease, padding-left .16s ease;
}
#union-factory .model-factory-proof_text { display: flex; flex-direction: column; row-gap: .1875rem; min-width: 0; }
#union-factory .model-factory-proof_name { font-size: 1.0625rem; font-weight: 600; color: var(--theme-heading); }
#union-factory .model-factory-proof_desc { font-size: .9375rem; color: var(--brand-gray-350); text-wrap: pretty; }
#union-factory .model-factory-proof_main:hover { background-color: rgba(255,255,255,.035); padding-left: .625rem; }
#union-factory .model-factory-proof_main:focus-visible { outline: 2px solid var(--theme-accent); outline-offset: -2px; }
#union-factory .model-factory-proof_cs {
  display: flex; flex-direction: column; justify-content: center; row-gap: .1875rem;
  padding: 1.375rem .25rem; text-decoration: none; color: inherit;
  transition: background-color .16s ease;
}
#union-factory .model-factory-proof_co { font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--theme-accent); }
#union-factory .model-factory-proof_result { font-size: .9375rem; font-weight: 600; color: var(--theme-heading); text-wrap: pretty; }
#union-factory .model-factory-proof_result::after { content: " ↗"; font-weight: 400; color: var(--brand-gray-400); transition: color .16s ease; }
#union-factory .model-factory-proof_cs:hover { background-color: rgba(255,255,255,.035); }
#union-factory .model-factory-proof_cs:hover .model-factory-proof_result::after { color: var(--theme-accent); }
#union-factory .model-factory-proof_cs:focus-visible { outline: 2px solid var(--theme-accent); outline-offset: -2px; }
@media (prefers-reduced-motion: reduce) {
  #union-factory .model-factory-proof_main, #union-factory .model-factory-proof_cs, #union-factory .model-factory-proof_result::after { transition: none; }
}
@media (max-width: 767px) {
  #union-factory .model-factory-proof_row { grid-template-columns: 1fr; }
  #union-factory .model-factory-proof_main { padding-bottom: .375rem; }
  #union-factory .model-factory-proof_cs { padding-top: 0; padding-bottom: 1.125rem; }
}
/* ── flat blocks ──
   These read as cards but nothing about them is clickable, so the border,
   fill and shadow are decorative only. A hairline above each groups them into
   columns and keeps them distinct against the page ground without the chrome.
   Interactive cards — cross-links, reference links — keep the card treatment. */
#union-factory .flat-block {
  display: flex; flex-direction: column; row-gap: .5rem;
  background-color: transparent; border: 0; box-shadow: none; border-radius: 0;
  border-top: 1px solid var(--theme-border);
  padding: 1.375rem 0 .25rem;
}
#union-factory .flat-block p { color: var(--brand-gray-350); }
#union-factory .flat-block_icon { width: 1.25rem; height: 1.25rem; color: var(--theme-accent); margin-bottom: .125rem; }
/* ── above-the-fold rhythm ──
   padding-section-large is 7rem top and bottom, which pushed the next section
   a full screen down. Tighten the hero and the top of the section under it so
   that section peeks above the fold, the way the home page does. */
#union-factory .section_model-factory-hero .padding-section-large { padding-top: 2rem; padding-bottom: 1.5rem; }
#union-factory .section_model-factory-proof .padding-section-large { padding-top: 4rem; }
@media (max-width: 991px) {
  #union-factory .section_model-factory-hero .padding-section-large { padding-top: 2rem; padding-bottom: 1.5rem; }
}
/* proof-section header: same scale as the home page's "How teams own their AI
   stack" — no eyebrow, 25→34px heading, 16.5px lede, 32px down to the list. */
#union-factory .model-factory-proof_head { max-width: 47.5rem; margin: 0 0 2rem; }
#union-factory .model-factory-proof_h { font-size: clamp(1.5625rem, 4.2vw, 2.125rem); line-height: 1.15; margin: 0 0 .625rem; }
#union-factory .model-factory-proof_lede { font-size: 1.03125rem; color: var(--brand-gray-350); margin: 0; text-wrap: pretty; }
/* Every walkthrough pane shares one grid cell, so the block stays the height of
   its tallest tab and switching never moves the page. Measured before this: the
   four panes ran 453–715px. Same treatment as the agents build tabs and the
   observability panes. *//* Stacking means every pane is laid out, so the widest one sets the width —
   without these the hidden panes pushed the page 297px wide at vw=390. */
#union-factory .mf-panes { display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; }
#union-factory .mf-panes > .model-factory-code_pane { min-width: 0; }
#union-factory .mf-panes .model-factory-code_component, #union-factory .mf-panes .model-factory-code_panel { min-width: 0; }
#union-factory .mf-panes > .model-factory-code_pane { grid-area: 1 / 1; display: block; }
#union-factory .mf-panes > .model-factory-code_pane:not(.is-active) { visibility: hidden; pointer-events: none; }


/* ═══ 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-factory {
  /* brand */
  --brand-dark: #18191a;
  --brand-gray-100: #f2f3f3;
  --brand-gray-300: #cccfd1;
  --brand-gray-350: #81858b;
  --brand-gray-400: #72757a;
  --brand-yellow-500: #fcb51f;
  --brand-purple: #6f2aef;
  --brand-red: #cd3234;
  --brand-green: #78b856;
  --brand-orange: #e8883a;
  --brand-blue: #3378f5;
  --brand-pink: #ad3abb;
  --brand-brown: #a65a17;
  --brand-blue-dark: #1648b8;
  --brand-green-dark: #008013;
  --brand-red-dark: #980202;
  --white-12: #ffffff1f;
  /* theme roles */
  --theme-background: #000000;
  --theme-heading: #ffffff;
  --theme-body: var(--brand-gray-300);
  --theme-accent: var(--brand-yellow-500);
  --theme-border: var(--white-12);
  --theme-card: var(--brand-dark);
  /* type */
  --font-body: "Yellix", Arial, sans-serif;
  --font-heading: "Yellix", Arial, sans-serif;
  --font-code: "IBM Plex Mono", Tahoma, sans-serif;
  --heading-weight: 600;
  --heading-line-height: 1.05;
  /* ui — note: tighter radii than flyte.org */
  --radius-small: .5rem;
  --radius-medium: 1rem;
  --radius-large: 1.5rem;
  --border-width: 1px;
}
#union-factory {
  margin: 0;
  background-color: var(--theme-background);
  color: var(--theme-body);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
#union-factory p { margin: 0; }
#union-factory a { color: inherit; }
#union-factory img { max-width: 100%; display: block; }
#union-factory code, #union-factory pre { font-family: var(--font-code); }
/* ── prototype deviation: in-page anchor behaviour ──
   The hero's secondary CTA and the proof rows link to sections on the same
   page. Without these two rules the browser jumps instantly and lands with
   the heading underneath the sticky navbar. Smooth scroll is disabled for
   visitors who asked for reduced motion. */
#union-factory { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  #union-factory { scroll-behavior: auto; }
}
#union-factory [id] { scroll-margin-top: 6rem; }
/* some anchors target widgets, not sections *//* ═══ _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-factory {
  /* 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-factory pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
/* ═══ _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-factory {
  --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 */
}
/* ═══ 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-factory {
  /* brand */
  --brand-dark: #18191a;
  --brand-gray-100: #f2f3f3;
  --brand-gray-300: #cccfd1;
  --brand-gray-350: #81858b;
  --brand-gray-400: #72757a;
  --brand-yellow-500: #fcb51f;
  --brand-purple: #6f2aef;
  --brand-red: #cd3234;
  --brand-green: #78b856;
  --brand-orange: #e8883a;
  --brand-blue: #3378f5;
  --brand-pink: #ad3abb;
  --brand-brown: #a65a17;
  --brand-blue-dark: #1648b8;
  --brand-green-dark: #008013;
  --brand-red-dark: #980202;
  --white-12: #ffffff1f;
  /* theme roles */
  --theme-background: #000000;
  --theme-heading: #ffffff;
  --theme-body: var(--brand-gray-300);
  --theme-accent: var(--brand-yellow-500);
  --theme-border: var(--white-12);
  --theme-card: var(--brand-dark);
  /* type */
  --font-body: "Yellix", Arial, sans-serif;
  --font-heading: "Yellix", Arial, sans-serif;
  --font-code: "IBM Plex Mono", Tahoma, sans-serif;
  --heading-weight: 600;
  --heading-line-height: 1.05;
  /* ui — note: tighter radii than flyte.org */
  --radius-small: .5rem;
  --radius-medium: 1rem;
  --radius-large: 1.5rem;
  --border-width: 1px;
}
#union-factory {
  margin: 0;
  background-color: var(--theme-background);
  color: var(--theme-body);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
#union-factory p { margin: 0; }
#union-factory a { color: inherit; }
#union-factory img { max-width: 100%; display: block; }
#union-factory code, #union-factory pre { font-family: var(--font-code); }
/* ── prototype deviation: in-page anchor behaviour ──
   The hero's secondary CTA and the proof rows link to sections on the same
   page. Without these two rules the browser jumps instantly and lands with
   the heading underneath the sticky navbar. Smooth scroll is disabled for
   visitors who asked for reduced motion. */
#union-factory { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  #union-factory { scroll-behavior: auto; }
}
#union-factory [id] { scroll-margin-top: 6rem; }
/* some anchors target widgets, not sections */

/* 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-factory {
  /* 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-factory pre {
  border: 1px solid var(--code-border);
  border-radius: var(--code-radius);
  padding: 1.5rem;
  overflow-x: auto;
}
/* ══════════════════════════════════════════════════════════════════════════
   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 above the prototype. set_visibility is
   unsupported on ComponentInstances and remove_element is irreversible, so
   they are suppressed here. This stylesheet loads only on this page, so the
   unscoped rules 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-factory figure, #union-factory blockquote, #union-factory figcaption {
  margin: 0; padding: 0; border: 0; text-align: inherit;
}
#union-factory ul, #union-factory ol { margin: 0; padding: 0; }
#union-factory button { font: inherit; color: inherit; }
/* The site's .navigation is position:fixed (~8rem tall), so page content would
   start underneath it. 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-factory { padding-top: 8rem; }
#union-factory [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-factory { padding-top: 138px; }
  @media (max-width: 991px) { #union-factory { padding-top: 96px; } }

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

  /* ── mobile diagrams ───────────────────────────────────────
     The diagrams fit the screen — never wider than the viewport. What buys
     the legibility is dropping the small stuff and spending the space on
     what is left: the second line inside each station ("ingest · filter ·
     synthesize", "durable fan-out · spot") renders around 7px scaled to
     fit, and it crowds the station name. Gone, the name sits centred —
     which also removes the hover lift it needed to make room. */
  @media (max-width: 767px) {
    #union-factory .mf-widget_frame,
    #union-factory .mfc_chart,
    #union-factory .mfc-lineage { overflow-x: visible; }
    #union-factory .mf-widget_svg,
    #union-factory .mfc_chart > svg,
    #union-factory .mfc-lin_svg { min-width: 0; }

    #union-factory .mf-widget_station-sub { display: none; }
    #union-factory .mf-widget_station-title {
      opacity: 1;
      transform: none;
      transition: none;
      font-size: 24px;
      letter-spacing: 0;
    }
    /* Perimeter label, centre caption and the unclassed edge labels all sit
       around 6.5–7.3px once the widget is scaled to fit. */
    #union-factory .mf-widget_perimeter-text,
    #union-factory .mf-widget_center-sub,
    #union-factory .mf-widget_svg text:not([class]) { font-size: 20px; }

    /* Those artifact labels sit on fixed-width pills that were drawn for
       the old 13.5-unit type, so at 20 the text spilled out both ends.
       Each pill is centred on its label, so the new width is the label's
       measured width + 14 units of padding a side, and x is the centre
       minus half of that. The rects carry no class — y is what tells them
       apart, and .is-return separates the two that share y=292. */
    #union-factory .mf-widget_artifact:not(.is-return) rect[y="58"]  { x: 174px; width: 292px; }
    #union-factory .mf-widget_artifact:not(.is-return) rect[y="292"] { x: 328px; width: 304px; }
    #union-factory .mf-widget_artifact:not(.is-return) rect[y="536"] { x: 192px; width: 256px; }
    #union-factory .mf-widget_artifact.is-return rect[y="292"]       { x: 44px;  width: 232px; }

    /* The lineage graph is 1000 units wide, so it scales hardest. Keep the
       node title and artifact name, drop the per-node annotations — run
       ids, badges, "Ready", edge labels — which land near 3.5px. */
    #union-factory .mfc-lin_edgelabel,
    #union-factory .mfc-lin_badgetext,
    #union-factory .mfc-lin_readytext,
    #union-factory .mfc-lin_latest,
    #union-factory .mfc-lin_run { display: none; }
    #union-factory .mfc-lin_title { font-size: 30px; }
    #union-factory .mfc-lin_name { font-size: 28px; }

    /* The training chart's axis labels are 10 units on a 640 viewBox. */
    #union-factory .mfc_chart > svg text { font-size: 22px; }
  }

  /* ── mobile widgets ────────────────────────────────────────
     The HTML widgets are drawn at desktop density, so their rem type lands
     at 9.8–12px on a phone. Raise the floor to 13px, 12.5px for monospace. */
  @media (max-width: 767px) {
    #union-factory .mf-widget_chip,
    #union-factory .mfc,
    #union-factory .mfc-art_age,
    #union-factory .mfc-art_cols,
    #union-factory .mfc-art_run,
    #union-factory .mfc-ev_table,
    #union-factory .mfc-run_meta,
    #union-factory .mfc-run_tabs,
    #union-factory .mfc-trig_age,
    #union-factory .mfc-trig_cols,
    #union-factory .mfc-trig_cond,
    #union-factory .mfc-trig_task,
    #union-factory .mfc_chart-title,
    #union-factory .mfc_chip-key,
    #union-factory .mfc_chip-val,
    #union-factory .mfc_controls-label,
    #union-factory .mfc_empty,
    #union-factory .mfc_filter,
    #union-factory .mfc_footer,
    #union-factory .mfc_legend-item,
    #union-factory .mfc_pill-fail,
    #union-factory .mfc_pill-ok,
    #union-factory .mfc_pill-pass,
    #union-factory .mfc_play,
    #union-factory .mfc_report-config,
    #union-factory .mfc_report-status,
    #union-factory .mfc_sub,
    #union-factory .mfc_tile-delta,
    #union-factory .mfc_tile-label,
    #union-factory .mfc_verpick,
    #union-factory .mfc_verpick-label,
    #union-factory .model-factory-more_kicker,
    #union-factory .model-factory-reference_repo,
    #union-factory .proof-cell_co,
    #union-factory .text-style-tagline { font-size: 13px; }

    /* The run tabs, version picker and eval table headers size their own
       children rather than inheriting, so the container rules above miss
       them. */
    #union-factory .mfc-run_tabs > span,
    #union-factory .mfc_verpick > button { font-size: 13px; }
    #union-factory .mfc-ev_table th { font-size: 12.5px; }

    #union-factory .model-factory-code_filename,
    #union-factory .model-factory-code_pre { font-size: 12.5px; }

    /* A little more room now that the type is bigger. */
    #union-factory .mfc_tile { padding: 13px 14px; }
    #union-factory .mfc-art_row,
    #union-factory .mfc-trig_row { padding: 10px 12px; }
    #union-factory .mfc-run_tabs > span { padding: 8px 11px; }
    #union-factory .mfc_pill-ok,
    #union-factory .mfc_pill-pass,
    #union-factory .mfc_pill-fail { padding: 4px 9px; }
  }
