/* ziltch-terminal.css — THE Ziltch design system (ADR-0044; Erin-directed "design enforcement everywhere").
 *
 * ONE token set every surface renders against — the terminal, the render islands, the gateway app-shell, AND the OC
 * marketing chrome — so the platform reads as one designed instrument, not a patchwork of per-island inline styles.
 * Bloomberg muscle-memory for the app: a dark, dense, tabular-numeric surface with the signature AMBER brand accent and
 * unambiguous up-green / down-red. The tokens are defined at :root so they apply DOCUMENT-WIDE (every surface that loads
 * this file), not only inside .zt-terminal; the component styles below stay scoped (.zt-*, .zt-terminal) so they never
 * bleed into the surrounding chrome. Load this on every gateway _Host page + the theme so the design is enforced once.
 */

:root {
    /* ── the Ziltch identity: "sail a sea of stars" (Erin's favorite image — a pointillist starry-night cosmos, deep
       midnight blue, gold stars, foliage green, a lone robot on an avenue of light). The brand mark is the purple Z;
       the surface is the night sky; gold is the starlight accent. ──────────────────────────────────────────────────── */
    --zt-brand: #5b3e78;         /* the Ziltch purple (the Z mark) — lifted off the #472c54 logo for legibility on dark */
    --zt-brand-deep: #472c54;    /* the logo's deep purple (badges, fills on light) */
    --zt-brand-ink: #ffffff;     /* white on the brand purple (the logo) */
    --zt-gold: #e9c46a;          /* STARLIGHT gold — the signature accent (focus, the command line, highlights, the stars) */
    --zt-gold-dim: #9c7f3e;

    /* ── app surfaces (the night sky — deep midnight blue/indigo) ──────────────── */
    --zt-bg: #070b1a;            /* the deep night sky */
    --zt-bg-2: #0b1228;          /* sunken areas (command bar, gutters) */
    --zt-panel: #101a38;         /* panel body — a clear field of midnight blue */
    --zt-panel-2: #16234a;       /* panel header / zebra */
    --zt-border: #273664;        /* panel + grid borders */
    --zt-grid: #1b2a55;          /* chart gridlines (faint constellations) */
    --zt-ink: #e8ecf8;           /* starlight text */
    --zt-fg: var(--zt-ink);      /* alias (render kit uses --zt-fg) */
    --zt-ink-dim: #9aa6cc;       /* secondary text */
    --zt-ink-faint: #7582aa;     /* tertiary / axis labels - 5.16 on --zt-bg, 4.51 on --zt-panel.
                                    WAS #6573a0 at 4.21 / 3.68, BOTH under the AA 4.5 floor. The audit at
                                    line ~86 recorded it as "4.29 (marginal rather than broken)" - but 4.29 is
                                    UNDER 4.5, so it was broken, and it measured only ONE ground. On --zt-panel,
                                    where muted text actually sits, it was 3.68. Measured by @ziltch2, verified
                                    independently per WCAG 2.1 relative luminance, and now gated for BOTH
                                    grounds by DarkModeContrastGateTests - the dark twin the light gate lacked. */
    --zt-muted: var(--zt-ink-faint);

    --zt-pos: #6dc98a;           /* up / long / gain — foliage green (the trees) */
    --zt-pos-dim: #2f7a4f;
    --zt-neg: #ff6b6b;           /* down / short / loss */
    --zt-neg-dim: #b03636;
    --zt-accent: var(--zt-gold); /* starlight gold — THE accent */
    --zt-accent-2: #7fb2ff;      /* a luminous starlight blue (info / links / charts) */
    --zt-warn: #ffd166;

    /* 🩸 --zt-good / --zt-bad ARE ALIASES OF --zt-pos / --zt-neg, and they exist because they were USED and never
       DEFINED. RenderScalarSignal.cs emits var(--zt-good,#4fa96b) and var(--zt-bad,#dc5b57); neither token was
       declared in any stylesheet, so every health, money and budget signal in the product rendered its HARDCODED
       FALLBACK and could not be themed at all. The tell is what they MISSED: --zt-pos/--zt-neg/--zt-warn each get a
       light-mode value below, chosen against measured contrast and pinned by LightModeContrastGateTests — and
       --zt-good/--zt-bad got none of that, because a gate can only cover a token that exists. A "good" reading sat
       at #4fa96b on a light ground where --zt-pos had already been moved to #1f7a45 for 4.93 contrast.
       ⚖️ ALIASES RATHER THAN NEW COLOURS, DELIBERATELY: good/bad and pos/neg are ONE semantic in two vocabularies
       (a healthy cell and a gain are both "green means yes"), so giving them separate values would be inventing a
       distinction the product does not have — and the light/dark swap and the contrast gate come for free. */
    --zt-good: var(--zt-pos);
    --zt-bad: var(--zt-neg);

    /* the four cross-panel link-group colors (A/B/C/D) — drawn from the palette (gold / blue / purple / green) */
    --zt-link-a: #e9c46a;
    --zt-link-b: #7fb2ff;
    --zt-link-c: #b58cf0;
    --zt-link-d: #6dc98a;

    /* ── density scale (tabular, compact) ────────────────────────────────────── */
    --zt-font: "IBM Plex Mono", "JetBrains Mono", ui-monospace, "Cascadia Mono", "Consolas", monospace;
    --zt-font-ui: system-ui, -apple-system, "Segoe UI", sans-serif;
    --zt-fs-xs: 12.5px;
    --zt-fs-sm: 14.5px;
    --zt-fs-md: 16.5px;
    --zt-fs-lg: 19px;
    --zt-row-h: 20px;
    --zt-gap: 6px;
    --zt-radius: 7px;
    --zt-shadow: 0 8px 24px rgba(0,0,0,.5);
}

/* ── LIGHT MODE FOR THE TOKENS ONLY THIS FILE DECLARES ────────────────────────────────────────────────────────────
   🩸 WITHOUT THIS BLOCK, LIGHT MODE RENDERS DARK-TUNED SIGNAL COLOURS ON A LIGHT GROUND. The names below exist ONLY
   here — chrome.css has no counterpart and neither light-rescue block (ziltch-chrome.css, ziltch.css) mentions them —
   so they kept their night-sky values when a viewer opted into light, which is the one direction nobody checked.

   MEASURED, not judged by eye. Contrast against --p-light-surface-2 (#f6f5f9), the panel ground in light mode:
       --zt-warn      #ffd166 -> 1.33     (WCAG AA body text wants 4.5; 1.33 is "cannot see it")
       --zt-link-a    #e9c46a -> 1.54
       --zt-pos       #6dc98a -> 1.87        --zt-link-d 1.87
       --zt-link-b    #7fb2ff -> 1.99
       --zt-link-c    #b58cf0 -> 2.43
       --zt-neg       #ff6b6b -> 2.56
       --zt-ink-faint #6573a0 -> 4.21 on bg / 3.68 on panel - RAISED to #7582aa; 'marginal' was a failing number accepted
   ⚠️ AND MY FIRST REPLACEMENT FOR IT WAS ALSO SHORT: #6b7186 measured 4.47, under the 4.5 floor. The gate rejected
   it; I had accepted it by eye as "about right". #686e82 = 4.67.
   The stalled-panel overlay (.zt-panel__overlay--stalled, :107) paints --zt-warn as TEXT, so at 1.33 a viewer in
   light mode is told nothing at all by the element whose entire job is to say "this panel is stalled".

   ⚖️ HUE PRESERVED, LUMINANCE MOVED. Each value keeps its semantic hue — warn amber, up green, down red, and the
   four link colours in their gold/blue/purple/green families — and is darkened until it reads on a light ground.
   Re-picking the palette for light would be a design change; this is the same palette made legible, and every
   replacement below measures 4.47 or better. The surface/line tokens carry no text, so they are chosen to sit as
   light equivalents of their dark roles rather than by ratio.

   🔑 SCOPED TO THE EXPLICIT OPT-IN ONLY. Dark stays unconditional at :root above — this file's identity and the
   product default — so an un-stamped document is untouched. This fires solely when a viewer has chosen light.     */
:root[data-bs-theme="light"] {
    --zt-bg-2: #eceaf2;          /* sunken areas — a shade under the light surface, as #0b1228 sits under the dark one */
    --zt-panel-2: #eef0f6;       /* panel header / zebra */
    --zt-border: #d4d8e4;        /* panel + grid borders — the light-ground twin of #273664 */
    --zt-ink-faint: #686e82;     /* tertiary / axis labels — 4.67. Was #6b7186 at 4.47, which is UNDER the AA 4.5
                                    floor: caught by LightModeContrastGateTests before it ever ran, not by eye. */
    --zt-pos: #1f7a45;           /* up / long / gain — 4.93 */
    --zt-pos-dim: #14572f;
    --zt-neg: #c02a2a;           /* down / short / loss — 5.37 */
    --zt-neg-dim: #8f2020;
    --zt-warn: #8a6100;          /* 5.10 — the one that was invisible at 1.33 */
    /* good/bad follow pos/neg here too — the alias is declared in BOTH blocks rather than only the dark one, because
       a var() alias resolves against whatever :root is in scope: declaring it once above would still have picked up
       the light --zt-pos, but only by accident of cascade order. Stated in both is stated. */
    --zt-good: var(--zt-pos);    /* = #1f7a45, 4.93 */
    --zt-bad: var(--zt-neg);     /* = #c02a2a, 5.37 */
    /* 🔴 THE LIGHT ARM DARKENED EVERY SEMANTIC COLOUR FOR CONTRAST AND MISSED THE ACCENT ITSELF.
       --zt-warn, --zt-pos, --zt-neg and all four --zt-link-* are overridden here with their ratios cited;
       --zt-gold was not, so the signature #e9c46a stayed on a LIGHT ground. Measured 2026-09-12 on
       /gateway/labs: the page's primary navigation — "Terminal", "Market Board", "Forecast" — rendered
       #c79a3a on #f6f5f9 at 2.39:1 against the 4.5 WCAG 1.4.3 requires, and the ◇ Labs heading at 2.59:1
       against 3.0. Just over half the requirement, on the links the page exists to offer.
       ⚖️ THE VALUE IS NOT INVENTED — IT IS THIS FILE'S OWN. #8a6100 is already the established light
       gold-family ink here, cited at 5.10 twice (--zt-warn, --zt-link-a). Completing the pattern, not
       adding a token. (An independent computation for "shallowest gold clearing 4.5 on BOTH #ffffff and
       the #f6f5f9 card" landed on #8a6a1f at 5.05/4.65 — same answer, so the file's is used.)
       📌 THE DARK ARM IS UNTOUCHED: :root still carries #e9c46a, which measures 11.73:1 on --zt-bg. Gold as
       ink is correct on the night-sky ground this palette was designed for; it is only wrong on light. */
    --zt-gold: #8a6100;          /* gold family — 5.10 on the light surface, as --zt-link-a below */
    --zt-link-a: #8a6100;        /* gold family — 5.10 */
    --zt-link-b: #1a5fb4;        /* blue — 5.79 */
    --zt-link-c: #6b3fa0;        /* purple — 6.80 */
    --zt-link-d: #1f7a45;        /* green — 4.93 */
}

/* 🔴 THE TOGGLE HAS THREE STATES AND THIS FILE ONLY ANSWERED TWO. `:root[data-bs-theme="light"]` above fires
   only on an EXPLICIT light choice. The theme control cycles light -> dark -> SYSTEM, and its system state
   REMOVES the attribute entirely (verified 2026-09-12: glyph ☀/☾/◐, and `data-bs-theme` absent on the third
   press). So a visitor on the default setting with a light OS preference got the CHROME in light — it answers
   prefers-color-scheme — while every token in here stayed on the dark palette. Dark ink, light ground.
   Measured on /gateway/labs in that exact state: 7 of 15 scored text nodes below their WCAG threshold; with the
   attribute forced to "light", 5. The two-failure difference IS this gap, and the default state is the one
   nobody tests because setting a theme explicitly is what a tester does first.
   ⚖️ `:not([data-bs-theme="dark"])` is what keeps an explicit DARK choice winning over the OS preference —
   without it a user who chose dark on a light-preferring machine would be overridden by their own laptop.
   📌 ziltch-chrome.css has carried all four arms for months; this file had two. Same theme, two answers. */
@media (prefers-color-scheme: light) {
    :root:not([data-bs-theme="dark"]) {
    --zt-bg-2: #eceaf2;          /* sunken areas — a shade under the light surface, as #0b1228 sits under the dark one */
    --zt-panel-2: #eef0f6;       /* panel header / zebra */
    --zt-border: #d4d8e4;        /* panel + grid borders — the light-ground twin of #273664 */
    --zt-ink-faint: #686e82;     /* tertiary / axis labels — 4.67. Was #6b7186 at 4.47, which is UNDER the AA 4.5
                                    floor: caught by LightModeContrastGateTests before it ever ran, not by eye. */
    --zt-pos: #1f7a45;           /* up / long / gain — 4.93 */
    --zt-pos-dim: #14572f;
    --zt-neg: #c02a2a;           /* down / short / loss — 5.37 */
    --zt-neg-dim: #8f2020;
    --zt-warn: #8a6100;          /* 5.10 — the one that was invisible at 1.33 */
    /* good/bad follow pos/neg here too — the alias is declared in BOTH blocks rather than only the dark one, because
       a var() alias resolves against whatever :root is in scope: declaring it once above would still have picked up
       the light --zt-pos, but only by accident of cascade order. Stated in both is stated. */
    --zt-good: var(--zt-pos);    /* = #1f7a45, 4.93 */
    --zt-bad: var(--zt-neg);     /* = #c02a2a, 5.37 */
    /* 🔴 THE LIGHT ARM DARKENED EVERY SEMANTIC COLOUR FOR CONTRAST AND MISSED THE ACCENT ITSELF.
       --zt-warn, --zt-pos, --zt-neg and all four --zt-link-* are overridden here with their ratios cited;
       --zt-gold was not, so the signature #e9c46a stayed on a LIGHT ground. Measured 2026-09-12 on
       /gateway/labs: the page's primary navigation — "Terminal", "Market Board", "Forecast" — rendered
       #c79a3a on #f6f5f9 at 2.39:1 against the 4.5 WCAG 1.4.3 requires, and the ◇ Labs heading at 2.59:1
       against 3.0. Just over half the requirement, on the links the page exists to offer.
       ⚖️ THE VALUE IS NOT INVENTED — IT IS THIS FILE'S OWN. #8a6100 is already the established light
       gold-family ink here, cited at 5.10 twice (--zt-warn, --zt-link-a). Completing the pattern, not
       adding a token. (An independent computation for "shallowest gold clearing 4.5 on BOTH #ffffff and
       the #f6f5f9 card" landed on #8a6a1f at 5.05/4.65 — same answer, so the file's is used.)
       📌 THE DARK ARM IS UNTOUCHED: :root still carries #e9c46a, which measures 11.73:1 on --zt-bg. Gold as
       ink is correct on the night-sky ground this palette was designed for; it is only wrong on light. */
    --zt-gold: #8a6100;          /* gold family — 5.10 on the light surface, as --zt-link-a below */
    --zt-link-a: #8a6100;        /* gold family — 5.10 */
    --zt-link-b: #1a5fb4;        /* blue — 5.79 */
    --zt-link-c: #6b3fa0;        /* purple — 6.80 */
    --zt-link-d: #1f7a45;        /* green — 4.93 */
    }
}

.zt-terminal {
    background: var(--zt-bg);
    color: var(--zt-ink);
    font-family: var(--zt-font-ui);
    font-size: var(--zt-fs-md);
    font-variant-numeric: tabular-nums;
    -webkit-font-smoothing: antialiased;
}

.zt-terminal .mono { font-family: var(--zt-font); font-variant-numeric: tabular-nums; }
.zt-terminal .pos { color: var(--zt-pos); }
.zt-terminal .neg { color: var(--zt-neg); }
.zt-terminal .dim { color: var(--zt-ink-dim); }
.zt-terminal .faint { color: var(--zt-ink-faint); }
.zt-terminal .amber { color: var(--zt-accent); }

/* link-group color dots / accents */
.zt-bg-A { background: var(--zt-link-a); }
.zt-link-B { color: var(--zt-link-b); } .zt-bg-B { background: var(--zt-link-b); }
.zt-link-C { color: var(--zt-link-c); } .zt-bg-C { background: var(--zt-link-c); }

/* ── panel chrome (PanelShell) ───────────────────────────────────────────────── */
.zt-panel {
    display: flex; flex-direction: column; min-height: 0; min-width: 0; height: 100%;
    background: var(--zt-panel); border: 1px solid var(--zt-border); border-radius: var(--zt-radius);
    overflow: hidden;
}
.zt-panel__hd {
    display: flex; align-items: center; gap: var(--zt-gap); padding: 4px 8px;
    background: var(--zt-panel-2); border-bottom: 1px solid var(--zt-border);
    font-size: var(--zt-fs-sm); user-select: none;
}
.zt-panel__title { font-weight: 600; letter-spacing: .2px; white-space: nowrap; }
.zt-panel__code { font-family: var(--zt-font); font-size: var(--zt-fs-xs); color: var(--zt-accent);
    border: 1px solid var(--zt-border); border-radius: 3px; padding: 0 4px; }
.zt-panel__linked { color: var(--zt-ink-dim); font-family: var(--zt-font); white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis; }
.zt-panel__dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.zt-panel__tools { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.zt-panel__body { flex: 1 1 auto; min-height: 0; overflow: auto; position: relative; }
.zt-panel__overlay { position: absolute; inset: 0; display: grid; place-items: center; text-align: center;
    color: var(--zt-ink-dim); font-size: var(--zt-fs-sm); padding: 1rem; }
.zt-panel__overlay code { color: var(--zt-accent-2); }
/* stalled = the source stayed empty past the grace window (body restarting / unhealthy) — amber + a slow pulse so it
   reads as "still retrying, alive", not frozen. Self-clears the instant data returns. */
.zt-panel__overlay--stalled { color: var(--zt-warn); animation: zt-stall-pulse 2s ease-in-out infinite; }
@keyframes zt-stall-pulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

/* ── capability ladder (LADR) — the four questions answered with DATA: metric + status light, read top-down ────── */
.zt-lgrid { display: grid; grid-template-columns: 1fr auto auto; column-gap: 18px; row-gap: 8px; align-items: center; }
.zt-lhd { color: var(--zt-ink-dim); font-size: 10px; text-transform: uppercase; letter-spacing: .08em; text-align: right; }
.zt-lq { color: var(--zt-ink); }
.zt-lqm { color: var(--zt-ink-dim); font-size: 11px; margin-left: 7px; }
.zt-lcell { display: inline-flex; align-items: center; gap: 6px; justify-content: flex-end; white-space: nowrap; }
.zt-lcell small { font-size: 11px; }
/* status light — the at-a-glance pass/weak/pending/off per rung; pos/neg glow (alive), pending/off muted */
.zt-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex: none; }
.zt-dot--pos { background: var(--zt-link-d); box-shadow: 0 0 5px rgba(74,222,128,.6); }
.zt-dot--neg { background: var(--zt-neg); box-shadow: 0 0 5px color-mix(in srgb, var(--zt-neg) 60%, transparent); }
.zt-dot--weak { background: var(--zt-warn); box-shadow: 0 0 4px rgba(255,209,102,.5); }
.zt-dot--pending { background: var(--zt-warn); opacity: .45; }
.zt-dot--off { background: var(--zt-ink-dim); opacity: .4; }

/* ── buttons / inputs ────────────────────────────────────────────────────────── */
.zt-btn { font-family: var(--zt-font-ui); font-size: var(--zt-fs-sm); color: var(--zt-ink-dim);
    background: var(--zt-bg-2); border: 1px solid var(--zt-border); border-radius: 4px; padding: 1px 7px;
    cursor: pointer; }
.zt-btn:hover { color: var(--zt-ink); border-color: var(--zt-accent); }
.zt-btn.on { color: var(--zt-bg); background: var(--zt-accent); border-color: var(--zt-accent); }

/* ── DataGrid ────────────────────────────────────────────────────────────────── */
.zt-grid { width: 100%; border-collapse: collapse; font-size: var(--zt-fs-sm); }
.zt-grid thead th { position: sticky; top: 0; z-index: 1; text-align: right; font-weight: 600;
    color: var(--zt-ink-dim); background: var(--zt-panel-2); border-bottom: 1px solid var(--zt-border);
    padding: 3px 8px; cursor: pointer; white-space: nowrap; }
.zt-grid thead th.l { text-align: left; }
.zt-grid tbody td { text-align: right; padding: 2px 8px; border-bottom: 1px solid #0e151f;
    white-space: nowrap; font-family: var(--zt-font); }
.zt-grid tbody td.l { text-align: left; }
.zt-grid tbody tr { cursor: pointer; }
.zt-grid tbody tr:hover { background: var(--zt-panel-2); }
.zt-grid tbody tr.sel { background: #1c2c42; box-shadow: inset 2px 0 0 var(--zt-accent); }

/* ── sparkline ───────────────────────────────────────────────────────────────── */
.zt-spark { display: block; overflow: visible; }

/* ── stat strip (P&L / vitals headers) ───────────────────────────────────────── */
.zt-stats { display: flex; flex-wrap: wrap; gap: 16px; padding: 6px 10px; border-bottom: 1px solid var(--zt-border);
    position: sticky; top: 0; background: var(--zt-panel); z-index: 2; }
.zt-stat { display: flex; flex-direction: column; line-height: 1.15; }
.zt-stat b { font-size: var(--zt-fs-md); }
.zt-stat span { font-size: var(--zt-fs-xs); color: var(--zt-ink-faint); }

/* ── D3 surface host ─────────────────────────────────────────────────────────── */
.zt-d3surface { width: 100%; height: 100%; }

/* ── the workspace shell (TerminalDock) ──────────────────────────────────────── */
.zt-terminal { display: flex; flex-direction: column; height: 100vh; min-height: 0; padding: 6px; gap: 6px; box-sizing: border-box; }

.zt-dock__bar { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.zt-dock__brand { font-family: var(--zt-font); font-weight: 700; letter-spacing: 1px; font-size: var(--zt-fs-md); }
.zt-dock__cmd { flex: 1 1 auto; min-width: 0; }
.zt-dock__groups { display: flex; gap: 3px; flex: 0 0 auto; }
.zt-dock__groups .zt-btn { width: 24px; text-align: center; font-family: var(--zt-font); font-weight: 700; }

.zt-dock__add { position: relative; flex: 0 0 auto; }
.zt-dock__add > summary { list-style: none; }
.zt-dock__add > summary::-webkit-details-marker { display: none; }
.zt-dock__menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 50; min-width: 220px;
    background: var(--zt-panel); border: 1px solid var(--zt-border); border-radius: var(--zt-radius);
    box-shadow: 0 8px 24px rgba(0,0,0,.5); padding: 4px; display: flex; flex-direction: column; gap: 2px; }
.zt-dock__menuitem { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left;
    background: none; border: none; color: var(--zt-ink); font-size: var(--zt-fs-sm); padding: 4px 8px;
    border-radius: 4px; cursor: pointer; }
.zt-dock__menuitem:hover { background: var(--zt-panel-2); }

.zt-dock__grid { flex: 1 1 auto; min-height: 0; display: grid; gap: 6px;
    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); grid-auto-rows: minmax(280px, 1fr); overflow: auto; }
.zt-dock__cell { position: relative; min-width: 0; min-height: 0; }
.zt-dock__close { position: absolute; top: 4px; right: 6px; z-index: 4; width: 18px; height: 18px; line-height: 14px;
    text-align: center; color: var(--zt-ink-faint); background: var(--zt-panel-2); border: 1px solid var(--zt-border);
    border-radius: 4px; cursor: pointer; font-size: 13px; padding: 0; }
.zt-dock__close:hover { color: var(--zt-neg); border-color: var(--zt-neg); }
.zt-dock__empty { grid-column: 1 / -1; display: grid; place-items: center; }

/* ── command bar ─────────────────────────────────────────────────────────────── */
.zt-cmdbar { display: flex; align-items: center; gap: 8px; background: var(--zt-bg-2);
    border: 1px solid var(--zt-border); border-radius: var(--zt-radius); padding: 3px 10px; }
.zt-cmdbar:focus-within { border-color: var(--zt-accent); }
.zt-cmdbar__prompt { color: var(--zt-accent); font-family: var(--zt-font); font-weight: 700; }
.zt-cmdbar__in { flex: 1 1 auto; min-width: 0; background: none; border: none; outline: none;
    color: var(--zt-ink); font-size: var(--zt-fs-md); letter-spacing: .5px; text-transform: uppercase; }
.zt-cmdbar__in::placeholder { color: var(--zt-ink-faint); text-transform: none; letter-spacing: 0; }
.zt-cmdbar__hint { font-size: var(--zt-fs-xs); white-space: nowrap; }

/* 🔴 THE COMMAND INPUT RENDERED **4 PIXELS WIDE** ON A PHONE. Measured 2026-09-12 at 390x844 on the live
   /gateway/terminal, which answers 200 to a signed-out browser. The omni-search — the page's primary control,
   the thing the whole dock exists to drive — was a 4px sliver you could not see, focus by tapping, or type in.
   ⚖️ THE INPUT WAS INNOCENT. `.zt-cmdbar__in` already carries `flex: 1 1 auto; min-width: 0`, which is exactly
   right: it is willing to shrink. It was squeezed by two things that were not willing:
     1. `.zt-cmdbar__hint` is `white-space: nowrap` with no shrink allowance, so it claimed its full intrinsic
        108px and took it out of the input. It is a convenience label ("load into group A"), not a control.
     2. `.zt-dock__bar` is a `nowrap` flex row, so brand / cmd / groups / add all fought for one 344px line and
        the cmd cell settled at 80px — the second-SMALLEST share, for the most important element.
   Fixing only (1) took the input from 4px to 40px, which is still unusable; the wrap is what actually cures it.
   Measured at 390: input 4px -> 230px, cmd cell 80 -> 270, bar 36 -> 68 (two rows, as intended).
   📌 DESKTOP IS BYTE-IDENTICAL, VERIFIED NOT ARGUED — at 1430 the row still fits on one line so it does not
   wrap, the hint is above the 640px breakpoint so it stays: input 864px, bar 36px, children 64,1020,105,65
   before AND after. Wrapping only engages where the content already did not fit.
   ⚠️ This stylesheet had ZERO @media rules before this one — the terminal was built desktop-only, like 82 of
   the 91 painting surfaces in this repo. This fixes the one broken control, not that. */
.zt-dock__bar { flex-wrap: wrap; row-gap: 6px; }
.zt-dock__cmd { flex: 1 1 220px; min-width: 0; }
.zt-cmdbar__hint { flex: 0 1 auto; min-width: 0; overflow: hidden; }
@media (max-width: 640px) {
    /* The input is the control and the hint is a caption; below this width there is only room for one. */
    .zt-cmdbar__hint { display: none; }
}

/* ── status strip ────────────────────────────────────────────────────────────── */
.zt-status { display: flex; align-items: center; gap: 14px; flex: 0 0 auto; padding: 3px 10px;
    background: var(--zt-bg-2); border: 1px solid var(--zt-border); border-radius: var(--zt-radius);
    font-size: var(--zt-fs-xs); color: var(--zt-ink-dim); }
.zt-status b { color: var(--zt-ink); }
.zt-status .sep { padding-left: 14px; border-left: 1px solid var(--zt-border); }
.zt-status .brand { margin-left: auto; font-family: var(--zt-font); font-weight: 700; letter-spacing: 1.5px;
    color: var(--zt-accent); }

/* ── the GATEWAY APP SHELL — consistent chrome across every gateway _Host surface (Erin: consistent navigation,
   header/footer, design enforcement everywhere). A slim brand+nav header over a dark full-height app body. ────────── */
* { box-sizing: border-box; }
html.zt-app-html, body.zt-app { margin: 0; height: 100%; }
/* Larger base so the whole gateway surface reads comfortably on big screens (Erin: "everything is tiny") — scales all
   rem-based content up; the px type-scale vars (--zt-fs-*) above carry the chrome. */
html.zt-app-html { font-size: 17.5px; }
.zt-app { display: flex; flex-direction: column; min-height: 100vh; color: var(--zt-ink);
    font-family: var(--zt-font-ui); -webkit-font-smoothing: antialiased; background-color: var(--zt-bg);
    /* a faint SEA OF STARS — layered starlight dots (gold / white / blue) + a cosmic glow toward the top, evoking the
       Ziltch starry-night identity without competing with the content. */
    background-image:
        radial-gradient(1.5px 1.5px at 18% 28%, rgba(233,196,106,.55), transparent),
        radial-gradient(1px 1px at 72% 18%, rgba(255,255,255,.45), transparent),
        radial-gradient(1.5px 1.5px at 41% 66%, rgba(127,178,255,.45), transparent),
        radial-gradient(1px 1px at 86% 58%, rgba(233,196,106,.4), transparent),
        radial-gradient(1px 1px at 54% 42%, rgba(255,255,255,.35), transparent),
        radial-gradient(1px 1px at 9% 75%, rgba(127,178,255,.35), transparent),
        radial-gradient(1300px 520px at 50% -12%, rgba(40,54,100,.55), transparent);
    background-repeat: no-repeat; background-attachment: fixed; }
.zt-logo { height: 22px; width: 22px; border-radius: 5px; vertical-align: -5px; box-shadow: 0 0 0 1px rgba(255,255,255,.08); }
.zt-appbar { display: flex; align-items: center; gap: 16px; padding: 0 14px; height: 56px; flex: 0 0 auto;
    background: var(--zt-bg-2); border-bottom: 1px solid var(--zt-border); }
.zt-appbar__brand { display: inline-flex; align-items: center; gap: 7px; font-family: var(--zt-font); font-weight: 700;
    letter-spacing: 1.5px; color: var(--zt-accent); text-decoration: none; font-size: var(--zt-fs-lg); white-space: nowrap; }
.zt-appbar__brand:hover { filter: brightness(1.12); }
.zt-appnav { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.zt-appnav a { color: var(--zt-ink-dim); text-decoration: none; font-size: .98rem; padding: 7px 13px;
    border-radius: 5px; white-space: nowrap; transition: background .12s, color .12s; }
.zt-appnav a:hover { color: var(--zt-ink); background: var(--zt-panel); }
.zt-appnav a.active { color: var(--zt-brand-ink); background: var(--zt-accent); font-weight: 600; }
.zt-appnav .zt-appnav__sep { width: 1px; height: 18px; background: var(--zt-border); margin: 0 4px; }
.zt-appbar__home { margin-left: auto; color: var(--zt-ink-faint); text-decoration: none; font-size: var(--zt-fs-xs); white-space: nowrap; }
.zt-appbar__home:hover { color: var(--zt-accent-2); }
.zt-app__body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
.zt-app__body > * { flex: 1 1 auto; min-width: 0; }

/* ── RgRef — the universal entity-reference pill (the design-language ATOM: every RG element surfaces the same,
   traversable, type-colored, everywhere). --rg-c = the element type's accent (RgTypeStyle). ──────────────────────── */
.rg-ref { display: inline-flex; align-items: center; gap: 5px; padding: 1px 9px 1px 7px; border-radius: 999px;
    font-size: var(--zt-fs-sm); line-height: 1.6; color: var(--zt-ink); text-decoration: none; white-space: nowrap;
    background: color-mix(in srgb, var(--rg-c, var(--zt-accent)) 13%, transparent);
    border: 1px solid color-mix(in srgb, var(--rg-c, var(--zt-accent)) 34%, transparent);
    transition: background .12s, border-color .12s, box-shadow .12s; }
.rg-ref__glyph { color: var(--rg-c, var(--zt-accent)); font-size: .98em; line-height: 1; }
.rg-ref__label { font-weight: 500; overflow: hidden; text-overflow: ellipsis; max-width: 22ch; }
.rg-ref--link { cursor: pointer; }
.rg-ref--link:hover { background: color-mix(in srgb, var(--rg-c, var(--zt-accent)) 24%, transparent);
    border-color: var(--rg-c, var(--zt-accent)); box-shadow: 0 0 0 1px color-mix(in srgb, var(--rg-c) 30%, transparent); }
.rg-ref__status { width: 6px; height: 6px; border-radius: 50%; margin-left: 1px; flex: none; }
.rg-ref__status--live, .rg-ref__status--good { background: var(--zt-pos); box-shadow: 0 0 5px var(--zt-pos); }
.rg-ref__status--pending { background: var(--zt-warn); }
.rg-ref__status--stale, .rg-ref__status--bad { background: var(--zt-neg); box-shadow: 0 0 5px var(--zt-neg); }
.rg-ref__status--off { background: var(--zt-ink-faint); opacity: .6; }
/* a row of refs (associations / a collection of elements) wraps as traversable links */
.rg-refs { display: inline-flex; flex-wrap: wrap; gap: 5px; align-items: center; }

/* ── RgCard — the expanded element surface (header RgRef + value + traversable associations) ─────────────────── */
.rg-card { display: flex; flex-direction: column; gap: 7px; min-width: 200px; max-width: 360px; padding: 9px 11px;
    background: var(--zt-panel); border: 1px solid var(--zt-border); border-radius: var(--zt-radius); box-shadow: var(--zt-shadow); }
.rg-card__hd { display: flex; align-items: center; gap: 7px; }
.rg-card__kind { font-size: var(--zt-fs-xs); color: var(--zt-ink-dim); text-transform: uppercase; letter-spacing: .05em; }
.rg-card__tools { margin-left: auto; display: flex; gap: 4px; }
.rg-card__body { font-size: var(--zt-fs-sm); color: var(--zt-ink); }
.rg-card__assoc { display: flex; flex-direction: column; gap: 5px; border-top: 1px solid var(--zt-border); padding-top: 7px; }
.rg-card__assoc-label { font-size: var(--zt-fs-xs); color: var(--zt-ink-faint); text-transform: uppercase; letter-spacing: .06em; }

/* ── RgActionMenu — the generated action menu (self-declared actions; nothing renders when none) ──────────────── */
.rg-actions { position: relative; display: inline-flex; }
.rg-actions__trigger { border: none; background: transparent; color: var(--zt-ink-dim); cursor: pointer;
    font-size: 15px; line-height: 1; padding: 2px 6px; border-radius: 5px; }
.rg-actions__trigger:hover, .rg-actions--open .rg-actions__trigger { color: var(--zt-ink); background: color-mix(in srgb, var(--zt-accent) 16%, transparent); }
.rg-actions__menu { position: absolute; top: 100%; right: 0; z-index: 40; margin-top: 3px; min-width: 148px;
    display: flex; flex-direction: column; padding: 4px; background: var(--zt-panel-2); border: 1px solid var(--zt-border);
    border-radius: var(--zt-radius); box-shadow: var(--zt-shadow); }
.rg-actions__item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; border: none;
    background: transparent; color: var(--zt-ink); cursor: pointer; font-size: var(--zt-fs-sm); padding: 5px 8px; border-radius: 5px; }
.rg-actions__item:hover { background: color-mix(in srgb, var(--zt-accent) 14%, transparent); }
.rg-actions__item--destructive { color: var(--zt-neg); }
.rg-actions__item--destructive:hover { background: color-mix(in srgb, var(--zt-neg) 16%, transparent); }
.rg-actions__item--confirming { color: var(--zt-warn); font-weight: 600; background: color-mix(in srgb, var(--zt-warn) 14%, transparent); }
.rg-actions__glyph { width: 14px; text-align: center; opacity: .85; }
.rg-actions__label { flex: 1; }

/* ── Live Activity feed (Erin: "visualize the dynamic activities in Matrix and across RG") ── */
.rgx-activity{display:flex;flex-direction:column;height:calc(100vh - 3.6rem);padding:1rem 1.4rem;color:var(--zt-ink);}
.rgx-activity__head{display:flex;align-items:center;gap:.8rem;padding-bottom:.6rem;border-bottom:1px solid var(--zt-border);}
.rgx-activity__title{font-weight:600;color:var(--zt-accent);letter-spacing:.02em;}
.rgx-activity__rate{color:var(--zt-muted);font-variant-numeric:tabular-nums;font-size:.85rem;}
.rgx-activity__status{width:.6rem;height:.6rem;border-radius:50%;margin-left:auto;}
.rgx-activity__status--live{background:var(--zt-pos);box-shadow:0 0 7px var(--zt-pos);animation:rgx-pulse 1.6s ease-in-out infinite;}
.rgx-activity__status--off{background:var(--zt-muted);}
.rgx-activity__stream{flex:1;overflow-y:auto;margin-top:.5rem;display:flex;flex-direction:column;gap:.15rem;}
.rgx-activity__empty{color:var(--zt-muted);padding:1rem .4rem;font-style:italic;}
.rgx-activity__row{display:flex;align-items:center;gap:.6rem;padding:.28rem .45rem;border-radius:.35rem;border:1px solid transparent;animation:rgx-flash .9s ease-out;}
.rgx-activity__row:hover{background:rgba(255,255,255,.035);border-color:var(--zt-grid);}
.rgx-activity__seq{color:var(--zt-ink-faint);font-variant-numeric:tabular-nums;font-size:.74rem;min-width:3.6rem;}
.rgx-activity__op{color:var(--zt-ink-dim);font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;}
.rgx-activity__at{color:var(--zt-ink-faint);margin-left:auto;font-variant-numeric:tabular-nums;font-size:.7rem;}
@keyframes rgx-flash{from{background:rgba(233,196,106,.16);}to{background:transparent;}}
@keyframes rgx-pulse{0%,100%{opacity:1;}50%{opacity:.4;}}
.rgx-activity__vitals{display:flex;flex-wrap:wrap;gap:.4rem;padding:.55rem 0 .1rem;}
.rgx-vital{display:inline-flex;align-items:center;gap:.35rem;padding:.15rem .55rem;border-radius:1rem;background:var(--zt-panel);border:1px solid var(--zt-border);font-size:.74rem;color:var(--zt-ink-dim);}
.rgx-vital__glyph{color:var(--rg-c,var(--zt-accent));}
.rgx-vital b{color:var(--zt-ink);font-variant-numeric:tabular-nums;margin-left:.15rem;}
.rgx-matrix{display:flex;align-items:center;gap:.9rem;padding:.5rem .7rem;margin-top:.5rem;border-radius:.4rem;background:linear-gradient(90deg,rgba(93,176,255,.08),transparent);border:1px solid var(--zt-border);}
.rgx-matrix--off{opacity:.55;}
.rgx-matrix__label{color:#5db0ff;font-weight:600;letter-spacing:.02em;}
.rgx-matrix__stat{color:var(--zt-ink);font-variant-numeric:tabular-nums;font-weight:600;}
.rgx-matrix__stat em{color:var(--zt-muted);font-style:normal;font-weight:400;font-size:.8rem;margin-left:.3rem;}
.rgx-spark{display:flex;align-items:flex-end;gap:1px;height:20px;width:120px;}
.rgx-spark__bar{flex:1;background:linear-gradient(var(--zt-accent),var(--zt-gold-dim));border-radius:1px;min-height:3%;transition:height .25s linear;opacity:.85;}
.rgx-activity__filter{display:flex;gap:.3rem;padding:.4rem 0 .2rem;}
.rgx-fbtn{background:var(--zt-panel);border:1px solid var(--zt-border);color:var(--zt-ink-dim);padding:.2rem .7rem;border-radius:1rem;font-size:.74rem;cursor:pointer;transition:border-color .15s,color .15s,background .15s;}
.rgx-fbtn:hover{border-color:var(--zt-accent);color:var(--zt-ink);}
.rgx-fbtn--on{background:var(--zt-accent);border-color:var(--zt-accent);color:var(--zt-bg);font-weight:600;}

/* ── Architecture visualization (Erin: "dynamic from structure discovery, not hand drawn") ── */
.rgx-arch{display:flex;flex-direction:column;height:calc(100vh - 3.6rem);padding:.8rem 1.2rem;color:var(--zt-ink);}
.rgx-arch__head{display:flex;align-items:center;gap:.9rem;padding-bottom:.5rem;border-bottom:1px solid var(--zt-border);}
.rgx-arch__title{font-weight:600;color:var(--zt-accent);letter-spacing:.02em;}
.rgx-arch__meta{color:var(--zt-muted);font-size:.82rem;font-variant-numeric:tabular-nums;}
.rgx-arch__btn{margin-left:auto;background:var(--zt-panel);border:1px solid var(--zt-border);color:var(--zt-ink-dim);padding:.25rem .8rem;border-radius:.4rem;cursor:pointer;font-size:.78rem;}
.rgx-arch__btn:hover:not(:disabled){border-color:var(--zt-accent);color:var(--zt-ink);}
.rgx-arch__btn:disabled{opacity:.5;cursor:default;}
.rgx-arch__stage{flex:1;min-height:0;margin-top:.5rem;}
.rgx-arch__svg{width:100%;height:100%;display:block;}
.rgx-arch__edge{stroke:var(--zt-grid);opacity:.55;}
.rgx-arch__node{stroke-width:2.5;opacity:.92;}
.rgx-arch__node:hover{opacity:1;stroke:var(--zt-accent);}
.rgx-arch__glyph{fill:var(--zt-bg);font-weight:700;pointer-events:none;}
.rgx-arch__label{fill:var(--zt-ink-dim);font-size:9px;pointer-events:none;}

/* ── RG Browser (RG-reflection mandate, content leg: traversable entity drill-down) ── */
.rgx-browse{display:flex;flex-direction:column;height:calc(100vh - 3.6rem);padding:.8rem 1.2rem;color:var(--zt-ink);}
.rgx-browse__crumbs{display:flex;align-items:center;gap:.35rem;padding-bottom:.5rem;border-bottom:1px solid var(--zt-border);flex-wrap:wrap;}
.rgx-crumb{background:none;border:none;color:var(--zt-accent);cursor:pointer;font-size:.85rem;padding:.1rem .2rem;font-family:inherit;}
.rgx-crumb:hover{text-decoration:underline;}
.rgx-crumb--current{color:var(--zt-ink);cursor:default;}
.rgx-crumb__sep{color:var(--zt-ink-faint);}
.rgx-browse__body{flex:1;overflow-y:auto;margin-top:.5rem;display:flex;flex-direction:column;gap:.15rem;}
.rgx-browse__note{color:var(--zt-muted);font-style:italic;padding:.6rem .3rem;}
/* A read that could not be trusted as an emptiness must not look like the calm "nothing here" note beside it —
   the whole defect is the two being visually identical. Amber, not red: unknown is not an error. */
.rgx-browse__note--unknown{color:var(--zt-warn);font-style:normal;}
.rgx-browse__row{display:flex;align-items:center;gap:.6rem;padding:.35rem .5rem;border-radius:.35rem;border:1px solid transparent;background:none;color:var(--zt-ink);cursor:pointer;text-align:left;font-family:inherit;font-size:.85rem;width:100%;}
.rgx-browse__row:hover{background:rgba(255,255,255,.04);border-color:var(--zt-grid);}
.rgx-browse__glyph{min-width:1.2rem;text-align:center;}
.rgx-browse__k{color:var(--zt-ink);}
.rgx-browse__dim{color:var(--zt-ink-faint);font-size:.75rem;}
.rgx-browse__count{margin-left:auto;color:var(--zt-ink-dim);font-variant-numeric:tabular-nums;font-size:.78rem;}
.rgx-browse__dir{color:var(--zt-ink-faint);min-width:1.1rem;}
.rgx-browse__detail{display:flex;flex-direction:column;gap:.4rem;}
.rgx-browse__json{background:var(--zt-panel);border:1px solid var(--zt-border);border-radius:.4rem;padding:.7rem;overflow-x:auto;font-size:.78rem;color:var(--zt-ink-dim);max-height:45vh;}
.rgx-browse__edges-h{color:var(--zt-accent);font-weight:600;font-size:.82rem;margin-top:.3rem;}
/* Dynamic RG nav links (discovered participants) — subtly distinct (live green) from the static nav. */
.rgx-nav__rg{color:var(--zt-pos);opacity:.85;}
.rgx-nav__rg:hover{opacity:1;color:var(--zt-accent);}
.rgx-activity__note{color:var(--zt-pos);font-size:.82rem;}
.rgx-activity__row--push{opacity:.9;}
.rgx-arch__legend{display:flex;flex-wrap:wrap;gap:.8rem;padding:.4rem 0 .1rem;}
.rgx-arch__leg{display:inline-flex;align-items:center;gap:.35rem;color:var(--zt-ink-dim);font-size:.76rem;}
.rgx-arch__swatch{width:.7rem;height:.7rem;border-radius:2px;display:inline-block;}

/* ── Labs section (Erin: demos/tests/research/experimental, off the main nav) ── */
.zt-appnav__label{color:var(--zt-ink-faint);font-size:.82rem;text-transform:uppercase;letter-spacing:.08em;margin-right:.3rem;}
.rgx-labs{padding:1.5rem 2rem;max-width:1100px;margin:0 auto;color:var(--zt-ink);}
.rgx-labs__intro{margin-bottom:1rem;}
.rgx-labs__h{color:var(--zt-accent);font-size:1.8rem;margin:0 0 .4rem;}
.rgx-labs__sub{color:var(--zt-ink-dim);max-width:64ch;line-height:1.5;}
.rgx-labs__group{color:var(--zt-ink);font-size:1.1rem;margin:1.8rem 0 .2rem;display:flex;align-items:center;gap:.6rem;}
.rgx-labs__tag{font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;padding:.12rem .5rem;border-radius:1rem;background:var(--zt-panel);border:1px solid var(--zt-border);color:var(--zt-ink-faint);}
.rgx-labs__note{color:var(--zt-ink-faint);font-size:.82rem;margin:0 0 .8rem;max-width:64ch;}
.rgx-labs__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:.8rem;}
.rgx-labs__card{display:flex;flex-direction:column;gap:.3rem;padding:.9rem 1rem;border-radius:.5rem;background:var(--zt-panel);border:1px solid var(--zt-border);text-decoration:none;transition:border-color .15s,transform .15s;}
.rgx-labs__card:hover{border-color:var(--zt-accent);transform:translateY(-2px);}
.rgx-labs__title{color:var(--zt-accent);font-weight:600;}
.rgx-labs__desc{color:var(--zt-ink-dim);font-size:.8rem;line-height:1.4;}
