:root {
  /* Ink & Paper.
     Two rules govern this palette, and they are the whole reason it doesn't look
     like every other purple-on-slate dashboard:

     1. The neutrals are WARM. Cool slate greys are what every framework default
        ships, so warm paper is the single cheapest way to look deliberate.
     2. Colour carries meaning, it is never decoration. The primary button is ink,
        not a brand hue — so the only saturated things on screen are the ones that
        mean something: a step number, an annotation, a recording light, a guide
        that is shared. One accent doing six jobs is what "nobody decided
        anything" looks like. */

  /* the one accent — step numbers, annotations, focus. Ochre, not purple:
     it has to stay legible drawn on top of the blue-grey admin panels this
     product exists to document, and orange is as far from that chrome as it gets. */
  --brand: #c2410c;
  --brand-2: #9e340a;
  --brand-soft: #f6ece2;
  --brand-ring: rgba(194, 65, 12, 0.28);
  --on-brand: #fffdfa;

  /* primary action = ink. Confident, and it never dates. */
  --pri: #1a1713;
  --pri-2: #322b23;
  --pri-fg: #fbfaf7;

  --bg: #fbfaf7;
  --bg-2: #f4f1ea;
  --panel: #ffffff;
  --panel-2: #f5f2ec;

  --ink: #1a1713;
  --ink-2: #443c31;
  --muted: #6f675b;
  --faint: #928879;

  --line: #e5dfd2;

  /* semantic, and tokenised so there is exactly one place to change them */
  --ok: #16643f;
  --err: #a8321f;
  --rec: #c1352c;
  --live-fg: #2f6344;
  --live-bg: #e7ece2;

  --r-sm: 7px;
  --r: 10px;
  --r-lg: 14px;
  --r-xl: 22px;

  /* Borders do the separating; shadows only lift things that genuinely float.
     Shadow on everything is another generated-UI tell. */
  --sh-1: 0 1px 2px rgba(26, 23, 19, 0.05);
  --sh-2: 0 6px 20px rgba(26, 23, 19, 0.07);
  --sh-3: 0 22px 60px rgba(26, 23, 19, 0.16);

  --fast: 130ms cubic-bezier(0.2, 0, 0.2, 1);
  --wrap: 1080px;

  /* native scrollbars, date pickers and form widgets follow this */
  color-scheme: light;
}

/* Dark is a *choice* now, not an OS reading.
   assets/theme.js resolves light | dark | auto and stamps data-theme on <html>
   before the first paint, so there is exactly one dark block here and no
   duplicated values. The site already can't work without JS — the whole
   dashboard and the public viewer are JS — so relying on it costs nothing, and
   if theme.js ever fails to load the page falls back to light, which is safe.

   The default is LIGHT, not the OS setting. Every artefact this product makes is
   light — the HTML export, the PDF, the published guide, the video slides — so an
   editor that matches the thing you're building is more coherent than one that
   flips with the time of day. "Auto" is one click away for anyone who wants it. */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* Warm near-black, not navy. Same reasoning as the light scale. */
  --brand: #e08a4f;
  --brand-2: #eb9c65;
  --brand-soft: #2c2318;
  --brand-ring: rgba(224, 138, 79, 0.30);
  --on-brand: #21180f;

  --pri: #f2ede3;
  --pri-2: #ffffff;
  --pri-fg: #15130f;

  --bg: #15130f;
  --bg-2: #1a1712;
  --panel: #1c1a15;
  --panel-2: #23201a;

  --ink: #f2ede3;
  --ink-2: #cbc2b1;
  --muted: #9a9080;
  --faint: #746b5d;

  --line: #332e26;

  --ok: #63c08e;
  --err: #f0897c;
  --rec: #ef7a72;
  --live-fg: #88bd99;
  --live-bg: #1f2a20;

  --sh-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --sh-2: 0 6px 20px rgba(0, 0, 0, 0.45);
  --sh-3: 0 22px 60px rgba(0, 0, 0, 0.6);
}
/* ================================================================================================
   Spoke — hold a key, talk, get text. Everything below is Spoke's own; the palette above is the
   house one, lifted unchanged from Cut so `theme.js` works with no edits.
   ================================================================================================ */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--ink);
  font: 15px/1.6 ui-sans-serif, -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}
.wrap { max-width: 860px; margin: 0 auto; padding: 0 22px; }
a { color: var(--brand-2); }

/* ---------- house bar ---------- */
.house-bar { background: var(--bg-2); border-bottom: 1px solid var(--line); font-size: 12.5px; }
.house-bar .row { display: flex; align-items: center; gap: 9px; height: 38px; max-width: 860px; margin: 0 auto; padding: 0 22px; }
.house-bar a { color: var(--muted); text-decoration: none; }
.house-bar a:hover { color: var(--ink); }
.house-bar .here { color: var(--ink); font-weight: 650; }
.house-bar .spacer { flex: 1; }

/* ---------- hero ---------- */
header.hero { padding: 54px 0 10px; }
h1 { font-size: clamp(34px, 6vw, 52px); line-height: 1.04; letter-spacing: -0.033em; margin: 0 0 14px; }
h1 .sub { display: block; color: var(--muted); font-size: clamp(17px, 2.4vw, 22px); font-weight: 500; letter-spacing: -0.015em; margin-top: 12px; }
.lede { font-size: 17px; color: var(--ink-2); max-width: 60ch; margin: 0 0 6px; }
.badges { display: flex; flex-wrap: wrap; gap: 7px; margin: 20px 0 0; padding: 0; list-style: none; }
.badges li { font-size: 12px; font-weight: 600; color: var(--ink-2); background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 5px 11px; }

/* ---------- the machine ---------- */
.deck { margin: 30px 0 0; background: var(--panel); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--sh-2); overflow: hidden; }
.modes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; border-bottom: 1px solid var(--line); }
.modes button {
  appearance: none; border: 0; border-right: 1px solid var(--line); background: var(--bg-2);
  padding: 13px 8px; cursor: pointer; font: inherit; color: var(--muted); text-align: center;
}
.modes button:last-child { border-right: 0; }
.modes button b { display: block; font-size: 13.5px; font-weight: 660; color: inherit; }
.modes button small { display: block; font-size: 11px; margin-top: 2px; opacity: .85; }
.modes button:hover { background: var(--panel); color: var(--ink); }
.modes button[aria-pressed="true"] { background: var(--panel); color: var(--brand-2); box-shadow: inset 0 -2px 0 var(--brand); }

.stage { padding: 20px; }
#out {
  width: 100%; min-height: 190px; resize: vertical; padding: 15px 16px;
  border: 1px solid var(--line); border-radius: 11px; background: var(--bg);
  color: var(--ink); font: inherit; line-height: 1.7;
}
#out:focus { outline: 0; border-color: var(--brand-ring); box-shadow: 0 0 0 3px var(--brand-ring); }

.bar { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.btn { appearance: none; font: inherit; cursor: pointer; border-radius: 10px; padding: 10px 15px; border: 1px solid var(--line); background: var(--panel); color: var(--ink); font-weight: 560; }
.btn:hover { background: var(--bg-2); }
.btn.talk { background: var(--pri); color: var(--pri-fg); border-color: transparent; font-weight: 650; padding: 12px 20px; }
.btn.talk[data-on="1"] { background: var(--rec, #c1352c); }
.btn:disabled { opacity: .5; cursor: default; }
.spacer { flex: 1; }
.hint { color: var(--faint); font-size: 12.5px; }
kbd { font: inherit; font-size: 12px; background: var(--bg-2); border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; padding: 1px 6px; }

/* The HUD. It exists because the cost of the wrong mode is a whole paragraph, so the mode has to
   be readable before the first word leaves your mouth — never discovered afterwards. */
.hud { position: fixed; left: 50%; bottom: 34px; transform: translateX(-50%) translateY(12px); opacity: 0; pointer-events: none;
  display: flex; align-items: center; gap: 12px; padding: 11px 18px; border-radius: 999px;
  background: var(--pri); color: var(--pri-fg); box-shadow: var(--sh-3, 0 14px 40px rgba(0,0,0,.28));
  transition: opacity 120ms ease, transform 120ms ease; z-index: 40; }
.hud[data-on="1"] { opacity: 1; transform: translateX(-50%) translateY(0); }
.hud .dot { width: 9px; height: 9px; border-radius: 50%; background: #ff6b5e; animation: pulse 1s infinite; }
@keyframes pulse { 50% { opacity: .35; } }
.hud .mode { font-weight: 700; letter-spacing: .02em; }
.hud .lvl { width: 64px; height: 5px; border-radius: 3px; background: rgba(255,255,255,.22); overflow: hidden; }
.hud .lvl i { display: block; height: 100%; width: 0%; background: #fff; transition: width 70ms linear; }
.hud .keys { font-size: 11.5px; opacity: .7; }

.msg { margin: 12px 0 0; font-size: 13.5px; color: var(--muted); min-height: 20px; }
.msg.err { color: var(--err); }
.load { margin-top: 12px; height: 5px; border-radius: 3px; background: var(--bg-2); overflow: hidden; display: none; }
.load[data-on="1"] { display: block; }
.load i { display: block; height: 100%; width: 0%; background: var(--brand); transition: width 140ms ease; }

/* ---------- prose ---------- */
section.note { padding: 46px 0 0; }
section.note h2 { font-size: 21px; letter-spacing: -0.02em; margin: 0 0 10px; }
section.note p { color: var(--ink-2); max-width: 66ch; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; margin-top: 18px; }
.card { background: var(--panel); border: 1px solid var(--line); border-radius: 13px; padding: 16px; }
.card h3 { margin: 0 0 6px; font-size: 14.5px; letter-spacing: -0.012em; }
.card p { margin: 0; font-size: 13.5px; color: var(--muted); }
footer.site { margin-top: 52px; border-top: 1px solid var(--line); padding: 20px 0 40px; color: var(--muted); font-size: 13px; }
footer.site .row { display: flex; gap: 14px; flex-wrap: wrap; }
@media (max-width: 620px) {
  .modes { grid-template-columns: repeat(2, 1fr); }
  .modes button:nth-child(2) { border-right: 0; }
  .hud .keys { display: none; }
}
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }
