

/* The three brand faces, self-hosted beside this file (OFL-*.txt beside them). */
@font-face { font-family: "Inter"; src: url("Inter.ttf") format("truetype"); font-weight: 100 900; 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; }
@font-face { font-family: "JetBrains Mono"; src: url("JetBrainsMono.ttf") format("truetype"); font-weight: 100 800; font-display: swap; }

/* == tokens == (the one place colour, space and motion are defined.
 * Derived tone surfaces use color-mix against the CURRENT scheme's hues, so
 * the light block below only overrides the base palette.) */
:root {
  color-scheme: dark;
  /* base palette — dark, the default.
   *
   * The surfaces are a deliberate LADDER, not four near-identical greys. The
   * palette this replaced was GitHub Primer's, whose panel sat 1.10:1 from the
   * page and whose border sat 1.43:1 — below the 3:1 WCAG 2.2 SC 1.4.11 asks of
   * any component you identify by its edge, which on this map is every box.
   * Depth is what a dense board is read by, so the rungs are spaced to be seen.
   *
   * The accent is cyan-teal, and that is a competitive choice rather than a
   * decorative one: indigo and violet are worn out in this category (Linear,
   * Clerk, Stripe, Sentry, Datadog, Railway) and blue is where everyone starts.
   * It also sits far enough from --ok that "waiting on you" never reads as
   * "finished". */
  --bg: #0c1313;
  --panel: #161f1f;
  --panel-2: #212b2c;
  --line: #3e4a4b;
  /* A border that CARRIES MEANING uses this, not --line: it clears 3:1 where
     --line deliberately stays quiet enough to divide without shouting. */
  --line-strong: #5c6d6d;
  --ink: #ebeff2;
  --dim: #abb2b8;
  --faint: #7d8989;
  --accent: #00c3cb;
  --ok: #48c063;
  --warn: #e2a520;
  --bad: #fc5950;
  --info: #a490ff;
  /* Distinct from --info on purpose. `standby` (a shared or dormant seat) and
     `info` (something actively in work) are different facts, and rendering both
     in the same purple made them indistinguishable everywhere flow.js drew them. */
  --standby: #7d9db4;
  --on-accent: #0c1313;
  --on-tone: #ffffff;
  /* derived tone surfaces — replaces every sprinkled hex */
  --ok-fill:     color-mix(in srgb, var(--ok)     11%, var(--panel));
  --ok-line:     color-mix(in srgb, var(--ok)     36%, var(--line));
  --warn-fill:   color-mix(in srgb, var(--warn)   11%, var(--panel));
  --warn-line:   color-mix(in srgb, var(--warn)   36%, var(--line));
  --bad-fill:    color-mix(in srgb, var(--bad)    11%, var(--panel));
  --bad-line:    color-mix(in srgb, var(--bad)    36%, var(--line));
  --info-fill:   color-mix(in srgb, var(--info)   11%, var(--panel));
  --info-line:   color-mix(in srgb, var(--info)   36%, var(--line));
  --standby-fill: color-mix(in srgb, var(--standby) 11%, var(--panel));
  --standby-line: color-mix(in srgb, var(--standby) 36%, var(--line));
  --accent-fill: color-mix(in srgb, var(--accent) 11%, var(--panel));
  --accent-line: color-mix(in srgb, var(--accent) 36%, var(--line));
  /* space — the existing 2/4/7/10/14 rhythm, named */
  --s1: 2px; --s2: 4px; --s3: 7px; --s4: 10px; --s5: 14px; --s6: 20px;
  /* radius */
  --r1: 6px; --r2: 8px; --r3: 10px; --r-pill: 999px;
  /* type */
  --fs-body: 11.5px;
  --fs-stat: clamp(21px, 4.5vw, 27px);
  /* motion — one vocabulary: travelling dash = carrying now, pulse = unwell */
  --t-fast: 120ms; --t-med: 200ms;
  --ease: cubic-bezier(.2, .7, .3, 1);
  --flow-period: 1.1s;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --hd: "Archivo", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  /* the mockups' two extra surfaces: tertiary text, and an unselected tile */
  --ink-3: #7d8989;
  --panel-0: #0f1717;
  --halt-bg: #2a1414;
  /* The chain's light mini card and the hardware panel's soft rule (Hardware.dc.html). */
  --ink-deep: #2c3838;
  --ok-deep: #0a7a2e;
  --line-soft: #2a3636;
}

/* == LCH == Where the browser can do oklch (Safari 15.4+, Chrome 111+,
   Firefox 113+) the palette is re-expressed perceptually and the accent is
   DERIVED from the current cell's hue -- `--cell-hue`, set by cells.js from the
   cell's accent -- so surfaces, lines, fills and states agree across cells and
   every screen carries a faint tint of which cell it is in. Lightness and
   chroma are fixed here; only the hue travels. The hex palette above is the
   fallback and stays the source of truth for the standby page's parity copy. */
@supports (color: oklch(50% 0.1 200)) {
  :root {
    /* 200 is the brand's cyan-teal. A cell with its own accent still overrides
       this (cells.js), so the per-cell tint survives the change. */
    --cell-hue: 200;
    --accent:    oklch(74% 0.13 var(--cell-hue));
    --on-accent: oklch(15.5% 0.011 var(--cell-hue));
    /* The ladder. Each rung is a visible step from the one below rather than
       the 1.10:1 the old 16/21/24 spacing produced. */
    --bg:      oklch(18% 0.010 var(--cell-hue));
    --panel:   oklch(23% 0.012 var(--cell-hue));
    --panel-2: oklch(28% 0.014 var(--cell-hue));
    --line:    oklch(40% 0.016 var(--cell-hue));
    --line-strong: oklch(52% 0.020 var(--cell-hue));
    --ok:   oklch(72% 0.17 148);
    --warn: oklch(76% 0.15 80);
    --bad:  oklch(68% 0.20 27);
    --info: oklch(72% 0.16 290);
    --standby: oklch(68% 0.05 240);
    --ok-fill:     color-mix(in oklch, var(--ok)     12%, var(--panel));
    --ok-line:     color-mix(in oklch, var(--ok)     38%, var(--line));
    --warn-fill:   color-mix(in oklch, var(--warn)   12%, var(--panel));
    --warn-line:   color-mix(in oklch, var(--warn)   38%, var(--line));
    --bad-fill:    color-mix(in oklch, var(--bad)    12%, var(--panel));
    --bad-line:    color-mix(in oklch, var(--bad)    38%, var(--line));
    --info-fill:   color-mix(in oklch, var(--info)   12%, var(--panel));
    --info-line:   color-mix(in oklch, var(--info)   38%, var(--line));
    --standby-fill: color-mix(in oklch, var(--standby) 12%, var(--panel));
    --standby-line: color-mix(in oklch, var(--standby) 38%, var(--line));
    --accent-fill: color-mix(in oklch, var(--accent) 12%, var(--panel));
    --accent-line: color-mix(in oklch, var(--accent) 38%, var(--line));
  }
}
/* == /tokens == */

* { box-sizing: border-box; }

html,
body {
  margin: 0; padding: 0;
  background: var(--bg); color: var(--ink);
  font-family: var(--sans);
  font-size: 11.5px; line-height: 1.45;
  -webkit-text-size-adjust: 100%;
  /* A long unbroken title (a file:// path, a URL) wraps inside its box instead of running out of it. */
  overflow-wrap: break-word;
}

:where(#toasts) a { color: var(--accent); text-decoration: none; }
:where(#toasts) a:hover { text-decoration: underline; }
/* Mono inherits its size. The artboards set every mono size absolutely -- 9.5px, 10px,
   10.5px -- so a 0.86 multiplier here just produced values the design never uses
   (11.5 x 0.86 = 9.89, 10.5 x 0.86 = 9.03, 12 x 0.86 = 10.32). */
code { font-family: var(--mono); }
section[hidden] { display: none !important; }

/* What the page says when it cannot reach the engine (app.js). */
.note {
  color: var(--dim); font-size: 12px; background: var(--panel-2);
  border-left: 2px solid var(--line); padding: 7px 9px;
  border-radius: 0 8px 8px 0; margin: 8px 0 0;
}
.note.bad { border-left-color: var(--bad); }

:where(#toasts) table { width: 100%; border-collapse: collapse; font-size: 13px; }
th,
td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
th { color: var(--faint); font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700; }
tbody tr:hover { background: var(--panel-2); }

:where(#toasts) button {
  font: inherit; font-size: 11.5px; cursor: pointer;
  background: var(--panel-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: 7px; padding: 5px 11px;
}
:where(#toasts) button:hover { border-color: var(--accent); }
:where(#toasts) button:disabled { opacity: 0.45; cursor: not-allowed; }

summary { cursor: pointer; }

:where(#toasts) :is(input, select, textarea) {
  font: inherit; font-size: 12px; background: var(--panel-0); color: var(--ink);
  border: 1px solid var(--line); border-radius: 7px; padding: 8px 10px; width: 100%;
}
:where(#toasts) input:focus,
:where(#toasts) select:focus,
:where(#toasts) textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
:where(#toasts) textarea { font-family: var(--mono); font-size: 12px; line-height: 1.5; resize: vertical; min-height: 120px; }
/* iOS Safari zooms the whole page on focus of any text input under 16px. */
@media (max-width: 719px) {
  input,
  select,
  textarea { font-size: 16px; }
}

#toasts { position: fixed; right: 10px; bottom: 10px; z-index: 100; display: grid; gap: 7px; max-width: min(440px, 92vw); }
.toast {
  background: var(--panel-2); border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent); border-radius: 7px; padding: 9px 13px;
  font-size: 12px; line-height: 1.45; color: var(--ink); max-width: 560px;
  box-shadow: 0 14px 36px rgb(0 0 0 / 0.6);
}
.toast.ok { border-left-color: var(--ok); }
.toast.bad { border-left-color: var(--bad); }
.toast .x { float: right; cursor: pointer; color: var(--faint); }

/* Any heading, anywhere: absolute, so nothing falls through to the user agent's 1.5em. */
h1,
h2,
h3,
h4 { font-size: 13.5px; font-weight: 600; margin: 0 0 5px; }
