/* beads-runner/web/shared/tokens.css — C-shell (claude-tools-uxvsh).
 *
 * THE single source of the design tokens + reset that every view shares
 * (Contract C.1, UX-V2-ARCHITECTURE §4). Until now the :root custom-property
 * block, the `*` reset, the `body` base, and `::selection` were copy-pasted
 * byte-for-byte into board.css / inbox.css / intake.css. They now live here
 * ONCE; each page links this FIRST, then its own page-specific stylesheet.
 *
 * Superset note: the union of all three pages' tokens — `--font-read` (Inbox
 * reading prose) and `--tap` (Intake ≥44px touch targets) are included so no
 * page loses a token it relied on. Adding a page-specific token is still fine
 * in that page's own CSS; this file holds only what is genuinely shared.
 *
 * Also owns the persistent NAV chrome (Contract C.2) painted by shared/shell.js
 * so the global nav + workspace facet tabs look identical on every route.
 * Presentation only; no behavior. */

:root{
  --ink:#080a0e; --ink-2:#0b0e14; --panel:#10141c; --panel-2:#161b25;
  --line:rgba(255,255,255,.07); --line-2:rgba(255,255,255,.12);
  --text:#e8ebf1; --dim:#8b94a6; --faint:#535b6b;
  --amber:#ffb454; --amber-soft:#ffcd86; --amber-glow:rgba(255,180,84,.22);
  --mint:#4fd6a0; --coral:#ff6b6b; --sky:#74a8ff; --slate:#5b6577;
  --font-display:'Fraunces',Georgia,serif;
  --font-read:'Newsreader',Georgia,serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --tap:44px; /* Intake (I1): ≥44px touch targets */
}
*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  background:var(--ink);color:var(--text);font-family:var(--mono);
  min-height:100vh;-webkit-font-smoothing:antialiased;
  background-image:
    radial-gradient(900px 600px at 78% -5%, rgba(116,168,255,.06), transparent 60%),
    radial-gradient(800px 700px at 8% 105%, rgba(79,214,160,.05), transparent 55%);
}
::selection{background:var(--amber);color:#1a1206}

/* ── persistent NAV chrome (Contract C.2) — painted by shared/shell.js ──────
 * Global row (Inbox · Workspaces · Capacity · Cross-WS) is always present.
 * When inside a workspace context the facet row (Board · Blueprint · Activity
 * · Gates) renders below it. The active link/tab carries .active. The nav is
 * sticky so it stays reachable as a view scrolls (the Inbox stays the product
 * — it is one tap from anywhere; UX-DESIGN-V2 §2.3). */
.shell-nav{
  position:sticky;top:0;z-index:40;
  background:linear-gradient(180deg,rgba(8,10,14,.96),rgba(8,10,14,.86));
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);
  padding:max(8px,env(safe-area-inset-top)) 14px 0;
}
.shell-nav .shell-row{
  display:flex;gap:4px;align-items:stretch;max-width:1320px;margin:0 auto;
  overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;
}
.shell-nav .shell-row::-webkit-scrollbar{display:none}
.shell-nav .shell-global{padding-bottom:0}
.shell-nav a{
  display:inline-flex;align-items:center;gap:6px;flex:none;
  font-family:var(--mono);font-size:12px;letter-spacing:.04em;
  text-decoration:none;color:var(--dim);
  padding:9px 13px;border-radius:9px 9px 0 0;
  border:1px solid transparent;border-bottom:none;min-height:var(--tap);
  white-space:nowrap;transition:color .2s,background .2s;
}
.shell-nav a:hover{color:var(--text)}
.shell-nav a.active{
  color:var(--text);background:var(--panel);
  border-color:var(--line-2);
  box-shadow:inset 0 2px 0 var(--amber);
}
.shell-nav .shell-tabs{
  border-top:1px solid var(--line);margin-top:6px;padding-top:4px;
}
.shell-nav .shell-tabs a{font-size:11px;letter-spacing:.1em;text-transform:uppercase}
.shell-nav .shell-ws-label{
  display:flex;align-items:center;font-family:var(--font-display);
  font-size:14px;color:var(--text);padding:6px 10px 6px 2px;flex:none;
  letter-spacing:-.01em;
}
.shell-nav .shell-ws-label .crumb{color:var(--slate);margin-right:8px;font-family:var(--mono);font-size:11px}

/* ── off-network badge (claude-tools-4zrn) — painted by shared/sw-register.js ──
 * Shown on the NON-Inbox pull surfaces when navigator reports offline, so the
 * last-known snapshot the shared service worker is serving reads honestly as
 * stale (UX-DESIGN-V2 §2.4 "local == remote", read-only off-network path).
 * Presentation only; sw-register.js toggles [hidden]. */
#offline-badge{
  position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(12px + env(safe-area-inset-bottom));z-index:60;
  padding:6px 13px;border-radius:999px;
  font-family:var(--mono);font-size:12px;letter-spacing:.03em;
  color:var(--amber-soft);background:rgba(40,28,4,.94);
  border:1px solid var(--line-2);box-shadow:0 6px 20px rgba(0,0,0,.45);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  pointer-events:none;
}
#offline-badge[hidden]{display:none}

/* ── per-project RUNNER CARD (shared) — extracted from board.css + workspace.css
 *    in claude-tools-758l so the Board (/board), the per-workspace Board facet
 *    (/ws/<ref>/board), and the Workspaces card (/workspaces) render the runner's
 *    honest state row + the Flow-D desired-state controls IDENTICALLY (one source
 *    of truth: RunnerCard.renderStateRow / renderControls in /shared/runner-card.js).
 *
 *    STATE-ROW selectors stay scoped under .runner (renderStateRow always mounts
 *    into a .runner box on the Board + facet). The CONTROL selectors are BARE so
 *    the four buttons + the pending/stale/error notes also style correctly inside
 *    the Workspaces card's .ws-runner-controls wrapper (which is NOT a .runner).
 *    Presentation only — every honest-state decision lives in board-view.js /
 *    workspaces-view.js. The Board keeps its own .runners GRID + per-runner .rqh
 *    queue line in board.css (those are Board-specific). ── */
.runner{flex:1 1 240px;min-width:0;border:1px solid var(--line);border-radius:13px;
  background:var(--panel);padding:13px 14px}
.runner .rp{font-size:11px;color:var(--dim);letter-spacing:.06em;
  margin-bottom:9px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.runner .rstate{display:flex;align-items:center;gap:9px;font-size:13px;
  font-family:var(--font-display);letter-spacing:-.01em}
.runner .pill{width:8px;height:8px;border-radius:50%;flex:none}
.runner .pill.live{background:var(--mint);box-shadow:0 0 7px var(--mint)}
.runner .pill.attention{background:var(--amber);box-shadow:0 0 7px var(--amber)}
.runner .pill.unknown{background:var(--slate)}
/* g2s — soft 'thinking' visual between 90s and 180s heartbeat age (wire liveness
 * stays 'live' — S-1; this is presentation only). */
.runner .pill.thinking{background:var(--mint);opacity:.55;animation:thinking-pulse 1.6s ease-in-out infinite}
.runner .rstate .pill.thinking + span{color:var(--dim)}
@keyframes thinking-pulse{0%,100%{opacity:.35}50%{opacity:.75}}
@media (prefers-reduced-motion:reduce){.runner .pill.thinking{animation:none;opacity:.55}}
/* S-1: a STALE runner is visually its OWN state — never the live green pill. */
.runner.stale{border-color:rgba(255,107,107,.32);
  background:linear-gradient(160deg,rgba(255,107,107,.09),var(--panel))}
.runner .pill.stale{background:var(--coral);box-shadow:0 0 7px var(--coral)}
.runner.stale .rstate{color:var(--coral)}
.runner .rnote{margin-top:8px;font-size:10px;color:var(--faint);letter-spacing:.04em}
/* 8ag/4g5o — secondary "currently working on" line (ref + optional title). */
.runner .workspace-current-task{display:block;margin-top:6px;font-family:var(--mono);
  font-size:11px;color:var(--dim);letter-spacing:.02em}
.runner .workspace-current-task .workspace-current-task-title{color:var(--faint);font-weight:normal}

/* F2 (claude-tools-8fh) desired-state CONTROL row — BARE selectors (style inside
 * .runner AND the Workspaces card's .ws-runner-controls). Mobile-first: each
 * button ≥44×44px, no hover-only state. ACTIVE = the button matching the current
 * ACTUAL — never desired (the view-models enforce). */
.rctrls{display:flex;flex-wrap:wrap;gap:6px;margin-top:11px}
.rbtn{
  flex:1 1 auto;min-width:72px;min-height:44px;
  padding:10px 12px;border-radius:9px;
  font-family:var(--mono);font-size:12px;letter-spacing:.04em;
  background:var(--panel-2);color:var(--text);
  border:1px solid var(--line-2);
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  touch-action:manipulation;
  transition:background .15s, border-color .15s;
}
.rbtn:focus-visible{outline:2px solid var(--sky);outline-offset:2px}
.rbtn:active{background:var(--ink-2)}
.rbtn.active{
  background:rgba(79,214,160,.15);
  border-color:rgba(79,214,160,.5);
  color:var(--mint);
  font-weight:500;
}
/* S-1: a stale runner has NO live actual to highlight; the renderer drops
 * `active`, but if somehow set we still suppress the green pill look. */
.runner.stale .rbtn.active{
  background:var(--panel-2);border-color:var(--line-2);color:var(--text);
  font-weight:400;
}
.rbtn.busy{opacity:.55;cursor:progress}
.rbtn:disabled{opacity:.55;cursor:not-allowed}
.rpending{
  margin-top:9px;font-size:11px;letter-spacing:.04em;
  padding:7px 10px;border-radius:8px;
  background:rgba(255,180,84,.1);
  border:1px solid rgba(255,180,84,.3);
  color:var(--amber-soft);
}
.rstale{
  margin-top:8px;font-size:10px;letter-spacing:.04em;
  color:var(--coral);
}
.rerr{
  margin-top:8px;font-size:11px;letter-spacing:.02em;
  padding:7px 10px;border-radius:8px;
  background:rgba(255,107,107,.1);
  border:1px solid rgba(255,107,107,.35);
  color:var(--coral);
}
