/* ==========================================================================
   Trinium — trinium.io
   One stylesheet. No build step, no framework, no dependencies.

   Every colour token below is lifted verbatim from ui/src/themes/theme.js so
   the website and the product read as one continuous thing. If the app's
   theme changes, change it here too.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 90px;
}

body {
  font-family: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  transition: background-color .25s ease, color .25s ease;
}

img, svg, video { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: var(--primary); color: #fff; }

/* --------------------------------------------------------------------------
   2. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* brand — identical in both modes for gradients */
  --brand-1: #6366F1;
  --brand-2: #8B5CF6;

  /* light (default) */
  --primary: #6366F1;
  --primary-light: #818CF8;
  --primary-dark: #4F46E5;
  --secondary: #8B5CF6;
  --secondary-dark: #7C3AED;

  --bg: #F7F8FA;
  --surface: #FFFFFF;
  --surface-2: #F1F3F7;
  --text: #1A1D27;
  --text-muted: #5B6172;
  --divider: #E6E8EE;

  --success: #16A34A;
  --warning: #D97706;
  --error: #DC2626;
  --info: #0EA5E9;

  /* node categories — the product's signature accents */
  --cat-input: #2563EB;
  --cat-preparation: #15803D;
  --cat-join: #EAB308;
  --cat-parse: #E11D48;
  --cat-transform: #C026D3;
  --cat-output: #0891B2;
  --cat-developer: #64748B;

  /* readable ink per category (product's readableInk(), 0.45 luminance rule) */
  --ink-input: #ffffff;
  --ink-preparation: #ffffff;
  --ink-join: #1A1D27;
  --ink-parse: #ffffff;
  --ink-transform: #ffffff;
  --ink-output: #ffffff;
  --ink-developer: #ffffff;

  --shadow-sm: 0 1px 2px 0 rgba(0,0,0,.06);
  --shadow-md: 0 2px 8px rgba(0,0,0,.08);
  --shadow-lg: 0 6px 18px rgba(0,0,0,.08);
  --shadow-xl: 0 24px 60px rgba(0,0,0,.12);

  --nav-bg: rgba(255,255,255,.82);
  --grid-dot: #D8DCE6;

  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-2xl: 28px;

  /* JetBrains Mono (Google Fonts, same request as Plus Jakarta Sans) for code, numbers and data */
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --container: 1220px;
  --gutter: clamp(20px, 5vw, 40px);

  color-scheme: light;
}

[data-theme="dark"] {
  --primary: #818CF8;
  --primary-light: #A5B0FC;
  --primary-dark: #6366F1;
  --secondary: #A78BFA;
  --secondary-dark: #8B5CF6;

  --bg: #0F1117;
  --surface: #1A1D27;
  --surface-2: #21252F;
  --text: #E6E8EE;
  --text-muted: #9CA3B4;
  --divider: #2A2E3A;

  --success: #22C55E;
  --warning: #F59E0B;
  --error: #EF4444;
  --info: #38BDF8;

  --cat-input: #60A5FA;
  --cat-preparation: #4ADE80;
  --cat-join: #FACC15;
  --cat-parse: #FB7185;
  --cat-transform: #E879F9;
  --cat-output: #22D3EE;
  --cat-developer: #94A3B8;

  --ink-input: #ffffff;
  --ink-preparation: #1A1D27;
  --ink-join: #1A1D27;
  --ink-parse: #ffffff;
  --ink-transform: #ffffff;
  --ink-output: #1A1D27;
  --ink-developer: #ffffff;

  --shadow-sm: 0 1px 2px 0 rgba(0,0,0,.3);
  --shadow-md: 0 2px 8px rgba(0,0,0,.4);
  --shadow-lg: 0 6px 18px rgba(0,0,0,.45);
  --shadow-xl: 0 24px 60px rgba(0,0,0,.6);

  --nav-bg: rgba(15,17,23,.82);
  --grid-dot: #2A2E3A;

  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5 { line-height: 1.12; letter-spacing: -.025em; font-weight: 700; }

.display {
  font-size: clamp(2.6rem, 6.2vw, 4.4rem);
  font-weight: 800;
  letter-spacing: -.038em;
  line-height: 1.02;
}

.h1 { font-size: clamp(2.2rem, 4.6vw, 3.3rem); font-weight: 800; letter-spacing: -.033em; }
.h2 { font-size: clamp(1.85rem, 3.4vw, 2.6rem); font-weight: 700; letter-spacing: -.03em; }
.h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); font-weight: 700; letter-spacing: -.02em; }
.h4 { font-size: 1.0625rem; font-weight: 700; letter-spacing: -.01em; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--primary);
  margin-bottom: 18px;
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: .55;
}

.lead {
  font-size: clamp(1.06rem, 1.55vw, 1.28rem);
  line-height: 1.6;
  color: var(--text-muted);
}
/* A display headline sets at line-height 1.02, so a paragraph straight under it collides with
   its descenders. Every hero on the site has that pair, so the gap is defined once here. */
.display + .lead { margin-top: clamp(18px, 2.2vw, 26px); }

.muted { color: var(--text-muted); }
.small { font-size: .875rem; line-height: 1.6; }
.tiny { font-size: .78rem; line-height: 1.55; }

.mono {
  font-family: var(--font-mono);
  font-size: .92em;
  letter-spacing: -.01em;
}

.grad-text {
  background: linear-gradient(100deg, var(--brand-1), var(--brand-2) 65%, #A78BFA);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.balance { text-wrap: balance; }
.pretty  { text-wrap: pretty; }

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container-narrow { max-width: 860px; }
.container-mid { max-width: 1020px; }

.section { padding-block: clamp(72px, 9vw, 128px); }
.section-tight { padding-block: clamp(52px, 6vw, 82px); }

.section-head { max-width: 760px; margin-bottom: clamp(40px, 5vw, 64px); }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head .h2 + p { margin-top: 18px; }

.rule { height: 1px; background: var(--divider); border: 0; }

.grid { display: grid; gap: 24px; }
.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
}
.split.reverse > :first-child { order: 2; }

.stack-sm > * + * { margin-top: 10px; }
.stack   > * + * { margin-top: 18px; }
.stack-lg > * + * { margin-top: 30px; }

.center { text-align: center; }
.flex { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.flex-center { justify-content: center; }


/* --------------------------------------------------------------------------
   5. Navigation
   -------------------------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--nav-bg);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease, background-color .25s ease;
}
.nav.scrolled { border-bottom-color: var(--divider); }

.nav-inner {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 66px;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  margin-right: 14px;
  flex-shrink: 0;
}
.brand svg { width: 26px; height: 26px; }
.brand-word {
  font-size: 1.28rem;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--primary);
}
/* The product name reads larger in the top bar than in the footer. The bar's own height
   (.nav-inner, 66px) is unchanged — the mark simply uses more of it. */
.nav .brand { gap: 11px; }
.nav .brand svg { width: 34px; height: 34px; }
.nav .brand-word { font-size: 1.7rem; letter-spacing: -.03em; line-height: 1; }

.nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
}
.nav-links a {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding-inline: 13px;
  border-radius: var(--r-lg);
  font-size: .9rem;
  font-weight: 600;
  color: var(--text-muted);
  text-decoration: none;
  transition: color .16s ease, background-color .16s ease;
  white-space: nowrap;
}
.nav-links a:hover { color: var(--text); background: var(--surface-2); }
.nav-links a[aria-current="page"] { color: var(--primary); background: color-mix(in srgb, var(--primary) 11%, transparent); }

.nav-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.icon-btn {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--r-lg);
  color: var(--text-muted);
  transition: color .16s ease, background-color .16s ease;
}
.icon-btn:hover { color: var(--text); background: var(--surface-2); }
.icon-btn svg { width: 19px; height: 19px; }

.theme-toggle .moon { display: none; }
[data-theme="dark"] .theme-toggle .sun { display: none; }
[data-theme="dark"] .theme-toggle .moon { display: block; }

.nav-toggle { display: none; }

.mobile-menu {
  display: none;
  border-top: 1px solid var(--divider);
  background: var(--surface);
  padding: 12px var(--gutter) 20px;
}
.mobile-menu.open { display: block; }
.mobile-menu a {
  display: block;
  padding: 11px 0;
  font-weight: 600;
  text-decoration: none;
  color: var(--text);
  border-bottom: 1px solid var(--divider);
}
.mobile-menu a[aria-current="page"]:not(.btn) { color: var(--primary); }
.mobile-menu .btn { margin-top: 16px; width: 100%; justify-content: center; }

/* --------------------------------------------------------------------------
   6. Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 46px;
  padding-inline: 22px;
  border-radius: var(--r-md);
  font-size: .945rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  border: 1.5px solid transparent;
  transition: transform .16s ease, box-shadow .16s ease, background-color .16s ease,
              border-color .16s ease, color .16s ease;
}
.btn svg { width: 17px; height: 17px; flex-shrink: 0; }

.btn-primary {
  background: linear-gradient(135deg, var(--brand-1), var(--secondary-dark));
  color: #fff;
  box-shadow: 0 6px 20px -6px rgba(99,102,241,.55);
}
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 12px 28px -8px rgba(99,102,241,.65); }

.btn-secondary {
  background: var(--surface);
  color: var(--text);
  border-color: var(--divider);
  box-shadow: var(--shadow-sm);
}
.btn-secondary:hover { border-color: var(--primary); color: var(--primary); transform: translateY(-1px); }

.btn-ghost { color: var(--text-muted); padding-inline: 14px; }
.btn-ghost:hover { color: var(--primary); }

.btn-lg { height: 52px; padding-inline: 28px; font-size: 1rem; }
.btn-sm { height: 38px; padding-inline: 16px; font-size: .875rem; }

.btn-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
  font-size: .945rem;
}
.btn-link svg { width: 15px; height: 15px; transition: transform .18s ease; }
.btn-link:hover svg { transform: translateX(3px); }

/* on the always-dark bands */
.band-dark .btn-secondary {
  background: rgba(255,255,255,.06);
  border-color: rgba(255,255,255,.16);
  color: #E6E8EE;
  box-shadow: none;
}
.band-dark .btn-secondary:hover { background: rgba(255,255,255,.11); border-color: rgba(255,255,255,.3); color: #fff; }

/* --------------------------------------------------------------------------
   7. The always-dark aurora band (from the product's login screen)
   -------------------------------------------------------------------------- */
.band-dark {
  position: relative;
  isolation: isolate;
  background: #0B0D14;
  color: #E6E8EE;
  overflow: hidden;
  --text: #E6E8EE;
  --text-muted: #9CA3B4;
  --divider: rgba(255,255,255,.11);
  --surface: rgba(255,255,255,.04);
}
.band-dark .eyebrow { color: var(--primary-light); }
.band-dark h1, .band-dark h2, .band-dark h3, .band-dark .display { color: #fff; }

.aurora { position: absolute; inset: -20% -10%; z-index: -2; pointer-events: none; }
.aurora i {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .55;
  will-change: transform;
}
.aurora i:nth-child(1) {
  width: 46vw; height: 46vw; min-width: 380px; min-height: 380px;
  top: -6%; left: 2%;
  background: rgba(99,102,241,.40);
  animation: drift1 28s ease-in-out infinite alternate;
}
.aurora i:nth-child(2) {
  width: 40vw; height: 40vw; min-width: 320px; min-height: 320px;
  top: 12%; right: -4%;
  background: rgba(139,92,246,.35);
  animation: drift2 34s ease-in-out infinite alternate;
}
.aurora i:nth-child(3) {
  width: 36vw; height: 36vw; min-width: 300px; min-height: 300px;
  bottom: -18%; left: 32%;
  background: rgba(79,70,229,.30);
  animation: drift3 40s ease-in-out infinite alternate;
}

@keyframes drift1 { to { transform: translate3d(9%, 7%, 0) scale(1.14); } }
@keyframes drift2 { to { transform: translate3d(-11%, 9%, 0) scale(1.1); } }
@keyframes drift3 { to { transform: translate3d(7%, -10%, 0) scale(1.16); } }

/* film grain — kills gradient banding, exactly as the app does it */
.grain {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

.vignette {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 52%, rgba(0,0,0,.55) 100%);
}

/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */
.hero { padding-block: clamp(76px, 10vw, 132px) clamp(64px, 8vw, 104px); }
.hero-cta { margin-top: 34px; }

.page-hero { padding-block: clamp(64px, 8vw, 104px) clamp(56px, 7vw, 88px); }
.page-hero .display { max-width: 15ch; }
.page-hero.center .display, .page-hero.center .lead { margin-inline: auto; }
.page-hero .lead { color: #A9B0C4; max-width: 640px; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 32px;
  padding-inline: 6px 15px;
  border-radius: 999px;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.13);
  font-size: .8rem;
  font-weight: 600;
  color: #C3C9DA;
  margin-bottom: 26px;
  text-decoration: none;
  transition: border-color .18s ease, background-color .18s ease;
}
.pill:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.24); }
.pill b {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding-inline: 9px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--brand-1), var(--secondary-dark));
  color: #fff;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   9. Cards
   -------------------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r-xl);
  padding: 28px;
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.card-hover:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--divider));
  box-shadow: var(--shadow-lg);
  transform: translateY(-2px);
}
a.card { text-decoration: none; display: block; }
.card .h3 { margin-bottom: 10px; }
.card p { color: var(--text-muted); font-size: .945rem; }

.card-icon {
  width: 42px;
  height: 42px;
  border-radius: var(--r-md);
  display: grid;
  place-items: center;
  margin-bottom: 18px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
}
.card-icon svg { width: 21px; height: 21px; stroke-width: 1.9; }

.band-dark .card {
  background: rgba(255,255,255,.035);
  border-color: rgba(255,255,255,.1);
  backdrop-filter: blur(10px);
}


/* a bordered feature row */
.feature-row {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}
.feature-row .dot {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  background: color-mix(in srgb, var(--primary) 13%, transparent);
  color: var(--primary);
  margin-top: 2px;
}
.feature-row .dot svg { width: 15px; height: 15px; stroke-width: 2.4; }
.feature-row h4 { margin-bottom: 3px; }
.feature-row p { color: var(--text-muted); font-size: .93rem; }

/* --------------------------------------------------------------------------
   10. The builder canvas replica
   -------------------------------------------------------------------------- */
.canvas {
  position: relative;
  border-radius: var(--r-xl);
  border: 1px solid var(--divider);
  background:
    radial-gradient(circle, var(--grid-dot) 1.5px, transparent 1.5px) 0 0 / 18px 18px,
    var(--bg);
  overflow: hidden;
  box-shadow: var(--shadow-xl);
}
.band-dark .canvas {
  border-color: rgba(255,255,255,.12);
  --grid-dot: rgba(255,255,255,.09);
  background:
    radial-gradient(circle, var(--grid-dot) 1.5px, transparent 1.5px) 0 0 / 18px 18px,
    #0F1117;
}

.canvas-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 42px;
  padding-inline: 14px;
  border-bottom: 1px solid var(--divider);
  background: var(--surface);
  font-size: .78rem;
  color: var(--text-muted);
  font-weight: 600;
}
.band-dark .canvas-bar { background: rgba(255,255,255,.04); border-bottom-color: rgba(255,255,255,.1); }
.canvas-bar .dots { display: flex; gap: 6px; margin-right: 6px; }
.canvas-bar .dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--divider); }
.canvas-bar .live {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--success);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.canvas-bar .live::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 25%, transparent);
}

.canvas-stage {
  position: relative;
  padding: 26px;
  min-height: 360px;
}
.canvas-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.canvas-edges path {
  fill: none;
  stroke: var(--divider);
  stroke-width: 2;
  stroke-linecap: round;
}
.band-dark .canvas-edges path { stroke: rgba(255,255,255,.16); }
.canvas-edges path.hot {
  stroke: var(--primary);
  stroke-dasharray: 7 9;
  animation: dash 1.1s linear infinite;
}
@keyframes dash { to { stroke-dashoffset: -32px; } }

/* the node card — a faithful copy of ui/src/components/flow/CanvasNode.jsx */
.node {
  position: relative;
  width: 208px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: var(--r-xl);
  background: var(--surface);
  border: 1.5px solid var(--divider);
  box-shadow: var(--shadow-md);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.band-dark .node { background: #1A1D27; border-color: rgba(255,255,255,.13); }
.node.is-selected { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(99,102,241,.22), var(--shadow-lg); }
.node.is-done { border-color: color-mix(in srgb, var(--success) 55%, var(--divider)); }

.node-body { min-width: 0; }
.node-label {
  font-size: .875rem;
  font-weight: 700;
  letter-spacing: -.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text);
}
.band-dark .node-label { color: #E6E8EE; }
.node-sub {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: .75rem;
  color: var(--text-muted);
}
.node-sub i { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }

/* the 42px gradient icon tile */
.tile {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: var(--r-lg);
  display: grid;
  place-items: center;
  position: relative;
}
.tile svg { width: 24px; height: 24px; }
.tile[data-cat] { background: linear-gradient(140deg, var(--c-90), var(--c)); box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 2px 6px var(--c-45); color: var(--ink); }
.tile.sm { width: 34px; height: 34px; border-radius: var(--r-md); }
.tile.sm svg { width: 19px; height: 19px; }
.tile.lg { width: 52px; height: 52px; border-radius: 18px; }
.tile.lg svg { width: 29px; height: 29px; }

/* soft variant — used in the gallery so 82 saturated tiles aren't a shout */
.tile.soft { background: var(--c-12); border: 1px solid var(--c-28); box-shadow: none; color: var(--c); }

/* stroked (Tabler) vs filled (Simple Icons) artwork */
.tile svg[data-t="s"] { fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.tile svg[data-t="f"] { fill: currentColor; stroke: none; }

/* category colour resolution — one attribute drives fill, shadow and ink */
[data-cat="Input"]        { --c: var(--cat-input);        --ink: var(--ink-input);        --c-90: color-mix(in srgb, var(--cat-input) 92%, transparent);        --c-45: color-mix(in srgb, var(--cat-input) 45%, transparent);        --c-12: color-mix(in srgb, var(--cat-input) 12%, transparent);        --c-28: color-mix(in srgb, var(--cat-input) 28%, transparent); }
[data-cat="Preparation"]  { --c: var(--cat-preparation);  --ink: var(--ink-preparation);  --c-90: color-mix(in srgb, var(--cat-preparation) 92%, transparent);  --c-45: color-mix(in srgb, var(--cat-preparation) 45%, transparent);  --c-12: color-mix(in srgb, var(--cat-preparation) 12%, transparent);  --c-28: color-mix(in srgb, var(--cat-preparation) 28%, transparent); }
[data-cat="Join"]         { --c: var(--cat-join);         --ink: var(--ink-join);         --c-90: color-mix(in srgb, var(--cat-join) 92%, transparent);         --c-45: color-mix(in srgb, var(--cat-join) 45%, transparent);         --c-12: color-mix(in srgb, var(--cat-join) 12%, transparent);         --c-28: color-mix(in srgb, var(--cat-join) 28%, transparent); }
[data-cat="Parse"]        { --c: var(--cat-parse);        --ink: var(--ink-parse);        --c-90: color-mix(in srgb, var(--cat-parse) 92%, transparent);        --c-45: color-mix(in srgb, var(--cat-parse) 45%, transparent);        --c-12: color-mix(in srgb, var(--cat-parse) 12%, transparent);        --c-28: color-mix(in srgb, var(--cat-parse) 28%, transparent); }
[data-cat="Transform"]    { --c: var(--cat-transform);    --ink: var(--ink-transform);    --c-90: color-mix(in srgb, var(--cat-transform) 92%, transparent);    --c-45: color-mix(in srgb, var(--cat-transform) 45%, transparent);    --c-12: color-mix(in srgb, var(--cat-transform) 12%, transparent);    --c-28: color-mix(in srgb, var(--cat-transform) 28%, transparent); }
[data-cat="Output"]       { --c: var(--cat-output);       --ink: var(--ink-output);       --c-90: color-mix(in srgb, var(--cat-output) 92%, transparent);       --c-45: color-mix(in srgb, var(--cat-output) 45%, transparent);       --c-12: color-mix(in srgb, var(--cat-output) 12%, transparent);       --c-28: color-mix(in srgb, var(--cat-output) 28%, transparent); }
[data-cat="Developer"]    { --c: var(--cat-developer);    --ink: var(--ink-developer);    --c-90: color-mix(in srgb, var(--cat-developer) 92%, transparent);    --c-45: color-mix(in srgb, var(--cat-developer) 45%, transparent);    --c-12: color-mix(in srgb, var(--cat-developer) 12%, transparent);    --c-28: color-mix(in srgb, var(--cat-developer) 28%, transparent); }

/* ports */
.port {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--surface);
  border: 2.5px solid var(--c, var(--divider));
  top: 50%;
  transform: translateY(-50%);
}
.band-dark .port { background: #1A1D27; }
.port.in  { left: -6px; }
.port.out { right: -6px; }
.port.p1 { top: 33%; }
.port.p2 { top: 67%; }

/* run status badge */
.node-status {
  position: absolute;
  top: -7px;
  right: -7px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 2px solid var(--surface);
  background: var(--text-muted);
  color: #fff;
  opacity: 0;
  transform: scale(.5);
  transition: opacity .28s ease, transform .28s cubic-bezier(.34,1.56,.64,1), background-color .28s ease;
}
.band-dark .node-status { border-color: #1A1D27; }
.node-status svg { width: 12px; height: 12px; stroke-width: 3; }
.node.is-running .node-status { opacity: 1; transform: scale(1); background: var(--primary); }
.node.is-done .node-status { opacity: 1; transform: scale(1); background: var(--success); }

/* the enterprise padlock, exactly as the product renders it */
.node-lock {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--secondary);
  color: #fff;
  display: grid;
  place-items: center;
}
.node-lock svg { width: 11px; height: 11px; stroke-width: 2.6; fill: none; stroke: currentColor; }

/* the row counter that ticks during the demo run */
.node-rows {
  position: absolute;
  bottom: -9px;
  left: 12px;
  height: 19px;
  padding-inline: 7px;
  border-radius: 6px;
  background: var(--surface);
  border: 1px solid var(--divider);
  font-size: .66rem;
  font-weight: 700;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity .3s ease;
}
.band-dark .node-rows { background: #1A1D27; border-color: rgba(255,255,255,.14); }
.node.is-done .node-rows, .node.is-running .node-rows { opacity: 1; }

/* absolute placement inside the stage */
.canvas-stage .node { position: absolute; }

/* extra port positions — the product distributes n ports at (i+1)/(n+1) */
.port.of2-1 { top: 33.33%; }
.port.of2-2 { top: 66.66%; }
.port.of3-1 { top: 25%; }
.port.of3-2 { top: 50%; }
.port.of3-3 { top: 75%; }

/* The demo canvas is drawn at a fixed 1080x318 so the SVG edges land exactly on
   the ports, then scaled down as one piece. Below 760px it becomes a stack. */
.canvas-fit { position: relative; overflow: hidden; height: 318px; }
.canvas-fit .canvas-stage {
  width: 1080px;
  height: 318px;
  min-height: 0;
  padding: 0;
  transform-origin: top left;
  transform: scale(var(--s, 1));
}

@media (max-width: 1219px) { .canvas-fit { height: 275px; } .canvas-fit .canvas-stage { --s: .865; } }
@media (max-width: 1080px) { .canvas-fit { height: 245px; } .canvas-fit .canvas-stage { --s: .77; } }
@media (max-width: 950px)  { .canvas-fit { height: 212px; } .canvas-fit .canvas-stage { --s: .666; } }
@media (max-width: 850px)  { .canvas-fit { height: 188px; } .canvas-fit .canvas-stage { --s: .59; } }

@media (max-width: 760px) {
  .canvas-fit { height: auto; }
  .canvas-fit .canvas-stage {
    width: 100%;
    height: auto;
    transform: none;
    padding: 22px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 22px;
  }
  .canvas-fit .canvas-stage .node {
    position: relative !important;
    left: auto !important;
    top: auto !important;
    width: 100%;
    max-width: 260px;
  }
  /* a short vertical connector between the stacked cards */
  .canvas-fit .canvas-stage .node:not(:last-child)::after {
    content: "";
    position: absolute;
    bottom: -22px;
    left: 50%;
    width: 2px;
    height: 22px;
    background: var(--divider);
  }
  .canvas-fit .canvas-edges { display: none; }
  .canvas-fit .port { display: none; }
}

/* --------------------------------------------------------------------------
   11. Node gallery
   -------------------------------------------------------------------------- */
.gallery-controls {
  position: sticky;
  top: 66px;
  z-index: 40;
  /* the gallery section is painted --surface, so --bg here showed as a mismatched strip
     the moment the bar stuck */
  background: var(--surface);
  padding-block: 18px;
  border-bottom: 1px solid var(--divider);
  margin-bottom: 34px;
}

.search-box { position: relative; margin-bottom: 14px; }
.search-box svg {
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px; height: 18px;
  color: var(--text-muted);
  pointer-events: none;
}
.search-box input {
  width: 100%;
  height: 50px;
  padding: 0 46px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--divider);
  background: var(--surface);
  font-size: .97rem;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.search-box input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
}
.search-box input::placeholder { color: var(--text-muted); }
.search-clear {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 26px; height: 26px;
  border-radius: 50%;
  display: none;
  place-items: center;
  color: var(--text-muted);
}
.search-clear.show { display: grid; }

.hero-links { gap: 26px; flex-wrap: wrap; margin-top: 22px; }

/* Use cases: who each scenario is for, on its contents card. Together the seven name all five
   audiences from Home's "Who it's for" (usecases.html, docs/BACKLOG.md §91l). */
.uc-for {
  display: block;
  margin-top: 10px;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--primary);
}

/* The Nodes & Connectors hero: read from → shape → write to, as a picture (nodes.html). The
   lines meet the cards because every column spreads equal-height items with space-around, so
   item i of n sits at (i + 0.5) / n of the column; the paths in the markup use those fractions.
   Each gap's SVG is stretched to its cell (preserveAspectRatio none), so the stroke must not
   scale with it, and the junction is an HTML dot because an SVG circle would stretch too. */
.split.hx { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); }
.hx-map { margin: 0; }
.hx-grid {
  display: grid;
  grid-template-columns: auto minmax(28px, 1fr) minmax(0, 200px) minmax(28px, 1fr) auto;
  grid-template-rows: 300px auto;
  row-gap: 16px;
}
.hx-col { display: flex; flex-direction: column; justify-content: space-around; min-width: 0; }
.hx-gap { position: relative; }
.hx .canvas-edges path { vector-effect: non-scaling-stroke; }
.hx-dot {
  position: absolute;
  left: 50%; top: 50%;
  width: 9px; height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--edge);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--edge) 22%, transparent), 0 0 16px var(--edge);
}
.hx-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  height: 44px;
  padding: 0 12px 0 11px;
  border-radius: var(--r-lg);
  background: #1A1D27;
  border: 1.5px solid rgba(255,255,255,.13);
  box-shadow: var(--shadow-md);
  color: #E6E8EE;
  font-size: .82rem;
  font-weight: 600;
  white-space: nowrap;
}
.hx-chip img { width: 22px; height: 22px; object-fit: contain; flex-shrink: 0; }
.hx-chip span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.hx .node { width: auto; padding: 9px 10px; }
.hx-label {
  grid-row: 2;
  justify-self: center;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #8E96AB;
}
/* Side by side only where all three columns fit their names; below that the picture sits
   under the text, as every split does at 900px. */
@media (max-width: 1180px) {
  .split.hx { grid-template-columns: minmax(0, 1fr); }
  .hx-map { max-width: 640px; }
}
/* Phones: the logos carry the connectors (the figure's label names them), the node cards keep
   their names, and the gaps take what is left. */
@media (max-width: 600px) {
  .hx-grid { grid-template-columns: 44px minmax(20px, 1fr) minmax(0, 168px) minmax(20px, 1fr) 44px; grid-template-rows: 256px auto; }
  .hx-chip { justify-content: center; padding: 0; }
  .hx-chip span { display: none; }
  .hx .node { padding: 7px 8px; gap: 8px; }
  .hx .node-label { font-size: .8rem; }
  .hx .node-sub { font-size: .7rem; }
}

/* Highlights: the product's own icon beside the node's name. */
.hl-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.hl-head .h4 { margin: 0; }
.search-clear:hover { background: var(--surface-2); color: var(--text); }

.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding-inline: 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--divider);
  background: var(--surface);
  font-size: .84rem;
  font-weight: 600;
  color: var(--text-muted);
  transition: all .16s ease;
}
.chip i { width: 9px; height: 9px; border-radius: 50%; background: var(--c, var(--text-muted)); }
.chip:hover { color: var(--text); border-color: color-mix(in srgb, var(--c, var(--primary)) 45%, var(--divider)); }
.chip[aria-pressed="true"] {
  background: var(--c-12, color-mix(in srgb, var(--primary) 12%, transparent));
  border-color: var(--c-28, color-mix(in srgb, var(--primary) 40%, transparent));
  color: var(--c, var(--primary));
  font-weight: 700;
}
.chip .n { opacity: .6; font-variant-numeric: tabular-nums; }

.node-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: 14px;
}

/* One section per category, generated by scripts/website/nodes.mjs. The heading is what
   made the flat 91-card wall legible, and it carries the anchor other pages link to. */
.node-cat + .node-cat { margin-top: 38px; }
/* clears both sticky bars — the 66px nav and the search/chips bar under it */
.node-cat { scroll-margin-top: 210px; }
.node-cat h3 {
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--c, var(--text-muted));
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.node-cat h3::after { content: ""; flex: 1; height: 1px; background: var(--divider); }
.node-cat h3 .n {
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* The filter hides cards rather than rebuilding them, and `.gnode`'s own display wins
   over the user-agent [hidden] rule. */
.gnode[hidden], .node-cat[hidden] { display: none; }

.gnode {
  display: flex;
  gap: 13px;
  padding: 15px;
  border-radius: var(--r-lg);
  border: 1px solid var(--divider);
  background: var(--surface);
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.gnode:hover {
  border-color: color-mix(in srgb, var(--c) 50%, var(--divider));
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.gnode .tile { position: relative; }
.gnode-body { min-width: 0; }
.gnode-title {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: .93rem;
  font-weight: 700;
  letter-spacing: -.01em;
  margin-bottom: 4px;
}
.gnode-desc { font-size: .82rem; line-height: 1.5; color: var(--text-muted); }

/* The tier badge is gone (owner, 2026-09-11) — editions are explained on the pricing page and
   nowhere else. What is left is the neutral chip the gallery puts on the two canvas annotations. */
.badge-soft {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding-inline: 7px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--text-muted) 14%, transparent);
  color: var(--text-muted);
  font-size: .63rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  flex-shrink: 0;
}

.no-results { padding: 60px 20px; text-align: center; color: var(--text-muted); }

/* connector wall */
.conn-group + .conn-group { margin-top: 34px; }
.conn-group h3 {
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--text-muted);
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.conn-group h3::after { content: ""; flex: 1; height: 1px; background: var(--divider); }

.conn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(158px, 1fr)); gap: 12px; }
.conn {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--divider);
  background: var(--surface);
  font-size: .87rem;
  font-weight: 600;
  transition: border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.conn:hover { border-color: var(--primary); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.conn img {
  width: 24px;
  height: 24px;
  object-fit: contain;
  filter: grayscale(1);
  opacity: .72;
  transition: filter .2s ease, opacity .2s ease;
}
.conn:hover img { filter: none; opacity: 1; }
[data-theme="dark"] .conn img { filter: grayscale(1) brightness(1.7); }
[data-theme="dark"] .conn:hover img { filter: brightness(1.15); }

/* --------------------------------------------------------------------------
   12. Tables
   -------------------------------------------------------------------------- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--divider);
  border-radius: var(--r-xl);
  background: var(--surface);
  -webkit-overflow-scrolling: touch;
}

table.matrix {
  width: 100%;
  min-width: 720px;
  border-collapse: collapse;
  font-size: .93rem;
}
table.matrix th, table.matrix td {
  padding: 15px 20px;
  text-align: left;
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}
table.matrix thead th {
  position: sticky;
  top: 0;
  background: var(--surface);
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-muted);
  z-index: 2;
}
table.matrix tbody tr:last-child td { border-bottom: 0; }
table.matrix tbody tr:hover td { background: var(--surface-2); }
table.matrix td:not(:first-child), table.matrix th:not(:first-child) { text-align: center; width: 168px; }
table.matrix .rowhead { font-weight: 600; }
table.matrix .rowhead small { display: block; font-weight: 400; color: var(--text-muted); font-size: .82rem; margin-top: 3px; }

table.matrix .group td {
  background: var(--surface-2);
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--text-muted);
  padding-block: 10px;
}
table.matrix .group td:hover { background: var(--surface-2); }

/* Keep the row label visible while the table scrolls sideways on a phone. */
table.matrix td:first-child,
table.matrix th:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
}
table.matrix thead th:first-child { z-index: 3; }
table.matrix .group td:first-child { background: var(--surface-2); }
table.matrix tbody tr:hover td:first-child { background: var(--surface-2); }

.yes, .no {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
}
.yes { background: color-mix(in srgb, var(--success) 15%, transparent); color: var(--success); }
.no  { color: var(--text-muted); opacity: .4; }
.yes svg, .no svg { width: 13px; height: 13px; stroke-width: 3; fill: none; stroke: currentColor; }

.cell-note { font-size: .84rem; font-weight: 600; color: var(--text-muted); }
.cell-note.on { color: var(--success); }

/* comparison table */
table.compare { width: 100%; min-width: 780px; border-collapse: collapse; font-size: .93rem; }
table.compare th, table.compare td {
  padding: 18px 20px;
  text-align: left;
  border-bottom: 1px solid var(--divider);
  vertical-align: top;
}
table.compare thead th {
  font-size: .78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-muted);
}
table.compare thead th:nth-child(2) { color: var(--primary); }
table.compare td:first-child { font-weight: 600; width: 200px; }
table.compare td:nth-child(2) {
  background: color-mix(in srgb, var(--primary) 5%, transparent);
  font-weight: 600;
}
table.compare tbody tr:last-child td { border-bottom: 0; }

/* grouped section rows, and a sticky label column for narrow screens */
table.compare .group td {
  background: var(--surface-2);
  font-size: .73rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--text-muted);
  padding-block: 9px;
}
table.compare td:first-child,
table.compare th:first-child { position: sticky; left: 0; z-index: 1; background: var(--surface); }
table.compare thead th:first-child { z-index: 3; }
table.compare .group td:first-child { background: var(--surface-2); }

/* the at-a-glance variant: short cells, tighter rows */
table.compare.glance { min-width: 840px; }
table.compare.glance th,
table.compare.glance td { padding: 13px 18px; }
table.compare.glance td { font-size: .89rem; line-height: 1.45; }
table.compare.glance td:first-child { width: 210px; }
table.compare.glance td:nth-child(2) { color: var(--text); }
table.compare.glance .yes,
table.compare.glance .no { vertical-align: middle; }

/* --------------------------------------------------------------------------
   13. Pricing
   -------------------------------------------------------------------------- */
.plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  align-items: start;
}

.plan {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r-2xl);
  padding: 30px;
  display: flex;
  flex-direction: column;
  height: 100%;
}
.plan-featured {
  border-color: transparent;
  box-shadow: 0 0 0 2px var(--primary), var(--shadow-xl);
  transform: scale(1.025);
  z-index: 1;
}
@media (max-width: 900px) { .plan-featured { transform: none; } }

.plan-tag {
  position: absolute;
  top: -13px;
  left: 50%;
  transform: translateX(-50%);
  height: 26px;
  padding-inline: 14px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--brand-1), var(--secondary-dark));
  color: #fff;
  font-size: .69rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

.plan-name { font-size: 1.15rem; font-weight: 700; letter-spacing: -.02em; }
.plan-blurb { font-size: .9rem; color: var(--text-muted); margin-top: 6px; min-height: 44px; }
.plan-price { margin: 22px 0 4px; display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
.plan-price .amt { font-size: 2.7rem; font-weight: 800; letter-spacing: -.04em; line-height: 1; }
.plan-price .per { font-size: .92rem; color: var(--text-muted); font-weight: 600; }
.plan-price .from { font-size: .92rem; color: var(--text-muted); font-weight: 600; align-self: center; }
.plan-unit { font-size: .82rem; color: var(--text-muted); min-height: 20px; }
.plan .btn { margin: 24px 0 22px; width: 100%; }

/* Plan feature list — every item is the same two-part shape: a bold lead term the
   eye can scan, with the detail demoted beneath it. One item = one idea. */
.plan ul { list-style: none; padding: 0; display: grid; gap: 15px; }
.plan li { display: flex; gap: 10px; line-height: 1.5; align-items: flex-start; }
.plan li svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 3px; color: var(--success); stroke-width: 2.6; fill: none; stroke: currentColor; }
.plan li > div { display: grid; gap: 3px; min-width: 0; }
.plan li b { display: block; font-size: .905rem; font-weight: 700; letter-spacing: -.01em; }
.plan li span { font-size: .81rem; line-height: 1.5; color: var(--text-muted); }
.plan-sep {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .11em;
  color: var(--text-muted);
  padding-top: 6px;
}

/* Pricing, 2026-09-29: two editions under one trial band, and the rate evidence behind a
   disclosure under the calculator (docs/BACKLOG.md §92). */
.plans.two { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 940px; margin-inline: auto; gap: 26px; }
.trial-band {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: 940px;
  margin: 0 auto 30px;
  padding: 16px 22px;
  border-radius: var(--r-lg);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--divider));
  background: var(--surface);
  box-shadow: var(--shadow-md);
  font-size: .95rem;
  color: var(--text-muted);
}
.trial-band b { color: var(--text); }
.trial-band svg {
  width: 22px; height: 22px; flex-shrink: 0;
  color: var(--primary);
  fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   14. Code / terminal
   -------------------------------------------------------------------------- */
.terminal {
  border-radius: var(--r-lg);
  border: 1px solid var(--divider);
  background: #0F1117;
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}
.terminal-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 38px;
  padding-inline: 14px;
  background: rgba(255,255,255,.04);
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.terminal-bar i { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,.16); }
.terminal-bar span {
  margin-left: 8px;
  font-size: .74rem;
  font-weight: 600;
  color: #6B7383;
  letter-spacing: .04em;
}
.terminal-bar .copy { margin-left: auto; color: #8E96AB; }
.terminal-bar .copy:hover { color: #fff; }
.terminal-bar .copy svg { width: 15px; height: 15px; }

.terminal pre {
  margin: 0;
  padding: 20px;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: .84rem;
  line-height: 1.8;
  color: #C3C9DA;
}
.terminal .c { color: #6B7383; }
.terminal .p { color: var(--brand-2); user-select: none; }
.terminal .k { color: #7DD3FC; }
.terminal .s { color: #86EFAC; }

code.inline {
  font-family: var(--font-mono);
  font-size: .86em;
  padding: .12em .42em;
  border-radius: 5px;
  background: var(--surface-2);
  border: 1px solid var(--divider);
  white-space: nowrap;
}
.band-dark code.inline { background: rgba(255,255,255,.07); border-color: rgba(255,255,255,.12); }

/* an expression / schema panel mock */
.panel {
  border-radius: var(--r-lg);
  border: 1px solid var(--divider);
  background: var(--surface);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
.panel-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 15px;
  border-bottom: 1px solid var(--divider);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface-2);
}
.panel-body { padding: 15px; }

.schema-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: .84rem;
  border-bottom: 1px solid var(--divider);
}
.schema-row:last-child { border-bottom: 0; }
.schema-row .nm { font-weight: 600; }
.schema-row .ty {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: .74rem;
  color: var(--text-muted);
  padding: 2px 7px;
  border-radius: 5px;
  background: var(--surface-2);
  border: 1px solid var(--divider);
}
.schema-row .ic { width: 15px; height: 15px; color: var(--text-muted); flex-shrink: 0; }

/* --------------------------------------------------------------------------
   15. Misc components
   -------------------------------------------------------------------------- */

/* The licensing band — the four things Trinium does not charge for. */
.nots {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 18px;
}
.not {
  position: relative;
  padding: 24px 22px 22px;
  border: 1px solid var(--divider);
  border-radius: var(--r-lg);
  background: var(--bg);
}
.not-x {
  display: inline-block;
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--error);
  margin-bottom: 10px;
}
.not b {
  display: block;
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -.01em;
  margin-bottom: 7px;
}
.not span:not(.not-x) {
  display: block;
  font-size: .9rem;
  line-height: 1.55;
  color: var(--text-muted);
}

/* The Pro→Enterprise crossover ladder. The arithmetic IS the argument, so the
   fifth rung is marked and the rest are deliberately plain. */
.ladder {
  display: grid;
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 52px);
  align-items: center;
  padding: clamp(26px, 3.4vw, 40px);
  border: 1px solid var(--divider);
  border-radius: var(--r-xl);
  background: var(--surface);
}
.ladder-steps { list-style: none; display: grid; gap: 8px; }
.ladder-steps li {
  display: grid;
  grid-template-columns: 6.5rem 6rem minmax(0, 1fr);
  align-items: baseline;
  gap: 14px;
  padding: 13px 18px;
  border-radius: var(--r-md);
  background: var(--bg);
  border: 1px solid transparent;
}
.ladder-steps b { font-weight: 700; font-size: .95rem; }
.ladder-steps span { font-weight: 800; font-size: 1.08rem; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ladder-steps i { font-style: normal; font-size: .87rem; color: var(--text-muted); }
.ladder-steps .is-cross {
  border-color: color-mix(in srgb, var(--primary) 45%, transparent);
  background: color-mix(in srgb, var(--primary) 8%, var(--surface));
}
.ladder-steps .is-cross span { color: var(--primary); }
.ladder-steps .is-cross i { color: var(--text); font-weight: 600; }

/* The TCO calculator on the pricing page. */
.calc { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 38px; align-items: start; }
.calc-control { padding: 26px; border: 1px solid var(--divider); border-radius: var(--r-xl); background: var(--surface); }
.calc-control label { display: block; font-weight: 700; font-size: .95rem; margin-bottom: 4px; }
.calc-count { font-size: 3rem; font-weight: 800; letter-spacing: -.03em; line-height: 1.05; color: var(--primary); }
.calc-count small { display: block; font-size: .87rem; font-weight: 500; color: var(--text-muted); letter-spacing: 0; margin-top: 2px; }
.calc-control input[type="range"] { width: 100%; margin: 20px 0 4px; accent-color: var(--primary); height: 22px; }
.calc-scale { display: flex; justify-content: space-between; font-size: .78rem; color: var(--text-muted); }
.calc-check {
  display: flex !important;
  align-items: center;
  gap: 10px;
  margin-top: 24px;
  padding: 12px 14px;
  border-radius: var(--r-md);
  background: var(--surface-2);
  font-size: .9rem !important;
  font-weight: 600;
  cursor: pointer;
}
.calc-check input { width: 18px; height: 18px; accent-color: var(--primary); flex-shrink: 0; }

/* Two sides, one comparison. Whichever side is cheaper at the current setting is green and the
   other is red — computed live, so at one or two builders the page shows the per-seat tool
   winning, which is the truth. Both bars share one scale. */
.calc-sides { display: grid; gap: 12px; }
.calc-side {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 6px 18px;
  padding: 20px 22px;
  border: 1.5px solid var(--divider);
  border-radius: var(--r-lg);
  background: var(--surface);
  --tone: var(--text-muted);
  transition: border-color .25s ease, background-color .25s ease;
}
.calc-side.is-cheaper { --tone: var(--success); }
.calc-side.is-dearer  { --tone: var(--error); }
.calc-side.is-cheaper,
.calc-side.is-dearer {
  border-color: color-mix(in srgb, var(--tone) 42%, transparent);
  background: color-mix(in srgb, var(--tone) 6%, var(--surface));
}
.calc-side b { display: block; font-size: 1.02rem; font-weight: 700; }
.calc-side .desc { display: block; font-size: .84rem; color: var(--text-muted); margin-top: 3px; }
.calc-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  vertical-align: 2px;
  color: var(--tone);
  background: color-mix(in srgb, var(--tone) 14%, transparent);
}
/* The page quotes monthly everywhere, so the side leads with the monthly figure
   and carries the annual equivalent under it. Both are always labelled. */
.calc-amt { font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; white-space: nowrap; font-variant-numeric: tabular-nums; text-align: right; color: var(--tone); }
.calc-amt em { font-style: normal; font-size: .78rem; font-weight: 600; color: var(--text-muted); letter-spacing: 0; margin-left: 2px; }
.calc-amt small {
  display: block;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-muted);
  margin-top: 2px;
}
.calc-bar { grid-column: 1 / -1; display: flex; height: 10px; border-radius: 999px; background: var(--surface-2); overflow: hidden; margin-top: 8px; }
.calc-bar i { display: block; height: 100%; background: var(--tone); transition: width .35s ease; }
.calc-bar i + i { background: color-mix(in srgb, var(--tone) 45%, var(--surface)); }
.calc-parts { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: .8rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.calc-side .calc-parts span { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.calc-parts span::before { content: ""; width: 9px; height: 9px; border-radius: 3px; background: var(--tone); }
.calc-parts span + span::before { background: color-mix(in srgb, var(--tone) 45%, var(--surface)); }
.calc-parts [hidden] { display: none !important; }

.calc-keep {
  padding: 22px 24px;
  border-radius: var(--r-lg);
  border: 1px solid var(--divider);
  background: var(--surface);
}
.calc-keep strong {
  display: block;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -.03em;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.calc-keep.is-win strong { color: var(--success); }
.calc-keep p { margin-top: 8px; font-size: .92rem; color: var(--text-muted); }

/* FAQ — a details/summary list, works with JavaScript off. */
.faq { border-top: 1px solid var(--divider); }
.faq details { border-bottom: 1px solid var(--divider); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 22px 0;
  cursor: pointer;
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -.01em;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  flex-shrink: 0;
  width: 11px;
  height: 11px;
  border-right: 2.2px solid var(--text-muted);
  border-bottom: 2.2px solid var(--text-muted);
  transform: rotate(45deg) translate(-3px, -3px);
  transition: transform .2s ease;
}
.faq details[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq summary:hover { color: var(--primary); }
.faq details > p,
.faq .faq-a { padding-bottom: 22px; margin-top: -4px; color: var(--text-muted); max-width: 74ch; }
.faq .faq-a > * + * { margin-top: 12px; }
.faq details[id] { scroll-margin-top: 90px; }

/* The FAQ page: jump links into the groups, then one .faq list per group. */
.faq-jump { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 30px; }
a.chip { text-decoration: none; }
.band-dark .chip { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.14); color: #C3C9DA; }
.band-dark .chip:hover { color: #fff; border-color: rgba(255,255,255,.3); }
.faq-group { scroll-margin-top: 90px; }
.faq-group + .faq-group { margin-top: clamp(48px, 6vw, 72px); }
.faq-group .eyebrow { margin-bottom: 10px; }
.faq-group h2 { margin-bottom: 22px; }

/* A one-line pointer to the FAQ, where a page used to carry its own list. */
.faq-pointer { display: flex; align-items: center; justify-content: space-between; gap: 18px 28px; flex-wrap: wrap; }
.faq-pointer .h3 { margin: 0; max-width: 34ch; }

.quote {
  border-left: 3px solid var(--primary);
  padding-left: 22px;
  font-size: clamp(1.15rem, 2vw, 1.42rem);
  line-height: 1.5;
  font-weight: 600;
  letter-spacing: -.02em;
}

.note {
  border: 1px solid var(--divider);
  border-left: 3px solid var(--primary);
  border-radius: var(--r-md);
  background: var(--surface);
  padding: 18px 22px;
  font-size: .92rem;
  color: var(--text-muted);
}
.note.warn { border-left-color: var(--warning); }
.note strong { color: var(--text); }

.step { display: flex; gap: 20px; }
.step-n {
  flex-shrink: 0;
  width: 34px; height: 34px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--brand-1), var(--secondary-dark));
  color: #fff;
  font-weight: 800;
  font-size: .92rem;
}
.steps { display: grid; gap: 28px; }

/* a plain one-line-per-item checklist (no heading weight) */
.tick-list { list-style: none; padding: 0; display: grid; gap: 12px; }
.tick-list li { display: flex; gap: 10px; align-items: flex-start; font-size: .92rem; line-height: 1.5; }
.tick-list > li > svg {
  width: 16px; height: 16px;
  flex-shrink: 0;
  margin-top: 4px;
  color: var(--success);
  stroke-width: 2.6;
  fill: none;
  stroke: currentColor;
}

/* stat callout */
.stat { display: grid; gap: 4px; }
.stat b { font-size: clamp(1.7rem, 3vw, 2.3rem); font-weight: 800; letter-spacing: -.035em; line-height: 1.05; }
.stat span { font-size: .87rem; color: var(--text-muted); }

/* memory bar visual */
.membar {
  height: 42px;
  border-radius: var(--r-sm);
  overflow: hidden;
  display: flex;
  border: 1px solid var(--divider);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .04em;
}
.membar div { display: grid; place-items: center; color: #fff; }
.membar .ram { background: linear-gradient(135deg, var(--brand-1), var(--secondary-dark)); flex: 0 0 62%; }
.membar .spill { background: var(--surface-2); color: var(--text-muted); flex: 1; }

/* forms */
.field { display: grid; gap: 7px; }
.field label { font-size: .87rem; font-weight: 600; }
.field label .req { color: var(--error); }
.field input, .field select, .field textarea {
  width: 100%;
  height: 46px;
  padding: 0 14px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--divider);
  background: var(--surface);
  font-size: .95rem;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.field textarea { height: auto; padding: 12px 14px; resize: vertical; min-height: 104px; line-height: 1.6; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
}
.field .hint { font-size: .8rem; color: var(--text-muted); }
/* `.field` is a grid, which would override the hidden attribute site.js sets on a field that does
   not apply to the chosen topic. */
.field[hidden] { display: none; }

/* The trial page's topic choice (trial.html, docs/BACKLOG.md §91o): two plain radio buttons,
   a trial (the default) or a question. */
.topic { display: flex; flex-wrap: wrap; gap: 10px 26px; border: 0; margin: 0; padding: 0; min-width: 0; }
.topic legend { padding: 0; margin-bottom: 10px; font-size: .87rem; font-weight: 600; }
.topic label { display: inline-flex; align-items: center; gap: 9px; font-size: .95rem; cursor: pointer; }
.topic input { width: 18px; height: 18px; margin: 0; accent-color: var(--primary); cursor: pointer; }
/* The honeypot: invisible to people, filled in by bots (Web3Forms reads `botcheck`). */
.botcheck { display: none; }
/* Hidden until the form sends; `:target` shows it without JavaScript after Web3Forms redirects. */
.form-sent { display: none; margin-top: 4px; border-left-color: var(--success); }
.form-sent:target, .form-sent.show { display: block; }

/* --------------------------------------------------------------------------
   15b. Architecture diagram
   CSS boxes + connector rules rather than a fixed-coordinate SVG, so it
   reflows and stacks instead of scaling into illegibility.
   -------------------------------------------------------------------------- */
.arch { margin: 0 0 clamp(32px, 4vw, 46px); }

.arch-boundary {
  border: 1.5px dashed color-mix(in srgb, var(--primary) 42%, var(--divider));
  border-radius: var(--r-xl);
  padding: clamp(20px, 3vw, 30px);
  background: color-mix(in srgb, var(--primary) 4%, transparent);
}

.arch-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 20px;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--primary);
}
.arch-head svg { width: 14px; height: 14px; stroke-width: 2.2; fill: none; stroke: currentColor; }

.arch-box {
  background: var(--surface);
  border: 1px solid var(--divider);
  border-radius: var(--r-md);
  padding: 13px 18px;
  text-align: center;
  min-width: 0;
  max-width: 100%;
}
.arch-box b { display: block; font-size: .92rem; font-weight: 700; letter-spacing: -.01em; }
.arch-box span { display: block; font-size: .77rem; line-height: 1.45; color: var(--text-muted); margin-top: 3px; }
.arch-box.dashed { border-style: dashed; background: transparent; }
.arch-box.key {
  border-color: color-mix(in srgb, var(--primary) 55%, var(--divider));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent), var(--shadow-md);
}

.arch-tier { display: flex; justify-content: center; }
.arch-tier > * { max-width: 400px; }

/* vertical connector between tiers */
.arch-conn { width: 2px; height: 20px; margin: 0 auto; background: var(--divider); }
.arch-conn.dotted {
  background: repeating-linear-gradient(to bottom, var(--divider) 0 4px, transparent 4px 9px);
  height: 26px;
}

/* the side branch (Trinium -> Python runner) */
.arch-row { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 14px; }
.arch-hconn { position: relative; width: 46px; height: 2px; background: var(--divider); flex-shrink: 0; }
.arch-hconn::after {
  content: "";
  position: absolute;
  right: -1px;
  top: 50%;
  transform: translateY(-50%);
  border-left: 7px solid var(--divider);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
}
.arch-hconn i {
  position: absolute;
  top: -17px;
  left: 50%;
  transform: translateX(-50%);
  font-style: normal;
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}

/* small labelled chips inside a box */
.arch-sub { display: flex; gap: 7px; justify-content: center; flex-wrap: wrap; margin-top: 12px; }
.arch-chip {
  font-size: .715rem;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 6px;
  background: var(--surface-2);
  border: 1px solid var(--divider);
  color: var(--text-muted);
  white-space: nowrap;
}

.arch-outside { text-align: center; }
.arch-deny {
  list-style: none;
  padding: 0;
  margin-top: 16px;
  display: flex;
  gap: 8px 20px;
  flex-wrap: wrap;
  justify-content: center;
}
.arch-deny li { display: inline-flex; align-items: center; gap: 7px; font-size: .82rem; font-weight: 600; color: var(--text-muted); }
.arch-deny svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--error); stroke-width: 2.8; fill: none; stroke: currentColor; }


@media (max-width: 700px) {
  /* the branch stacks; a horizontal arrow between stacked boxes is nonsense */
  .arch-hconn { display: none; }
  .arch-row { flex-direction: column; gap: 16px; }
  .arch-tier > * { max-width: 100%; width: 100%; }
}

/* --------------------------------------------------------------------------
   15c. Home — who it's for
   -------------------------------------------------------------------------- */
.card p.promise { color: var(--text); font-weight: 600; font-size: 1rem; line-height: 1.45; margin-top: 2px; }

/* About: the company facts. A muted label column beside the value; on a phone the label sits
   above its value. The rule between rows is the only decoration. */
.facts { display: grid; grid-template-columns: minmax(150px, .32fr) minmax(0, 1fr); margin: 0; }
.facts dt,
.facts dd { margin: 0; padding: 14px 0; border-top: 1px solid var(--divider); }
.facts dt:first-of-type,
.facts dt:first-of-type + dd { border-top: 0; padding-top: 0; }
.facts dt { color: var(--text-muted); font-size: .9rem; font-weight: 600; padding-right: 20px; }
.facts dd { color: var(--text); font-size: .95rem; line-height: 1.55; }
.facts a { color: var(--primary); }
@media (max-width: 620px) {
  .facts { grid-template-columns: minmax(0, 1fr); }
  .facts dt { padding-bottom: 2px; }
  .facts dd { border-top: 0; padding-top: 0; }
}

/* --------------------------------------------------------------------------
   15d. Demo animations — the Flow run, the memory/spill panel, mini pipelines.
   Every one of them is complete, finished-state markup without JavaScript;
   site.js only plays them, and only once they are on screen.
   -------------------------------------------------------------------------- */

/* the run-state label in a canvas bar (Home's tour) */
.canvas-bar .live[data-state="running"] { color: var(--primary); }
.canvas-bar .live[data-state="running"]::before { box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 25%, transparent); }


/* Mini pipelines on the use-case page: columns of compact node cards, joined by SVG edges drawn
   from the cards' real positions. Wider than a phone, so they scroll inside their own box. */
.mini-flow {
  position: relative;
  border: 1px solid var(--divider);
  border-radius: var(--r-xl);
  background:
    radial-gradient(circle, var(--grid-dot) 1.5px, transparent 1.5px) 0 0 / 18px 18px,
    var(--bg);
  overflow-x: auto;
  margin-bottom: clamp(30px, 4vw, 44px);
}
/* without JavaScript there is nothing to draw, and an empty bordered box reads as a bug —
   the "built from" list beside each use case carries the same content */
.mini-flow:empty { display: none; }
.mf-inner { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 44px; padding: 34px 30px; min-width: max-content; }
.mf-col { display: flex; flex-direction: column; gap: 18px; position: relative; z-index: 1; }
.mf-node {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 178px;
  padding: 9px 10px;
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1.5px solid var(--divider);
  box-shadow: var(--shadow-md);
}
.mf-node .tile { width: 34px; height: 34px; border-radius: var(--r-md); }
.mf-node .tile svg { width: 19px; height: 19px; }
.mf-node .node-label { font-size: .82rem; }
.mf-node .node-sub { font-size: .7rem; }
.mf-edges { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.mf-edges path { fill: none; stroke: color-mix(in srgb, var(--text-muted) 45%, var(--divider)); stroke-width: 2; stroke-linecap: round; }
.mf-edges path.alt { stroke-dasharray: 5 6; }
.mf-edges text { font-size: 10.5px; font-weight: 700; fill: var(--text-muted); paint-order: stroke; stroke: var(--bg); stroke-width: 4px; }
.mini-flow.is-live .mf-edges path { stroke: var(--primary); stroke-dasharray: 7 9; animation: dash 1.1s linear infinite; }
.mini-flow.is-live .mf-edges path.alt { stroke: var(--error); }
.mf-node { opacity: 0; transform: translateY(6px); transition: opacity .45s ease, transform .45s ease; }
.mini-flow.is-in .mf-node { opacity: 1; transform: none; }
/* on a phone the columns stack top-to-bottom and the edges are drawn vertically */
@media (max-width: 620px) {
  .mf-inner { flex-direction: column; min-width: 0; gap: 34px; padding: 26px 16px; }
  .mf-col { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 12px; }
  .mf-node { width: 150px; }
}
.mf-title { position: absolute; top: 10px; left: 16px; font-size: .66rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }

/* --------------------------------------------------------------------------
   15e. Home, rebuilt 2026-09-29: the canvas tour, the proof strip, the audience
   fork, the production bento, the big-number engine band, the catalog list and
   the security facts. One story, told once, in the order a buyer asks it.
   -------------------------------------------------------------------------- */

/* The canvas tour. One replica of the builder, four states (Build, Test, Ship, Run), switched by
   `data-step` on `.tour`; CSS decides what each state shows and site.js only plays them. The
   markup IS the finished Run state, so with JavaScript off the canvas reads as a completed run and
   the tab bar (which needs JavaScript to do anything) is not shown at all. */
.tour { position: relative; text-align: left; }
.tour-tabs { display: none; }
html.js .tour-tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.tour-tab {
  position: relative;
  overflow: hidden;
  display: grid;
  gap: 3px;
  padding: 12px 16px 14px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,.1);
  background: rgba(255,255,255,.03);
  text-align: left;
  transition: border-color .2s ease, background-color .2s ease;
}
.tour-tab:hover { border-color: rgba(255,255,255,.22); }
.tour-tab .n {
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .06em;
  color: #6B7383;
}
.tour-tab b { font-size: .98rem; font-weight: 700; color: #C3C9DA; letter-spacing: -.01em; }
.tour-tab span:last-child { font-size: .8rem; line-height: 1.4; color: #8E96AB; }
.tour-tab[aria-selected="true"] {
  border-color: rgba(129,140,248,.5);
  background: rgba(99,102,241,.13);
}
.tour-tab[aria-selected="true"] b { color: #fff; }
.tour-tab[aria-selected="true"] .n { color: var(--primary-light); }
/* the auto-advance timer, drawn along the bottom edge of the selected tab */
.tour-tab::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 0;
  background: linear-gradient(90deg, var(--brand-1), var(--brand-2));
}
.tour.is-auto .tour-tab[aria-selected="true"]::after { animation: tourfill var(--tour-ms, 6000ms) linear forwards; }
.tour.is-paused .tour-tab[aria-selected="true"]::after { animation-play-state: paused; }
@keyframes tourfill { to { width: 100%; } }

/* the canvas bar: pipeline name, the version chips, and the run state */
.tour .canvas { text-align: left; }
.vchip {
  display: none;
  align-items: center;
  height: 22px;
  padding-inline: 9px;
  border-radius: 999px;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .01em;
  color: #9CA3B4;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.1);
  white-space: nowrap;
}
.vchip.ok { color: #86EFAC; background: rgba(34,197,94,.1); border-color: rgba(34,197,94,.28); }
.vchip.warn { color: #FCD34D; background: rgba(245,158,11,.1); border-color: rgba(245,158,11,.3); }
.tour[data-step="build"] .vchip[data-for~="build"],
.tour[data-step="test"] .vchip[data-for~="test"],
.tour[data-step="ship"]:not(.is-promoted) .vchip[data-for~="ship"],
.tour[data-step="ship"].is-promoted .vchip[data-for~="promoted"],
.tour[data-step="run"] .vchip[data-for~="run"] { display: inline-flex; }
.canvas-bar .live[data-state="idle"] { visibility: hidden; }
.canvas-bar .live[data-state="test"] { color: var(--warning); }
.canvas-bar .live[data-state="test"]::before { box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning) 25%, transparent); }

/* nodes and edges being placed during Build */
.tour .node, .tour .canvas-edges path { transition: opacity .35s ease, transform .35s ease, border-color .15s ease; }
.tour .node.pre { opacity: 0; transform: translateY(8px); }
.tour .canvas-edges path.pre { opacity: 0; }

/* Flowing batches: every node in a Trinium pipeline runs at once, so while a run is live every
   edge carries data, in the colour of the node that sends it. `--edge` is set per path. */
.canvas-edges path.flow {
  stroke: var(--edge, var(--primary-light));
  stroke-width: 3;
  stroke-dasharray: 2 12;
  animation: flowdash .7s linear infinite;
}
.tour[data-step="test"] .canvas-edges path.flow { stroke: var(--warning); }
@keyframes flowdash { to { stroke-dashoffset: -28px; } }

/* the dock under the canvas: the builder's own tabs, Data Out, Messages and Metadata */
.dock { border-top: 1px solid var(--divider); background: var(--surface); }
.band-dark .dock { border-top-color: rgba(255,255,255,.1); background: rgba(255,255,255,.025); }
.dock-tabs {
  display: flex;
  align-items: center;
  gap: 2px;
  padding-inline: 12px;
  border-bottom: 1px solid var(--divider);
  font-size: .78rem;
  font-weight: 600;
}
.band-dark .dock-tabs { border-bottom-color: rgba(255,255,255,.08); }
.dock-tabs > span { padding: 10px 12px; color: var(--text-muted); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.dock-note {
  margin-left: auto;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.tour[data-step="build"] .dock-tabs [data-tab="metadata"],
.tour[data-step="test"] .dock-tabs [data-tab="data"],
.tour[data-step="ship"] .dock-tabs [data-tab="data"],
.tour[data-step="run"] .dock-tabs [data-tab="messages"] { color: var(--text); border-bottom-color: var(--primary); }
.dock-note [data-for] { display: none; }
.tour[data-step="build"] .dock-note [data-for="build"] { display: inline; color: var(--success); }
.tour[data-step="test"] .dock-note [data-for="test"],
.tour[data-step="ship"] .dock-note [data-for="test"] { display: inline; color: var(--warning); }
.tour[data-step="run"] .dock-note [data-for="run"] { display: inline; }

.dock-body { position: relative; height: 178px; overflow: hidden; }
.dock-pane {
  position: absolute;
  inset: 0;
  padding: 10px 20px;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease, visibility .3s;
}
.tour[data-step="build"] .dock-pane[data-pane="metadata"],
.tour[data-step="test"] .dock-pane[data-pane="data"],
.tour[data-step="ship"] .dock-pane[data-pane="data"],
.tour[data-step="run"] .dock-pane[data-pane="messages"] { opacity: 1; visibility: visible; }
.dock-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; }
.band-dark .schema-row { border-bottom-color: rgba(255,255,255,.07); }
.band-dark .schema-row .ty { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.1); }
.dock-table { width: 100%; border-collapse: collapse; font-size: .82rem; }
.dock-table th {
  text-align: left;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--text-muted);
  padding: 6px 10px 6px 0;
  border-bottom: 1px solid var(--divider);
}
.dock-table td { padding: 6px 10px 6px 0; border-bottom: 1px solid var(--divider); color: var(--text); }
.band-dark .dock-table th, .band-dark .dock-table td { border-bottom-color: rgba(255,255,255,.07); }
.dock-table .num { text-align: right; font-family: var(--font-mono); font-size: .78rem; }
.log { list-style: none; padding: 4px 0 0; display: grid; gap: 2px; }
.log li { display: flex; gap: 14px; font-size: .84rem; line-height: 1.9; color: var(--text); }
.log time { font-family: var(--font-mono); font-size: .76rem; color: var(--text-muted); }
.log li.ok { color: #86EFAC; }
.tour .fade-item { transition: opacity .35s ease, transform .35s ease; }
.tour .fade-item.pre { opacity: 0; transform: translateX(-8px); }

/* Ship: the Promote dialog, as the builder shows it, over a dimmed canvas */
.tour-dialog {
  position: absolute;
  inset: 42px 0 0;
  z-index: 3;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(8,9,14,.55);
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease, visibility .3s;
}
.tour.is-dialog .tour-dialog { opacity: 1; visibility: visible; }
.dlg {
  width: min(400px, 100%);
  padding: 20px 22px;
  border-radius: 16px;
  background: #1A1D27;
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 30px 80px rgba(0,0,0,.6);
}
.dlg h4 { font-size: 1.02rem; color: #fff; }
.dlg p { margin-top: 8px; font-size: .88rem; line-height: 1.55; color: #A9B0C4; }
.dlg p strong { color: #fff; }
.env-rail { display: flex; align-items: center; gap: 10px; margin-top: 16px; flex-wrap: wrap; }
.env-rail svg { width: 16px; height: 16px; color: #6B7383; flex-shrink: 0; }
.env {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  padding-inline: 11px;
  border-radius: 9px;
  font-size: .8rem;
  font-weight: 700;
  color: #E6E8EE;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.12);
}
.env i { font-style: normal; font-family: var(--font-mono); font-size: .76rem; color: var(--primary-light); }
.env .v-new { display: none; }
.tour.is-promoted .env .v-old { display: none; }
.tour.is-promoted .env .v-new { display: inline; color: #86EFAC; }
.tour.is-promoted .env.prod { border-color: rgba(34,197,94,.4); background: rgba(34,197,94,.08); }
.dlg-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.dlg-actions .btn { height: 36px; padding-inline: 16px; font-size: .85rem; pointer-events: none; }
.dlg-actions .btn-primary.is-pressed { transform: scale(.95); box-shadow: 0 0 0 4px rgba(99,102,241,.35); }

/* The proof strip under the tour: four figures, each a link to the page that proves it */
.proof-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: clamp(40px, 5vw, 60px);
  border-top: 1px solid rgba(255,255,255,.09);
  text-align: left;
}
.proof-strip a { display: block; padding: 26px 24px 4px; text-decoration: none; border-left: 1px solid rgba(255,255,255,.07); }
.proof-strip a:first-child { border-left: 0; padding-left: 0; }
.proof-strip b {
  display: block;
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  font-weight: 800;
  letter-spacing: -.035em;
  line-height: 1.05;
  color: #fff;
  font-variant-numeric: tabular-nums;
  transition: color .2s ease;
}
.proof-strip span { display: block; margin-top: 8px; font-size: .88rem; line-height: 1.45; color: #8E96AB; }
.proof-strip a:hover b { color: var(--primary-light); }

/* Who it's for: two paths a visitor chooses between, then the three audiences who join them */
.fork { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
.fork-card { position: relative; overflow: hidden; padding: clamp(26px, 3vw, 36px); }
.fork-card::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: linear-gradient(90deg, var(--c), color-mix(in srgb, var(--c) 30%, transparent));
}
.fork-card .card-icon { background: var(--c-12); color: var(--c); }
.fork-card .h3 { font-size: clamp(1.3rem, 2.2vw, 1.6rem); }
.fork-card .tick-list { margin-block: 20px 24px; }
.fork-card .tick-list li { font-size: .96rem; }
.also { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; margin-top: 22px; }
.also a { display: grid; grid-template-columns: 42px minmax(0, 1fr); gap: 4px 16px; align-items: start; padding: 22px 24px; }
.also .card-icon { grid-row: span 2; margin: 0; }
.also b { font-size: 1rem; font-weight: 700; color: var(--text); }
.also span { font-size: .9rem; line-height: 1.5; color: var(--text-muted); }

/* The production bento: mixed tile sizes, each tile carrying a small picture of the thing */
.bento { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 20px; }
.bento > * { grid-column: span 2; display: flex; flex-direction: column; }
.bento > .w4 { grid-column: span 4; }
.bento h3 { font-size: 1.14rem; font-weight: 700; letter-spacing: -.015em; line-height: 1.3; }
.bento p { margin-top: 8px; }
.bento .viz { margin-top: auto; padding-top: 22px; }
.bento svg.flowviz { width: 100%; height: auto; }
.flowviz rect { fill: var(--bg); stroke: var(--divider); stroke-width: 1.5; }
.flowviz rect.alert { stroke: color-mix(in srgb, var(--error) 55%, var(--divider)); stroke-dasharray: 5 4; }
.flowviz path { fill: none; stroke: var(--divider); stroke-width: 2; }
.flowviz path.fail { stroke: var(--error); stroke-dasharray: 5 5; opacity: .75; }
.flowviz text { font: 600 13px "Plus Jakarta Sans", sans-serif; fill: var(--text); }
.flowviz text.lbl { font-size: 11px; font-weight: 700; fill: var(--error); }
.flowviz circle { fill: var(--success); }
.flowviz circle.skip { fill: var(--text-muted); opacity: .5; }

.vlist { list-style: none; padding: 0; font-size: .86rem; }
.vlist li { display: flex; align-items: center; gap: 8px; padding: 9px 0; border-top: 1px solid var(--divider); }
.vlist .v { font-family: var(--font-mono); font-weight: 600; width: 2.4em; }
.vlist .tag {
  height: 20px;
  display: inline-flex;
  align-items: center;
  padding-inline: 7px;
  border-radius: 999px;
  font-size: .68rem;
  font-weight: 700;
  color: var(--success);
  background: color-mix(in srgb, var(--success) 12%, transparent);
}
.vlist .restore { margin-left: auto; font-size: .76rem; font-weight: 600; color: var(--primary); }

.starts { list-style: none; padding: 0; display: grid; gap: 10px; }
.starts li { display: flex; align-items: center; gap: 12px; font-size: .92rem; font-weight: 600; }
.starts svg {
  width: 30px; height: 30px;
  padding: 6px;
  border-radius: 9px;
  flex-shrink: 0;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

.meters { list-style: none; padding: 0; display: grid; gap: 10px; font-size: .8rem; }
.meters li { display: grid; grid-template-columns: 5.6rem minmax(0, 1fr) auto; gap: 10px; align-items: center; }
.meters b { font-weight: 600; }
.meters i { height: 6px; border-radius: 3px; background: linear-gradient(90deg, var(--c), color-mix(in srgb, var(--c) 45%, transparent)); }
.meters em { font-style: normal; font-family: var(--font-mono); font-size: .74rem; color: var(--text-muted); }
.meters-foot { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--divider); font-size: .78rem; color: var(--text-muted); }

.sql {
  margin: 0;
  padding: 16px 18px;
  border-radius: var(--r-md);
  background: #0F1117;
  border: 1px solid var(--divider);
  font-family: var(--font-mono);
  font-size: .8rem;
  line-height: 1.75;
  color: #C3C9DA;
  white-space: pre;
  overflow-x: auto;
}
.sql .k { color: #A5B4FC; }
.sql .c { color: #FDBA74; }
.sql .s { color: #86EFAC; }

/* The engine band: one number, set as large as the page allows, then how it was measured */
.bignum { display: flex; align-items: baseline; gap: clamp(12px, 2vw, 22px); flex-wrap: wrap; margin-top: 8px; }
.bignum b {
  font-size: clamp(3rem, 10.5vw, 8.6rem);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: .95;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(100deg, #fff 10%, #C7D2FE 55%, var(--brand-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.bignum span { font-size: clamp(1.2rem, 2.4vw, 1.9rem); font-weight: 700; color: #A9B0C4; }
.bigstats { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.bigstats span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding-inline: 16px;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.12);
  background: rgba(255,255,255,.04);
  font-size: .9rem;
  font-weight: 600;
  color: #C3C9DA;
}
.bigstats b { font-family: var(--font-mono); font-weight: 600; color: #fff; }
.bigstats b i { font-style: normal; color: #9CA3B4; font-size: .85em; }
.bigcap { margin-top: 16px; font-size: .86rem; color: #8E96AB; max-width: 70ch; }
.engine-why { margin-top: clamp(40px, 5vw, 64px); padding-top: clamp(32px, 4vw, 48px); border-top: 1px solid rgba(255,255,255,.09); }
.engine-why { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.engine-punch { margin-top: clamp(24px, 3vw, 34px); display: flex; align-items: baseline; justify-content: space-between; gap: 18px 32px; flex-wrap: wrap; }
.fact-list b { color: var(--text); }
.fact-list span { color: var(--text-muted); }

/* The catalog as six rows, one per category, each linking to its section of the gallery.
   The count in each row is written by scripts/website/nodes.mjs (`data-count`), never by hand. */
.cat-list { list-style: none; padding: 0; border-top: 1px solid var(--divider); }
.cat-list a {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  gap: 16px;
  align-items: center;
  padding: 14px 10px;
  border-bottom: 1px solid var(--divider);
  text-decoration: none;
  transition: background-color .16s ease;
}
.cat-list a:hover { background: var(--c-12); }
.cat-list b { display: block; font-size: .98rem; font-weight: 700; }
.cat-list small { display: block; font-size: .84rem; line-height: 1.45; color: var(--text-muted); }
.cat-list .n { font-family: var(--font-mono); font-weight: 600; font-size: 1.02rem; color: var(--c); }
.conn-grid.flat { grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); }

/* Home's pricing band sets the four "No" tiles two by two, beside the headline */
.nots.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.conn-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.conn-head::after { content: ""; flex: 1; height: 1px; background: var(--divider); }

/* Security, as four plain statements rather than four more boxes */
.fact-list { list-style: none; padding: 0; border-top: 1px solid var(--divider); }
.fact-list li { display: flex; gap: 16px; padding: 18px 0; border-bottom: 1px solid var(--divider); font-size: 1.02rem; line-height: 1.5; }
.fact-list svg {
  width: 22px; height: 22px;
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--primary);
  fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}

@media (max-width: 900px) {
  html.js .tour-tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .proof-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .proof-strip a:nth-child(3) { border-left: 0; padding-left: 0; }
  .fork, .also { grid-template-columns: minmax(0, 1fr); }
  .bento { grid-template-columns: minmax(0, 1fr); }
  .bento > *, .bento > .w4 { grid-column: auto; }
  .dock-grid { grid-template-columns: minmax(0, 1fr); }
  .dock-grid .schema-row:nth-child(n+5) { display: none; }
}
@media (max-width: 620px) {
  .tour-tab span:last-child { display: none; }
  .tour-tab { padding: 10px 12px; }
  .proof-strip a { padding: 20px 14px 4px; }
  .dock-body { height: 214px; }
  .log li { gap: 10px; line-height: 1.6; padding-block: 3px; }
  .dock-table .hide-sm { display: none; }
  .nots.two { grid-template-columns: minmax(0, 1fr); }
  /* a phone keeps what the step is about, the version and the run state, and drops the rest */
  .tour .canvas-bar .dots, .tour .canvas-bar .cb-name { display: none; }
}

/* --------------------------------------------------------------------------
   15f. A Flow, as the Flow builder draws it (product.html#flows, 2026-09-29).
   Faithful to ui/src/components/flows/: FlowStepNode.jsx (the card), FlowConditionEdge.jsx
   (the coloured edges and their chips) and flowStatus.js (what each status looks like).
   `data-status` on a step and `data-state` on the panels drive every visual;
   site.js ([data-flowrun]) only changes those attributes.
   -------------------------------------------------------------------------- */
.flowrun { position: relative; }

/* the builder's header row: flow name, environment, run chip, run history, Run / Cancel */
.flow-bar { gap: 10px; height: 48px; font-size: .82rem; }
.fb-icon svg { width: 18px; height: 18px; color: var(--primary); }
.fb-name { color: var(--text); font-size: .9rem; }
.fb-env {
  height: 20px; padding-inline: 8px; border-radius: 999px;
  display: inline-flex; align-items: center;
  font-size: .7rem; font-weight: 700;
  color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.fb-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.fb-run {
  height: 22px; padding-inline: 9px; border-radius: 999px;
  display: inline-flex; align-items: center;
  font-size: .72rem; font-weight: 700;
  --tone: var(--text-muted);
  color: var(--tone);
  background: color-mix(in srgb, var(--tone) 14%, transparent);
}
.fb-run[data-state="Running"] { --tone: var(--info); }
.fb-run[data-state="Succeeded"] { --tone: var(--success); }
.fb-run[data-state="Failed"] { --tone: var(--error); }
.fb-history {
  display: inline-flex; align-items: center; gap: 8px;
  height: 30px; padding: 0 8px 0 10px;
  border: 1px solid var(--divider); border-radius: 8px;
  font-weight: 600; color: var(--text); white-space: nowrap;
}
.fb-history small { font-size: .66rem; color: var(--text-muted); font-weight: 600; }
.fb-history svg { width: 14px; height: 14px; color: var(--text-muted); }
.fb-btn {
  display: inline-flex; align-items: center;
  height: 30px; padding-inline: 12px; border-radius: 8px;
  font-weight: 700; color: #fff; background: var(--success);
}
.fb-btn > span { display: inline-flex; align-items: center; gap: 6px; }
.fb-btn svg { width: 14px; height: 14px; }
.fb-btn .fb-stop { display: none; }
.fb-btn[data-live="true"] { background: var(--error); }
.fb-btn[data-live="true"] .fb-play { display: none; }
.fb-btn[data-live="true"] .fb-stop { display: inline-flex; }

/* the step card: FlowStepNode — 2px border, radius 8, an icon tile, name, "Run pipeline · x",
   and a status chip in the card */
.fstep {
  position: absolute;
  width: 180px;
  height: 84px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 10px 10px 9px;
  border-radius: 8px;
  border: 2px solid var(--divider);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: border-color .2s ease, opacity .2s ease, box-shadow .2s ease;
  --st: var(--text-muted);
}
/* the two handles, at mid-height like React Flow's */
.fstep::before, .fstep::after {
  content: "";
  position: absolute;
  top: calc(50% - 6px);
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--surface);
  border: 2px solid var(--divider);
}
.fstep::before { left: -7px; }
.fstep::after { right: -7px; }
.fstep-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.fstep-tile {
  width: 34px; height: 34px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 12px;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
}
.fstep[data-kind="notify"] .fstep-tile, .fstep-tile.is-notify {
  color: var(--secondary);
  background: color-mix(in srgb, var(--secondary) 14%, transparent);
}
.fstep-tile svg { width: 19px; height: 19px; }
.fstep-text { min-width: 0; display: grid; }
.fstep-text b, .fstep-text small { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fstep-text b { font-size: .84rem; font-weight: 700; color: var(--text); letter-spacing: -.01em; }
.fstep-text small { font-size: .7rem; color: var(--text-muted); }

.fstatus {
  align-self: flex-start;
  height: 20px; padding-inline: 8px; border-radius: 999px;
  display: inline-flex; align-items: center;
  font-size: .68rem; font-weight: 700;
  color: var(--text-muted);
  border: 1px solid var(--divider);
}
/* flowStatus.js: Running = info + a pulse · Succeeded = success · Failed = error ·
   Skipped = dashed and dimmed · Pending = neutral */
.fstep[data-status="Running"], .fpanel[data-state="running"] { --st: var(--info); }
.fstep[data-status="Succeeded"], .fpanel[data-state="done"] { --st: var(--success); }
.fstep[data-status="Failed"] { --st: var(--error); }
.fstep[data-status="Running"], .fstep[data-status="Succeeded"], .fstep[data-status="Failed"] { border-color: var(--st); }
.fstep[data-status="Running"] .fstatus, .fstep[data-status="Succeeded"] .fstatus, .fstep[data-status="Failed"] .fstatus,
.fpanel[data-state="running"] .fstatus, .fpanel[data-state="done"] .fstatus {
  color: #fff; background: var(--st); border-color: var(--st);
}
.fstep[data-status="Running"] { animation: flowPulse 1.4s ease-in-out infinite; }
@keyframes flowPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--info) 50%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--info) 0%, transparent); }
}
.fstep[data-status="Skipped"] { border-style: dashed; opacity: .55; box-shadow: none; }

/* the edges: coloured by their condition (FlowConditionEdge), with a chip at the midpoint */
.flow-stage .canvas-edges path.fedge { stroke-width: 2; }
.flow-stage .canvas-edges path.fedge.ok { stroke: var(--success); }
.flow-stage .canvas-edges path.fedge.fail { stroke: var(--error); }
.flow-stage .canvas-edges path.fedge.always { stroke: var(--text-muted); }
.flow-stage .canvas-edges path.fedge.hot { stroke-width: 3; stroke-dasharray: 6 7; animation: dash .9s linear infinite; }
.flow-stage marker.ok path { fill: var(--success); }
.flow-stage marker.fail path { fill: var(--error); }
.fchip {
  display: inline-flex; align-items: center; gap: 4px;
  height: 22px; padding-inline: 7px; border-radius: 999px;
  font-size: .68rem; font-weight: 700; white-space: nowrap;
  background: var(--surface);
  border: 1px solid currentColor;
  box-shadow: var(--shadow-sm);
}
.fchip.ok { color: var(--success); }
.fchip.fail { color: var(--error); }
.fchip.always { color: var(--text-muted); }
.flow-stage .fchip { position: absolute; transform: translate(-50%, -50%); z-index: 2; }

/* under the canvas: the pipeline inside a step, and the alert where it lands */
.flow-panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; margin-top: 20px; }
.fpanel {
  padding: 16px 18px;
  border-radius: var(--r-lg);
  border: 1px solid var(--divider);
  background: var(--bg);
  --st: var(--text-muted);
}
.fpanel-head { display: flex; align-items: center; gap: 10px; font-size: .9rem; color: var(--text-muted); }
.fpanel-head b { color: var(--text); }
.fpanel-head .fstep-tile { width: 28px; height: 28px; border-radius: 9px; }
.fpanel-head .fstep-tile svg { width: 16px; height: 16px; }
.fpanel-head .fstatus { margin-left: auto; }
.fpanel-note { margin-top: 12px; font-size: .84rem; color: var(--text-muted); }
.inset-pipe { display: flex; align-items: center; margin-top: 16px; }
.ipnode {
  display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0;
  padding: 6px 12px 6px 6px;
  border-radius: 10px;
  border: 1.5px solid var(--divider);
  background: var(--surface);
  font-size: .82rem; font-weight: 600;
  transition: border-color .2s ease;
}
.ipedge { flex: 1; min-width: 18px; height: 12px; }
.ipedge path { fill: none; stroke: var(--divider); stroke-width: 2; }
.fpanel[data-state="running"] .ipnode { border-color: color-mix(in srgb, var(--info) 55%, var(--divider)); }
.fpanel[data-state="done"] .ipnode { border-color: color-mix(in srgb, var(--success) 45%, var(--divider)); }
.fpanel[data-state="running"] .ipedge path { stroke: var(--edge); stroke-width: 3; stroke-dasharray: 2 10; animation: flowdash .7s linear infinite; }

.alert-quiet { margin-top: 16px; font-size: .9rem; color: var(--text-muted); }
.alert-msg {
  display: none;
  gap: 12px;
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--divider);
  border-left: 3px solid var(--error);
  animation: alertIn .45s cubic-bezier(.16,1,.3,1);
}
.fpanel[data-state="msg"] .alert-quiet { display: none; }
.fpanel[data-state="msg"] .alert-msg { display: flex; }
@keyframes alertIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.alert-avatar {
  width: 32px; height: 32px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 8px;
  color: #fff; font-weight: 800;
  background: linear-gradient(135deg, var(--brand-1), var(--secondary-dark));
}
.alert-from { font-size: .82rem; }
.alert-from time { margin-left: 6px; color: var(--text-muted); font-family: var(--font-mono); font-size: .74rem; }
.alert-body {
  margin: 4px 0 0;
  font-family: inherit;
  font-size: .86rem;
  line-height: 1.55;
  color: var(--text);
  white-space: pre-wrap;
}

/* the four points under it: short, plain, one idea each */
.flow-points { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 28px; margin-top: clamp(40px, 5vw, 56px); }
.flow-points .h4 { margin: 14px 0 6px; }
.flow-points p { font-size: .9rem; line-height: 1.55; color: var(--text-muted); }
.fp-icon {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: 11px;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.fp-icon svg { width: 20px; height: 20px; }
.fp-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }

@media (max-width: 900px) {
  .flow-panels { grid-template-columns: minmax(0, 1fr); }
  .flow-points { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .flow-bar .fb-history { display: none; }
}
@media (max-width: 760px) {
  .canvas-fit .flow-stage .fstep {
    position: relative !important;
    left: auto !important;
    top: auto !important;
    width: 100%;
    max-width: 280px;
    flex-shrink: 0;
  }
  .canvas-fit .flow-stage .fstep::before { display: none; }
  .canvas-fit .flow-stage .fstep::after {
    top: auto; bottom: -24px; right: auto; left: calc(50% - 1px);
    width: 2px; height: 22px; border: 0; border-radius: 0; background: var(--divider);
  }
  .canvas-fit .flow-stage .fstep:last-of-type::after { display: none; }
  .canvas-fit .flow-stage .fchip { display: none; }
  .flow-bar .fb-env { display: none; }
}
@media (max-width: 620px) {
  .flow-points { grid-template-columns: minmax(0, 1fr); }
  .flow-bar .fb-name { display: none; }
  .inset-pipe .ipnode > span:last-child { display: none; }
  .ipnode { padding: 6px; }
}

/* Product · 09: three foundations a data engine can be built on, compared by language
   (2026-09-29). The Rust column carries the one gradient accent in view. */
.lang-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.lang-name {
  display: block;
  margin-bottom: 10px;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.lang-cols .card p { font-size: .95rem; }
.lang-us {
  border: 1px solid transparent;
  background:
    linear-gradient(#141727, #141727) padding-box,
    linear-gradient(135deg, var(--brand-1), var(--brand-2)) border-box;
}
.band-dark .lang-us .lang-name { color: var(--primary-light); }
.lang-us p { color: #e6e8ee; }
@media (max-width: 900px) { .lang-cols { grid-template-columns: minmax(0, 1fr); } }

/* Security, 2026-09-29: every control a review asks about, one tile each, with a small mono
   tag where a reviewer wants the specific; and "Hosted, or yours", a comparison of models. */
.controls { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.control {
  display: flex;
  flex-direction: column;
  padding: 24px;
  border-radius: var(--r-xl);
  border: 1px solid var(--divider);
  background: var(--surface);
}
.control-icon {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  margin-bottom: 14px;
  border-radius: 11px;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.control-icon svg { width: 21px; height: 21px; }
.control .h4 { margin-bottom: 6px; }
.control p { font-size: .92rem; line-height: 1.55; color: var(--text-muted); }
.specs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 14px; }
.spec {
  display: inline-flex; align-items: center;
  height: 22px; padding-inline: 8px;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: .7rem; font-weight: 600;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--divider);
}
@media (max-width: 900px) { .controls { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) {
  .controls { grid-template-columns: minmax(0, 1fr); }
}

/* Security, pass 2 (2026-09-29): the controls in four labelled rows, and a replica of the
   Audit screen (ui/src/pages/AuditPage.jsx: its columns, action chips and outcome tones). */
.control-row + .control-row { margin-top: 30px; }
.control-label {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 14px;
  font-size: .76rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  color: var(--text-muted);
}
.control-label::after { content: ""; flex: 1; height: 1px; background: var(--divider); }

.audit-wrap { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: clamp(28px, 4vw, 48px); align-items: start; }
.audit-demo {
  border: 1px solid var(--divider);
  border-radius: var(--r-lg);
  background: var(--bg);
  overflow: hidden;
  font-size: .8rem;
  box-shadow: var(--shadow-md);
}
.ad-head, .ad-row {
  display: grid;
  grid-template-columns: 5.2rem 5.4rem 8.6rem 7rem 5.6rem minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  padding: 10px 14px;
}
.ad-head { font-size: .7rem; font-weight: 700; color: var(--text-muted); background: var(--surface-2); border-bottom: 1px solid var(--divider); }
.ad-row { border-bottom: 1px solid var(--divider); background: var(--surface); }
.ad-row:last-child { border-bottom: 0; }
.ad-row > span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ad-row.is-open { background: color-mix(in srgb, var(--primary) 6%, var(--surface)); }
.ad-when { font-family: var(--font-mono); font-size: .74rem; color: var(--text-muted); }
.ad-fam {
  font-style: normal; font-size: .64rem; font-weight: 700;
  padding: 1px 6px; margin-right: 6px; border-radius: 5px;
  color: var(--text-muted); border: 1px solid var(--divider);
}
.ad-out {
  display: inline-flex; align-items: center;
  height: 20px; padding-inline: 8px; border-radius: 999px;
  font-size: .68rem; font-weight: 700;
  --tone: var(--success);
  color: var(--tone);
  background: color-mix(in srgb, var(--tone) 14%, transparent);
}
.ad-out.warn { --tone: var(--warning); }
.ad-out.err { --tone: var(--error); }
.ad-detail { color: var(--text-muted); }
.ad-drawer {
  display: flex; flex-wrap: wrap; gap: 8px 26px;
  padding: 12px 14px 14px 22px;
  border-bottom: 1px solid var(--divider);
  border-left: 3px solid var(--primary);
  background: var(--surface);
  font-size: .8rem;
}
.ad-drawer small { display: block; font-size: .66rem; font-weight: 700; color: var(--text-muted); }
.ad-change .mono { font-size: .76rem; margin-right: 4px; }
.audit-points { list-style: none; padding: 0; display: grid; gap: 16px; }
.audit-points li { font-size: .94rem; line-height: 1.55; color: var(--text-muted); }
.audit-points b { color: var(--text); }

@media (max-width: 900px) {
  .audit-wrap { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 620px) {
  .ad-head, .ad-row { grid-template-columns: 4.6rem 7.6rem 5.2rem; }
  .ad-head > :nth-child(2), .ad-row > :nth-child(2), .ad-obj, .ad-detail { display: none; }
}

/* --------------------------------------------------------------------------
   16. Footer
   -------------------------------------------------------------------------- */
.footer {
  border-top: 1px solid var(--divider);
  padding-block: 62px 34px;
  background: var(--surface);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: 40px;
  margin-bottom: 46px;
}
.footer h4 {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--text-muted);
  margin-bottom: 16px;
}
.footer ul { list-style: none; padding: 0; display: grid; gap: 10px; }
.footer a {
  font-size: .91rem;
  color: var(--text-muted);
  text-decoration: none;
  transition: color .16s ease;
}
.footer a:hover { color: var(--primary); }
.footer-bottom {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  align-items: center;
  padding-top: 26px;
  border-top: 1px solid var(--divider);
  font-size: .84rem;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   17. Reveal on scroll
   -------------------------------------------------------------------------- */
/* Hidden only when JavaScript is running (the `js` class is set by each page's inline head script),
   because only JavaScript can reveal it again. Until 2026-09-29 this was unconditional, and with
   JavaScript off every fading section on the site stayed invisible: 20 on Home alone. */
html.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s cubic-bezier(.16,1,.3,1), transform .6s cubic-bezier(.16,1,.3,1);
}
html.js .reveal.in { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   18. Responsive
   -------------------------------------------------------------------------- */
/* The nav's two breakpoints are MEASURED, not chosen (2026-09-29, after "Node Catalog" became
   "Nodes & Connectors"): the full row needs a ~1,162px viewport and the compact one ~1,059px,
   measured as the free space left between the brand and the links, NOT as page overflow (the
   trial button eats into the side gutter long before the page scrolls sideways). Each switch
   sits ~40px above its need so a slightly wider font cannot push the button into the gutter.
   Re-measure both if a nav label changes. */
@media (max-width: 1200px) {
  .nav-links a { padding-inline: 9px; font-size: .855rem; }
  .brand { margin-right: 8px; }
  .nav .brand svg { width: 30px; height: 30px; }
  .nav .brand-word { font-size: 1.5rem; }
}
@media (max-width: 1080px) {
  .footer-grid { grid-template-columns: 1fr 1fr 1fr; }
  .footer-grid > :first-child { grid-column: 1 / -1; }
}

/* Eight nav items plus the trial button run out of room before the grids do, so the nav
   collapses to the menu button on its own. */
@media (max-width: 1100px) {
  .nav-links, .nav-actions .btn { display: none; }
  .nav-toggle { display: grid; }
}

@media (max-width: 900px) {
  .split, .g2, .g3, .g4 { grid-template-columns: minmax(0, 1fr); }
  .split.reverse > :first-child { order: 0; }
  .plans { grid-template-columns: minmax(0, 1fr); max-width: 460px; margin-inline: auto; }
  .plans.two { grid-template-columns: minmax(0, 1fr); max-width: 520px; }
  .gallery-controls { top: 0; }
  .nots { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .calc { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  .ladder { grid-template-columns: minmax(0, 1fr); gap: 26px; }
}

@media (max-width: 620px) {
  body { font-size: 1rem; }
  .card { padding: 22px; }
  .plan { padding: 26px; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 30px; }
  .conn-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .node-grid { grid-template-columns: minmax(0, 1fr); }
  table.matrix td:not(:first-child), table.matrix th:not(:first-child) { width: 110px; }
  table.matrix th, table.matrix td { padding: 13px 14px; }
  .nots { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .not { padding: 18px 18px 16px; }
  .calc-side { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 16px 18px; }
  .calc-amt { font-size: 1.35rem; text-align: left; }
  .ladder { padding: 20px; }
  .ladder-steps li { grid-template-columns: 5.4rem 5.2rem; padding: 11px 14px; }
  .ladder-steps i { grid-column: 1 / -1; }
}

/* --------------------------------------------------------------------------
   19. Reduced motion — the hero settles into its finished state
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  html.js .reveal { opacity: 1; transform: none; }
  .aurora i { animation: none; }
  .canvas-edges path.hot { stroke-dasharray: none; }
  .node .node-status { opacity: 1; transform: none; background: var(--success); }
  .node .node-rows { opacity: 1; }
}

@media print {
  .nav, .footer, .aurora, .grain, .vignette { display: none; }
  .band-dark { background: #fff; color: #000; }
}
