/* SoloINC faces. All OFL, all self-hosted: the console is served under default-src 'none', so no web font loading, ever.
   Display is Archivo Condensed: the bundled Archivo.ttf is a variable font with a width axis (wdth 62–125); display sets wdth 75 at weight 600. */
@font-face { font-family: "Inter"; src: url("Inter.ttf") format("truetype"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "JetBrains Mono"; src: url("JetBrainsMono.ttf") format("truetype"); font-weight: 100 800; font-display: swap; }
@font-face { font-family: "Archivo"; src: url("Archivo.ttf") format("truetype"); font-weight: 100 900; font-stretch: 62% 125%; font-display: swap; }

/* SoloINC colour. Mission control: a dark neutral ground, colour for life (lights, live roads, counts) and identity (each company's hue).
   Meanings never change: teal = an open form waiting on a person; signal green = moving now / live; amber = slow, stuck; red = failing; green check = all clear. Never colour alone: the word stays. */
:root {
  color-scheme: dark;
  /* neutral ramp — teal-tinted, from the console */
  --neutral-50: #f5f7f7; --neutral-100: #ebeff2; --neutral-200: #d3d9d9; --neutral-300: #a9b3b3; --neutral-400: #7d8989;
  --neutral-500: #5c6d6d; --neutral-600: #3e4a4b; --neutral-700: #2a3636; --neutral-800: #162020; --neutral-900: #0c1313;
  /* SoloINC teal — from the logo; 400 is the base */
  --teal-50: #e6fafb; --teal-100: #b8f0f2; --teal-200: #7fe3e8; --teal-300: #3fd4db; --teal-400: #00c3cb;
  --teal-500: #00a3aa; --teal-600: #008289; --teal-700: #006268; --teal-800: #004247;
  /* raw state hues */
  --amber-dark: #e2a520; --amber-light: #9a6b00;
  --red-dark: #fc5950; --red-light: #c62f27;
  --green-dark: #48c063; --green-light: #0a7a2e;

  /* == theme: dark (default) == */
  --bg: var(--neutral-900);
  --surface: var(--neutral-800);
  --surface-raised: #212b2c;      /* console panel-2: chips, raised tiles */
  --surface-sunk: #0f1717;        /* console panel-0: inputs, unselected tile */
  --line: var(--neutral-600);     /* dividers: quiet on purpose */
  --line-strong: var(--neutral-500); /* any edge that identifies a thing: clears 3:1 */
  --text: var(--neutral-100);
  --text-2: #abb2b8;              /* console dim: secondary copy */
  --muted: var(--neutral-400);    /* captions, ages, mono meta */
  --accent: var(--teal-400);      /* teal for text and lines */
  --accent-fill: var(--teal-400); /* teal for filled surfaces (primary button) */
  --on-accent: var(--neutral-900);
  --accent-tint: color-mix(in srgb, var(--teal-400) 11%, var(--surface));
  --accent-line: color-mix(in srgb, var(--teal-400) 45%, var(--line));

  /* == state tokens: same meaning in both themes, always shown with their word == */
  --signal: #3ee08f;                     /* moving now / live: the signal light, live road traffic, the in-flight readout */
  --state-moving: var(--muted);          /* the word stays neutral; the signal light is the mark */
  --state-moving-pulse: var(--signal);   /* the moving light and the running card's ring */
  --state-slow: var(--amber-dark);       /* outline badge */
  --state-stuck: var(--amber-dark);      /* filled badge */
  --state-failing: var(--red-dark);      /* filled badge + 3px left edge */
  --state-stopped: var(--neutral-500);   /* hatch + pause icon */
  --state-done: var(--neutral-400);      /* quiet check */
  --state-running: #a594f0;              /* a stage's job is running now: outline on its column, chip and flow card; never teal, red or amber */
  --for-you: var(--teal-400);            /* an open form waiting on a person (text + lines) */
  --for-you-fill: var(--teal-400);       /* the for-you dot on a flow strip */
  --for-you-ring: transparent;           /* light theme adds a teal-700 ring so the dot keeps 3:1 on bg */
  --success: var(--green-dark);          /* all clear (with its check), toasts, a connected light */
  --on-state: var(--neutral-900);        /* text on a filled amber/red badge */
  --stuck-tint: color-mix(in srgb, var(--amber-dark) 11%, var(--surface));
  --failing-tint: color-mix(in srgb, var(--red-dark) 10%, var(--surface));
  --stop-tint: color-mix(in srgb, var(--red-dark) 12%, transparent);
  --hatch: repeating-linear-gradient(135deg, color-mix(in srgb, var(--neutral-500) 45%, transparent) 0 1.5px, transparent 1.5px 6px);

  /* identity: a company's (or flow's) hue, re-inked at a fixed lightness + chroma per theme so any hue stays AA and vivid:
     oklch(from <hue> var(--hue-l) var(--hue-c) h). Stripes, dots, road links, tinted heads. Never status. */
  --cell-hue: var(--neutral-500);
  --hue-l: 0.80; /* @kind other */
  --hue-c: 0.13; /* @kind other */
  --road-ink: var(--text-2);             /* a lit road link with no hue */
  /* readouts: header counts, in their meaning's ink when above 0 */
  --readout-moving: var(--signal);
  --readout-stopped: var(--state-failing);
  --readout-for-you: var(--for-you);
  /* glow: lights and the marks that carry a meaning */
  --glow-mix: 70%; /* @kind other */
  --glow-for-you: 0 0 0 1px color-mix(in srgb, var(--teal-400) 38%, transparent), 0 0 18px color-mix(in srgb, var(--teal-400) 22%, transparent);
  --glow-failing: 0 0 0 1px color-mix(in srgb, var(--red-dark) 30%, transparent), 0 0 18px color-mix(in srgb, var(--red-dark) 18%, transparent);
  --glow-stop: 0 0 12px color-mix(in srgb, var(--red-dark) 22%, transparent);
  /* depth: a faint sheen on every card, a deeper one on the opened frame's head, the header bar */
  --card-sheen: linear-gradient(180deg, color-mix(in srgb, var(--text) 4%, transparent), transparent 64px);
  --frame-head: linear-gradient(180deg, color-mix(in srgb, var(--teal-400) 9%, transparent), transparent 140px);
  --head-bg: linear-gradient(180deg, color-mix(in srgb, var(--surface) 80%, var(--bg)), var(--bg));
  --head-line: 0 1px 0 color-mix(in srgb, var(--signal) 14%, transparent);

  /* backdrop grid (Industry structure) */
  --grid-line: color-mix(in srgb, var(--neutral-600) 38%, transparent);
  --grid-bg: linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 48px 48px, linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 48px 48px;
  --crosshair: color-mix(in srgb, var(--teal-200) 45%, var(--text)); /* Industry marks, brightened: ink with a teal cast */
  /* backdrop: grid + scanlines + two soft glows at the top (brand teal, cool blue). Main background only. */
  --scanlines: repeating-linear-gradient(0deg, color-mix(in srgb, var(--text) 2.2%, transparent) 0 1px, transparent 1px 3px);
  --bg-glow: radial-gradient(1100px 460px at 78% -12%, color-mix(in srgb, var(--teal-400) 10%, transparent), transparent 70%), radial-gradient(900px 420px at -5% -10%, color-mix(in srgb, #3d7bd9 8%, transparent), transparent 70%);
  --bg-texture: var(--bg-glow), var(--scanlines), var(--grid-bg);
  --shadow-pop: 0 14px 36px rgb(0 0 0 / 0.6);
  --scrim: rgb(0 0 0 / 0.72);
}

/* == theme: light — same meanings, darker inks == */
[data-theme="light"] {
  color-scheme: light;
  --bg: var(--neutral-50);
  --surface: #ffffff;
  --surface-raised: var(--neutral-100);
  --surface-sunk: var(--neutral-50);
  --line: var(--neutral-200);
  --line-strong: var(--neutral-400);
  --text: var(--neutral-900);
  --text-2: var(--neutral-600);
  --muted: var(--neutral-500);
  --accent: var(--teal-700);
  --accent-fill: var(--teal-400);
  --on-accent: var(--neutral-900);
  --accent-tint: color-mix(in srgb, var(--teal-400) 12%, #ffffff);
  --accent-line: color-mix(in srgb, var(--teal-700) 55%, var(--neutral-200));
  --signal: #0b7f42;
  --state-moving: var(--muted);
  --state-moving-pulse: var(--signal);
  --hue-l: 0.50; /* @kind other */
  --hue-c: 0.13; /* @kind other */
  --glow-mix: 55%; /* @kind other */
  --glow-for-you: 0 0 0 1px color-mix(in srgb, var(--teal-600) 40%, transparent), 0 0 16px color-mix(in srgb, var(--teal-400) 26%, transparent);
  --glow-failing: 0 0 0 1px color-mix(in srgb, var(--red-light) 30%, transparent), 0 0 16px color-mix(in srgb, var(--red-light) 16%, transparent);
  --glow-stop: 0 0 10px color-mix(in srgb, var(--red-light) 18%, transparent);
  --card-sheen: linear-gradient(180deg, color-mix(in srgb, var(--neutral-100) 70%, transparent), transparent 64px);
  --frame-head: linear-gradient(180deg, color-mix(in srgb, var(--teal-400) 11%, transparent), transparent 140px);
  --head-bg: linear-gradient(180deg, #ffffff, var(--bg));
  --head-line: 0 1px 0 color-mix(in srgb, var(--signal) 16%, transparent);
  --crosshair: color-mix(in srgb, var(--teal-700) 55%, var(--text));
  --scanlines: repeating-linear-gradient(0deg, color-mix(in srgb, var(--neutral-900) 1.6%, transparent) 0 1px, transparent 1px 3px);
  --bg-glow: radial-gradient(1100px 460px at 78% -12%, color-mix(in srgb, var(--teal-400) 12%, transparent), transparent 70%), radial-gradient(900px 420px at -5% -10%, color-mix(in srgb, #3d7bd9 8%, transparent), transparent 70%);
  --state-slow: var(--amber-light);
  --state-stuck: var(--amber-light);
  --state-failing: var(--red-light);
  --state-stopped: var(--neutral-500);
  --state-done: var(--neutral-500);
  --state-running: #5b47c4;
  --for-you: var(--teal-700);
  --for-you-fill: var(--teal-500);
  --for-you-ring: var(--teal-700);
  --success: var(--green-light);
  --readout-moving: var(--signal);
  --readout-stopped: var(--state-failing);
  --readout-for-you: var(--for-you);
  --on-state: #ffffff;
  --stuck-tint: color-mix(in srgb, var(--amber-light) 9%, #ffffff);
  --failing-tint: color-mix(in srgb, var(--red-light) 7%, #ffffff);
  --stop-tint: color-mix(in srgb, var(--red-light) 8%, transparent);
  --hatch: repeating-linear-gradient(135deg, color-mix(in srgb, var(--neutral-500) 40%, transparent) 0 1.5px, transparent 1.5px 6px);
  --grid-line: color-mix(in srgb, var(--neutral-300) 40%, transparent);
  --grid-bg: linear-gradient(var(--grid-line) 1px, transparent 1px) 0 0 / 48px 48px, linear-gradient(90deg, var(--grid-line) 1px, transparent 1px) 0 0 / 48px 48px;
  --bg-texture: var(--bg-glow), var(--scanlines), var(--grid-bg);
  --road-ink: var(--text-2);
  --shadow-pop: 0 14px 36px rgb(12 19 19 / 0.16);
  --scrim: rgb(12 19 19 / 0.45);
}

:root {
  --font-display: "Archivo", "Inter", system-ui, sans-serif; /* Archivo Condensed: wdth 75, weight 600 */
  --display-stretch: 75%; /* font-stretch that selects wdth 75 on the variable Archivo */
  --display-wdth: "wdth" 75; /* @kind other */
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --weight-body: 400; --weight-ui: 500; --weight-display: 600; --weight-mono: 400;

  /* sizes: console density (11.5px body) with a condensed display ladder above it */
  --fs-micro: 9.5px;    /* mono kickers, id tags */
  --fs-mono: 10.5px;    /* ids, action labels, table numbers */
  --fs-small: 11px;
  --fs-body: 11.5px;    /* the console's body */
  --fs-ui: 12.5px;      /* card titles, fields */
  --fs-h3: 13.5px;      /* section heading */
  --fs-h2: 20px;        /* view title (display) */
  --fs-h1: 28px;        /* screen title (display) */
  --fs-display: 48px;   /* marketing */
  --fs-hero: 88px;      /* landing hero, deck title */

  --lh-tight: 1.05; /* @kind other */
  --lh-heading: 1.2; /* @kind other */
  --lh-body: 1.45; /* @kind other */
  --lh-prose: 1.6; /* @kind other */
  --track-display: 0.005em;
  --track-kicker: 0.08em;   /* uppercase mono */
  --numeric: tabular-nums; /* @kind other */

  /* semantic aliases */
  --text-body: var(--weight-body) var(--fs-body)/var(--lh-body) var(--font-sans);
  --text-ui: var(--weight-ui) var(--fs-ui)/var(--lh-body) var(--font-sans);
  --text-id: var(--weight-mono) var(--fs-mono)/1.4 var(--font-mono);
  --text-kicker: var(--weight-ui) var(--fs-micro)/1.2 var(--font-mono);
  --text-heading: var(--weight-display) var(--fs-h2)/var(--lh-heading) var(--font-display);
}

/* Spacing is Industry's scale: 4px × 0.85 density. Frames are Industry's: square-cornered, hairline, "+" registration marks. */
:root {
  --s1: 3.4px; --s2: 6.8px; --s3: 10.2px; --s4: 13.6px; --s5: 20.4px; --s6: 27.2px;
  --s7: 40.8px; --s8: 54.4px; --s9: 81.6px; /* marketing extensions on the same 0.85 step */
  --r0: 0px;    /* badges */
  --r1: 0px;    /* cards, actions */
  --r2: 0px;    /* tiles, rows, forms */
  --r3: 0px;    /* panels, views */
  --r-pill: 999px; /* dots and the Inbox count only */
  --bw: 1px;
  --edge: 3px;        /* state edge / form edge / cell stripe */
  --corner: 11px;     /* "+" registration mark, centred on the frame corner */
  --corner-offset: -6px;
  --grid: 48px;       /* Industry states no grid size; 48px backdrop */
  --header-h: 47px;
  --footer-h: 30px;
}

/* Motion is life: lights breathe, pulse and blink by meaning; live road links carry travelling dots. Everything stops under prefers-reduced-motion. */
:root {
  --t-fast: 120ms; /* @kind other */
  --t-med: 200ms; /* @kind other */
  --ease: cubic-bezier(.2, .7, .3, 1); /* @kind other */
  --pulse-period: 1.4s; /* @kind other */
  --pulse-anim: si-pulse var(--pulse-period) ease-in-out infinite; /* @kind other */ /* moving now: the signal light */
  --pulse-anim-opacity: si-pulse-o var(--pulse-period) ease-in-out infinite; /* @kind other */ /* the moving dot on a flow strip: opacity only */
  --breathe-anim: si-breathe 3.2s ease-in-out infinite; /* @kind other */ /* live: the header's light, slow */
  --blink-for-you: si-blink 2.4s ease-in-out infinite; /* @kind other */ /* waiting on you: gentle */
  --blink-slow: si-blink 2s ease-in-out infinite; /* @kind other */
  --blink-stuck: si-blink 1.3s ease-in-out infinite; /* @kind other */
  --blink-failing: si-blink .8s ease-in-out infinite; /* @kind other */ /* failing: fastest */
  --travel-period: 1.8s; /* @kind other */
  --travel-anim: si-travel var(--travel-period) linear infinite; /* @kind other */ /* a dot riding a live road link toward the stage */
  --ring-period: 1.8s; /* @kind other */
  --ring-anim: si-ring var(--ring-period) ease-out infinite; /* @kind other */ /* a running card's frame: a signal ring breathing outward */
  --ring-rest: none; /* @kind other */ /* the static ring used instead when motion is reduced */
}
@keyframes si-ring { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--state-moving-pulse) 70%, transparent); } 100% { box-shadow: 0 0 0 7px transparent; } }
@keyframes si-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.72); } }
@keyframes si-pulse-o { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
@keyframes si-breathe { 0%, 100% { opacity: .55; transform: scale(.85); } 50% { opacity: 1; transform: scale(1.08); } }
@keyframes si-blink { 0%, 100% { opacity: 1; } 50% { opacity: .28; } }
@keyframes si-travel { 0% { left: 0; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { left: calc(100% - 4px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { :root { --pulse-anim: none; /* @kind other */ --pulse-anim-opacity: none; /* @kind other */ --breathe-anim: none; /* @kind other */ --blink-for-you: none; /* @kind other */ --blink-slow: none; /* @kind other */ --blink-stuck: none; /* @kind other */ --blink-failing: none; /* @kind other */ --travel-anim: none; /* @kind other */ --ring-anim: none; /* @kind other */ --ring-rest: 0 0 0 2px color-mix(in srgb, var(--state-moving-pulse) 40%, transparent); /* @kind other */ --t-fast: 0ms; /* @kind other */ --t-med: 0ms; /* @kind other */ } }

/* Status lights: one shared set. <i data-light="live|moving|for-you|slow|stuck|failing|stopped|ok|off">, size via --light-size.
   A light never stands alone: its word is beside it or in its aria-label. Animations come from motion.css and stop under reduced motion. */
[data-light] { --light-ink: var(--muted); --light-size: 7px; display: inline-block; flex: none; width: var(--light-size); height: var(--light-size); border-radius: 50%; background: var(--light-ink); vertical-align: middle;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--light-ink) 28%, transparent), 0 0 calc(var(--light-size) * 1.5) color-mix(in srgb, var(--light-ink) var(--glow-mix), transparent); }
[data-light="live"] { --light-ink: var(--signal); animation: var(--breathe-anim); }
[data-light="moving"] { --light-ink: var(--signal); animation: var(--pulse-anim); }
[data-light="for-you"] { --light-ink: var(--for-you-fill); animation: var(--blink-for-you); }
[data-light="slow"] { --light-ink: var(--state-slow); animation: var(--blink-slow); }
[data-light="stuck"] { --light-ink: var(--state-stuck); animation: var(--blink-stuck); }
[data-light="failing"] { --light-ink: var(--state-failing); animation: var(--blink-failing); }
[data-light="stopped"] { --light-ink: var(--state-stopped); box-shadow: none; }
[data-light="ok"] { --light-ink: var(--success); }
[data-light="off"] { background: transparent; box-shadow: none; border: 1.5px solid var(--muted); box-sizing: border-box; }
/* road traffic: a dot riding a live link (parent is position: relative); under reduced motion one still dot mid-link */
[data-travel] { position: absolute; top: 50%; left: 0; width: 4px; height: 4px; margin-top: -2px; border-radius: 50%; pointer-events: none; background: var(--travel-ink, var(--signal));
  box-shadow: 0 0 6px var(--travel-ink, var(--signal)); opacity: 0; animation: var(--travel-anim); }
@media (prefers-reduced-motion: reduce) { [data-travel] { left: calc(50% - 2px); opacity: 1; } [data-travel] ~ [data-travel] { display: none; } }

/* Layout rules as tokens. Read by components/shared/layout.js (Layout.mode, Layout.formStep). */
:root {
  --bp-narrow: 760px;      /* below: the phone stack; at and above: the grid with the side rail */
  --bp-side-sheet: 1300px; /* below (and >= --bp-narrow): an opened card is a side sheet in the rail's place; at and above: the end column pins */
  --bp-form-step: 430px;   /* below: forms over --form-step-fields fields go one field at a time */
  --form-step-fields: 3; /* @kind other */
  --strip-h: 16px;         /* flow strip height on rows (the track sits at half) */
  --strip-h-tile: 12px;    /* flow strip height on tiles */
  --strip-dot: 6px;        /* one card on the track (rows) */
  --strip-dot-tile: 5px;   /* one card on the track (tiles) */
  --strip-signal: 1.5; /* @kind other */ /* dots that carry a state are this many times a normal dot */
  --strip-halo: 2px;       /* soft halo in the dot's own colour */
  --strip-gap: 3px;        /* space between dots */
  --strip-tick: 8px;       /* stage boundary tick, a short vertical hairline */
  --strip-min-stage: 22px; /* narrowest span for a stage holding cards */
  --strip-empty: 8px;      /* an empty stage: a narrow span between two ticks */
  --touch: 44px;           /* minimum touch target */
  --focus-ring: 2px solid var(--text);
  --focus-offset: 2px;
}

/* The console's app.css names, mapped onto this system, for porting screens. Informational means no colour. */
:root, [data-theme="light"] {
  --panel: var(--surface); --panel-2: var(--surface-raised); --panel-0: var(--surface-sunk);
  --ink: var(--text); --dim: var(--text-2); --faint: var(--muted); --ink-3: var(--muted);
  --warn: var(--state-slow); --bad: var(--state-failing); --ok: var(--success);
  --info: var(--neutral-400); --info-line: var(--neutral-600); --info-fill: color-mix(in srgb, var(--neutral-400) 11%, var(--surface));
  --standby: var(--neutral-400); --standby-line: var(--neutral-600); --standby-fill: color-mix(in srgb, var(--neutral-400) 11%, var(--surface));
}

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--text); font: var(--text-body); -webkit-text-size-adjust: 100%; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
code, kbd, samp { font-family: var(--font-mono); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
