/* ============================================================
   INSTRUMENT — a design system for AI applications
   ============================================================

   Why this exists: models converge on the same templated look no matter how
   detailed the prompt. You cannot prompt your way out of it, because the
   sameness is in the training distribution, not in your wording.

   This system escapes it by refusing the defaults that produce it — the
   purple-blue gradient, glassmorphism, one uniform radius on everything,
   emoji as iconography, centered everything, pill buttons floating in
   whitespace — and by being designed OUTWARD from the surfaces AI apps
   actually have: streaming text, tool calls, reasoning traces, approval
   gates, and a live cost meter.

   The metaphor is instrumentation: an oscilloscope, a mixing desk, a flight
   panel. Flat fills, hairline rules, near-zero radii, tabular numerics, and
   exactly ONE hot accent used as a signal — never as decoration.

   ACCESSIBILITY IS NOT OPTIONAL HERE:
   - every ink/background pair below states its measured contrast ratio
   - state is NEVER conveyed by color alone — every state carries a mono chip
     label and a distinct glyph or edge treatment
   - prefers-reduced-motion collapses all timing, including the press and
     hold-to-confirm gestures
   ============================================================ */

:root {
  /* ---- COLOR: light ("warm paper, one hot accent") ---- */
  --bg-0: #f4f3ef;        /* panel field */
  --bg-1: #e9e7e0;        /* recessed wells: tool-call bodies, code, streaming well */
  --bg-2: #dedbd2;        /* deeper recess / active row */
  --line-0: #c7c3b8;      /* hairline rules, 1px */
  --line-1: #a9a498;      /* stronger divider / pressed-button rest shadow */
  --ink-0: #16150f;       /* primary text — 17.5:1 on bg-0 */
  --ink-1: #4a473d;       /* secondary text — 7.8:1 */
  --ink-2: #6a6555;       /* tertiary/meta — 5.25:1 on bg-0, 4.71:1 on bg-1 */
  --accent: #b04f0e;      /* the ONE hot color — white on it 5.29:1 */
  --accent-ink: #ffffff;  /* text on solid accent fill */
  --accent-dim: #8f4109;  /* accent used AS text on bg-0, 4.5:1+ */
  --ok: #2f6b3a;          /* success — 5.1:1 as text */
  --warn: #8a5a00;        /* warn — 4.9:1 as text */
  --err: #a3281a;         /* error — 5.3:1 as text */
  --run: #245e8a;         /* running/active — 5.6:1 as text */
  --grid: #00000012;      /* graph-paper overlay */

  /* ---- TYPE ---- */
  --font-mono: "SF Mono", "Berkeley Mono", "IBM Plex Mono", ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  --font-sans: -apple-system, "Segoe UI", system-ui, sans-serif; /* prose only, never chrome */
  --type--2: 0.6875rem;   /* 11px — labels/meta, uppercase, tracked */
  --type--1: 0.8125rem;   /* 13px — secondary */
  --type-0:  0.9375rem;   /* 15px — body default */
  --type-1:  1.125rem;    /* 18px — section values */
  --type-2:  1.75rem;     /* 28px — hero readout (cost meter) */
  --type-3:  2.5rem;      /* 40px — rare top-level KPI */
  --lh-tight: 1.15;
  --lh-body: 1.55;
  --measure-prose: 72ch;  /* cap streamed prose even inside a dense layout */

  /* ---- SPACE / GRID ---- */
  --unit: 4px;
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;
  --rail-width: 320px;        /* apparatus rail: tool calls + cost meter */
  --rail-collapse-bp: 900px;

  /* ---- RADIUS: near-zero. Instrument, not app. ---- */
  --radius-0: 0px;
  --radius-1: 2px;        /* small chips/badges only */
  --radius-pill: 999px;   /* ONLY the live-status dot */

  /* ---- BORDERS ---- */
  --hairline: 1px solid var(--line-0);
  --hairline-strong: 1px solid var(--line-1);

  /* ---- SHADOW: depth from fill + line, not blur ---- */
  --shadow-panel: 0 1px 0 0 var(--line-0) inset, 0 0 0 1px var(--line-0);
  --shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.28);

  /* ---- BUTTON PHYSICS: real press, kept flat and rectangular ---- */
  --shadow-btn-rest: 0 1px 0 0 var(--line-1);
  --shadow-btn-pressed: inset 0 1px 2px rgba(0, 0, 0, 0.35);
  --translate-press: 1px;
  --dur-press: 80ms;
  --dur-release: 180ms;
  --ease-press-down: cubic-bezier(0.4, 0, 1, 1);
  --ease-press-up: cubic-bezier(0.2, 0.9, 0.3, 1.04); /* a catch, not a bounce */

  /* ---- GAUGE / METER ---- */
  --gauge-height: 6px;
  --gauge-notch-width: 1px;
  --gauge-notch-color: var(--line-1);
  --gauge-fill: var(--accent);

  /* ---- MOTION ---- */
  --dur-instant: 60ms;
  --dur-fast: 120ms;
  --dur-med: 220ms;
  --dur-slow: 400ms;
  --ease-snap: cubic-bezier(0.2, 0.8, 0.2, 1);
  --ease-linear: linear;        /* meters/progress — never springy on data */
  --cursor-step: 530ms;         /* streaming block-cursor */
  --throw-confirm-hold: 600ms;  /* CRITICAL approvals require a hold, not a tap */
}

/* ---- DARK: same structure; accent brightened to hold 4.5:1 as text ---- */
@media (prefers-color-scheme: dark) {
  :root {
    --bg-0: #0d0e0c; --bg-1: #161815; --bg-2: #1f221d;
    --line-0: #33362f; --line-1: #4a4e42;
    --ink-0: #eeeee6;  /* ~16.9:1 */
    --ink-1: #b9b6a8;  /* ~9.2:1 */
    --ink-2: #8a8778;  /* ~4.7:1 */
    --accent: #ff8a2e; --accent-ink: #0d0e0c; --accent-dim: #ffab5e;
    --ok: #5fd485; --warn: #e8b23d; --err: #ff6b5c; --run: #6fb3e8;
    --grid: #ffffff10;
    --shadow-raised: 0 1px 3px rgba(0, 0, 0, 0.6);
    --shadow-btn-pressed: inset 0 1px 3px rgba(0, 0, 0, 0.65);
    color-scheme: dark;
  }
}

/* Manual toggle must beat the media query in BOTH directions. */
:root[data-theme="dark"] {
  --bg-0: #0d0e0c; --bg-1: #161815; --bg-2: #1f221d;
  --line-0: #33362f; --line-1: #4a4e42;
  --ink-0: #eeeee6; --ink-1: #b9b6a8; --ink-2: #8a8778;
  --accent: #ff8a2e; --accent-ink: #0d0e0c; --accent-dim: #ffab5e;
  --ok: #5fd485; --warn: #e8b23d; --err: #ff6b5c; --run: #6fb3e8;
  --grid: #ffffff10;
  --shadow-raised: 0 1px 3px rgba(0, 0, 0, 0.6);
  --shadow-btn-pressed: inset 0 1px 3px rgba(0, 0, 0, 0.65);
  color-scheme: dark;
}
:root[data-theme="light"] {
  --bg-0: #f4f3ef; --bg-1: #e9e7e0; --bg-2: #dedbd2;
  --line-0: #c7c3b8; --line-1: #a9a498;
  --ink-0: #16150f; --ink-1: #4a473d; --ink-2: #6a6555;
  --accent: #b04f0e; --accent-ink: #ffffff; --accent-dim: #8f4109;
  --ok: #2f6b3a; --warn: #8a5a00; --err: #a3281a; --run: #245e8a;
  --grid: #00000012;
  color-scheme: light;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-instant: 1ms; --dur-fast: 1ms; --dur-med: 1ms; --dur-slow: 1ms;
    --dur-press: 1ms; --dur-release: 1ms;
    --cursor-step: 0ms; --throw-confirm-hold: 0ms;
  }
}

/* ============================================================
   BASE
   ============================================================ */

.inst {
  background-color: var(--bg-0);
  /* Graph paper. The single move that says "instrument" before you read a word. */
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 32px 32px;
  color: var(--ink-0);
  font-family: var(--font-mono);
  font-size: var(--type-0);
  line-height: var(--lh-body);
  font-variant-numeric: tabular-nums slashed-zero;
}
.inst :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0;
}
.inst-prose {
  font-family: var(--font-sans);
  max-width: var(--measure-prose);
  font-variant-numeric: normal;
}
.inst-label {
  font-size: var(--type--2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-2);
}

/* ---- Layout: stream + apparatus rail ---- */
.inst-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--rail-width);
  gap: var(--s-6);
  align-items: start;
}
@media (max-width: 900px) {
  .inst-layout { grid-template-columns: minmax(0, 1fr); }
}

/* ---- Panel ---- */
.inst-panel {
  background: var(--bg-1);
  border: var(--hairline);
  border-radius: var(--radius-0);
}
.inst-panel-head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border-bottom: var(--hairline);
  font-size: var(--type--2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-2);
}

/* ============================================================
   STATE — color is never the only signal.
   Each state carries a mono chip AND a distinct edge/glyph.
   ============================================================ */

.inst-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 1px var(--s-1);
  border: 1px solid currentColor;
  border-radius: var(--radius-1);
  font-size: var(--type--2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.inst-chip-run { color: var(--run); }
.inst-chip-ok { color: var(--ok); }
.inst-chip-err { color: var(--err); }
.inst-chip-held { color: var(--warn); }

/* Left rail carries the state a second time, structurally. */
.inst-state { border-left: 3px solid var(--line-1); padding-left: var(--s-3); }
.inst-state-run { border-left-color: var(--run); animation: inst-pulse 1.6s var(--ease-linear) infinite; }
.inst-state-ok { border-left-color: var(--ok); }
.inst-state-err { border-left-color: var(--err); }
/* Held: hazard hatching, legible without color perception at all. */
.inst-state-held {
  border-left-color: var(--warn);
  background-image: repeating-linear-gradient(
    45deg, transparent, transparent 6px, var(--warn) 6px, var(--warn) 7px
  );
  background-size: auto;
  background-position: left top;
  background-repeat: no-repeat;
  background-clip: border-box;
}
/* Degraded: diagonal wash across the whole card. */
.inst-degraded {
  background-image: repeating-linear-gradient(
    -45deg, transparent, transparent 8px, var(--warn) 8px, var(--warn) 9px
  );
  background-blend-mode: normal;
  opacity: 0.92;
}

@keyframes inst-pulse { 50% { filter: brightness(1.65); } }
@media (prefers-reduced-motion: reduce) {
  .inst-state-run { animation: none; }
}

/* ============================================================
   STREAMING TEXT — a block cursor that steps, not a fade-in
   ============================================================ */

.inst-stream {
  background: var(--bg-1);
  border: var(--hairline);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.06);
  padding: var(--s-4);
}
.inst-cursor {
  display: inline-block;
  width: 0.55em;
  height: 1.05em;
  margin-left: 1px;
  background: var(--accent);
  vertical-align: text-bottom;
  animation: inst-step var(--cursor-step) steps(1) infinite;
}
@keyframes inst-step { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .inst-cursor { animation: none; opacity: 1; }
}

/* ============================================================
   TOOL CALL — a row on a scope, not a chat bubble
   ============================================================ */

.inst-tool {
  border: var(--hairline);
  background: var(--bg-0);
  margin-bottom: -1px; /* rows share hairlines, like a table */
}
.inst-tool-head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  padding: var(--s-2) var(--s-3);
  background: none;
  border: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}
.inst-tool-name { font-weight: 600; }
.inst-tool-args {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--ink-2);
  font-size: var(--type--1);
}
.inst-tool-dur { color: var(--ink-2); font-size: var(--type--1); }
.inst-tool-body {
  border-top: var(--hairline);
  padding: var(--s-3);
  background: var(--bg-1);
}
.inst-tool-body pre {
  margin: 0;
  font-size: var(--type--1);
  overflow-x: auto;
  color: var(--ink-1);
}

/* ============================================================
   REASONING — collapsed to a scope trace, expandable to text
   ============================================================ */

.inst-trace { display: flex; align-items: center; gap: var(--s-2); }
.inst-trace-spark {
  flex: 1;
  height: 18px;
  min-width: 60px;
  background:
    repeating-linear-gradient(90deg, var(--line-0) 0 1px, transparent 1px 8px),
    linear-gradient(var(--accent), var(--accent));
  background-size: 100% 100%, 100% 1px;
  background-position: 0 0, 0 center;
  background-repeat: repeat, no-repeat;
  opacity: 0.7;
}

/* ============================================================
   APPROVAL GATE — and the hold-to-confirm for irreversible actions
   ============================================================ */

.inst-gate { border: 1px solid var(--warn); background: var(--bg-1); padding: var(--s-4); }
.inst-gate-critical { border-color: var(--err); border-width: 2px; }

.inst-btn {
  font: inherit;
  font-size: var(--type--1);
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--line-1);
  border-radius: var(--radius-0);
  background: var(--bg-0);
  color: var(--ink-0);
  box-shadow: var(--shadow-btn-rest);
  cursor: pointer;
  transition:
    transform var(--dur-release) var(--ease-press-up),
    box-shadow var(--dur-release) var(--ease-press-up);
}
.inst-btn:active {
  transform: translateY(var(--translate-press));
  box-shadow: var(--shadow-btn-pressed);
  transition:
    transform var(--dur-press) var(--ease-press-down),
    box-shadow var(--dur-press) var(--ease-press-down);
}
.inst-btn-accent { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.inst-btn-danger { border-color: var(--err); color: var(--err); }

/* Hold-to-confirm: the fill IS the progress. A stray click cannot fire it. */
.inst-hold { position: relative; overflow: hidden; }
.inst-hold::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--err);
  transform: scaleX(var(--hold-progress, 0));
  transform-origin: left center;
  opacity: 0.22;
  pointer-events: none;
}
.inst-hold > * { position: relative; }

/* ============================================================
   COST METER — a multimeter readout plus a notched gauge
   ============================================================ */

.inst-meter-value {
  font-size: var(--type-2);
  line-height: var(--lh-tight);
  font-variant-numeric: tabular-nums slashed-zero;
}
.inst-gauge {
  position: relative;
  height: var(--gauge-height);
  background: var(--bg-2);
  border: var(--hairline);
  overflow: hidden;
}
.inst-gauge-fill {
  height: 100%;
  background: var(--gauge-fill);
  transition: width var(--dur-med) var(--ease-linear);
}
.inst-gauge-notches {
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    90deg, transparent 0 calc(10% - 1px), var(--gauge-notch-color) calc(10% - 1px) 10%
  );
  pointer-events: none;
}

/* ============================================================
   EMPTY / LOADING / REFUSED — the states everyone forgets
   ============================================================ */

.inst-empty {
  border: 1px dashed var(--line-1);
  padding: var(--s-7) var(--s-4);
  text-align: center;
  color: var(--ink-2);
}
.inst-empty-figure {
  font-size: var(--type-3);
  color: var(--line-1);
  font-variant-numeric: tabular-nums;
}
.inst-skeleton {
  background: linear-gradient(90deg, var(--bg-1) 0%, var(--bg-2) 50%, var(--bg-1) 100%);
  background-size: 200% 100%;
  animation: inst-sweep 1.4s var(--ease-linear) infinite;
  height: 1em;
}
@keyframes inst-sweep { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) {
  .inst-skeleton { animation: none; background: var(--bg-2); }
}
.inst-refused {
  border-left: 3px solid var(--err);
  padding-left: var(--s-3);
  color: var(--ink-1);
}
