/* ================================================================
   CODESAGO — BRIGHT WORKSHOP
   Implements DESIGN.md. Every value here is a token; components use
   tokens, never raw values.

   The product withholds code on purpose. A roomy, warm surface makes
   that read as teaching. An austere one makes it read as punishment.
   ================================================================ */

*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* ── NEUTRALS — tinted toward indigo, never pure grey ───────── */
  --canvas:  #f5f7fd;
  --surface: #ffffff;
  --raised:  #fafbfe;
  --sunken:  #eef1fa;

  --ink:   #0d1231;
  --ink-2: #3e4667;
  --ink-3: #5b6488;

  --line:        #e4e8f4;
  --line-strong: #ccd3e8;

  /* ── BRAND — indigo means "you may act on this" ─────────────── */
  --brand:       #4530d9;
  --brand-hover: #3722b0;
  --brand-wash:  #eeebff;
  --brand-line:  #cdc5ff;
  --brand-on:    #ffffff;

  /* ── ACCENT — earned progress only, never a CTA ─────────────── */
  --accent:      #ff6a3d;
  --accent-wash: #fff0ea;
  --accent-line: #ffd0bd;

  /* ── SIGNAL — describes the student's code ──────────────────── */
  --sig-held:  #a15c00;
  --sig-fault: #cf2338;
  --sig-clear: #0f7b4f;
  --sig-held-wash:  #fff6e6;
  --sig-fault-wash: #ffedef;
  --sig-clear-wash: #e6f6ee;
  --sig-held-line:  #f2d9a8;
  --sig-fault-line: #f8c6cd;
  --sig-clear-line: #b3ddc8;

  /* ── TAGS — pale category chips. Labels, not decoration. ────── */
  --tag-indigo-bg: #ecebff; --tag-indigo-fg: #3d2fb8;
  --tag-green-bg:  #e4f6ec; --tag-green-fg:  #10693f;
  --tag-amber-bg:  #fff3dc; --tag-amber-fg:  #8a5300;
  --tag-rose-bg:   #ffe9ee; --tag-rose-fg:   #b41d40;
  --tag-teal-bg:   #e0f4f6; --tag-teal-fg:   #0d6470;

  --focus-ring: #4530d9;
  --focus-halo: #ffffff;

  /* ── DEPTH — layered, ink-tinted, never pure black ──────────── */
  --shadow-sm: 0 1px 2px rgba(13, 18, 49, .05), 0 1px 3px rgba(13, 18, 49, .04);
  --shadow-md: 0 4px 8px rgba(13, 18, 49, .06), 0 12px 24px rgba(13, 18, 49, .08);
  --shadow-lg: 0 8px 16px rgba(13, 18, 49, .08), 0 28px 56px rgba(13, 18, 49, .16);
  --shadow-brand: 0 1px 2px rgba(69, 48, 217, .24), 0 6px 16px rgba(69, 48, 217, .28);

  /* ── TYPE — three faces, three jobs ─────────────────────────── */
  --display: 'Bricolage Grotesque', 'Inter', -apple-system, sans-serif;
  --font:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono:    'JetBrains Mono', 'Cascadia Code', ui-monospace, monospace;

  --t-xs:   12px;
  --t-sm:   13px;
  --t-base: 15px;
  --t-md:   17px;
  --t-lg:   21px;
  --t-xl:   27px;
  --t-2xl:  36px;
  --t-3xl:  52px;

  /* ── SPACE — 4px base. The fix for "cramped". ───────────────── */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 20px;  --s-6: 24px;  --s-7: 32px;  --s-8: 40px;
  --s-9: 48px;  --s-10: 64px; --s-11: 80px; --s-12: 96px;

  --r-sm: 8px;
  --r: 12px;
  --r-lg: 18px;
  --r-pill: 999px;

  --nav-h: 64px;
  --sb-h: 32px;
  --sidebar-w: 280px;
  /* The sidebar toggle button is a flex child of .workspace, so it takes a
     column of its own beside the sidebar. Named because .workspace-inner has
     to subtract it to stay a constant width. Matches .icon-btn. */
  --rail-w: 40px;

  --ease: cubic-bezier(.2, .7, .3, 1);
  --fast: 130ms var(--ease);
  --med:  220ms var(--ease);

  /* ── ALIASES ─────────────────────────────────────────────────
     ~170 inline styles and three scripts name these. They are how
     this system reaches markup this file does not own. Do not remove. */
  --bg: var(--canvas);   --bg2: var(--surface); --bg3: var(--sunken);
  --stock: var(--canvas); --stock-2: var(--surface); --stock-3: var(--sunken);
  --border: var(--line); --border2: var(--line-strong);
  --rule: var(--line);   --hair: var(--line);
  --text: var(--ink); --text-main: var(--ink);
  --text2: var(--ink-2); --text3: var(--ink-3);
  --primary: var(--brand); --primary-dim: var(--brand-wash);
  --primary-glow: rgba(69, 48, 217, .22);
  --accent-color: var(--accent);
  --font-mono: var(--mono);
  --sage: var(--sig-clear);   --sage-dim: var(--sig-clear-wash);
  --sergeant: var(--sig-fault); --sergeant-dim: var(--sig-fault-wash);
  --buddy: var(--sig-held);   --buddy-dim: var(--sig-held-wash);
  --amber: var(--sig-held);   --amber-dim: var(--sig-held-wash);
  --gold: var(--accent);
  --violet: var(--brand);     --violet-dim: var(--brand-wash);
  --sage-glow: transparent; --sergeant-glow: transparent; --buddy-glow: transparent;
  --radius: var(--r); --radius-sm: var(--r-sm); --radius-lg: var(--r-lg);
  --radius-pill: var(--r-pill);
  --transition: var(--fast);
}

/* ── DARK — a real second design, not an inversion ─────────────
   A deep indigo-navy room. The code is the lit thing; the chrome
   falls back. Brand lifts to stay legible on a dark ground; signal
   inks warm so a fault still reads as a fault. */
[data-theme="dark"] {
  --canvas:  #0b0f1c;
  --surface: #141a2b;
  --raised:  #1b2337;
  --sunken:  #080b14;

  --ink:   #f0f3fb;
  --ink-2: #aab3cc;
  --ink-3: #8892b0;

  --line:        #242c42;
  --line-strong: #38425e;

  --brand:       #8b7cff;
  --brand-hover: #a99dff;
  --brand-wash:  rgba(139, 124, 255, .14);
  --brand-line:  rgba(139, 124, 255, .36);
  --brand-on:    #0b0f1c;

  --accent:      #ff8a63;
  --accent-wash: rgba(255, 138, 99, .14);
  --accent-line: rgba(255, 138, 99, .36);

  --sig-held:  #f5b455;
  --sig-fault: #ff7d8f;
  --sig-clear: #4ed597;
  --sig-held-wash:  rgba(245, 180, 85, .13);
  --sig-fault-wash: rgba(255, 125, 143, .13);
  --sig-clear-wash: rgba(78, 213, 151, .13);
  --sig-held-line:  rgba(245, 180, 85, .34);
  --sig-fault-line: rgba(255, 125, 143, .34);
  --sig-clear-line: rgba(78, 213, 151, .34);

  --tag-indigo-bg: rgba(139,124,255,.16); --tag-indigo-fg: #b3a8ff;
  --tag-green-bg:  rgba(78,213,151,.14);  --tag-green-fg:  #6ee0aa;
  --tag-amber-bg:  rgba(245,180,85,.14);  --tag-amber-fg:  #f7c477;
  --tag-rose-bg:   rgba(255,125,143,.14); --tag-rose-fg:   #ff9aa8;
  --tag-teal-bg:   rgba(56,189,205,.14);  --tag-teal-fg:   #6fd4e0;

  --focus-ring: #8b7cff;
  --focus-halo: #0b0f1c;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-md: 0 4px 8px rgba(0, 0, 0, .5), 0 12px 24px rgba(0, 0, 0, .45);
  --shadow-lg: 0 8px 16px rgba(0, 0, 0, .5), 0 28px 56px rgba(0, 0, 0, .6);
  --shadow-brand: 0 1px 2px rgba(0, 0, 0, .5), 0 6px 18px rgba(139, 124, 255, .28);

  --primary-glow: rgba(139, 124, 255, .28);
}

/* ── BASE ─────────────────────────────────────────────────────── */
html, body { height: 100%; overflow: hidden; }

body {
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--ink-2);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The display face appears at --t-xl and above and nowhere else.
   That restraint is what keeps it from becoming noise. */
h1, h2 {
  font-family: var(--display);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.12;
  color: var(--ink);
}
h3, h4 {
  font-family: var(--font);
  font-weight: 700;
  letter-spacing: -.012em;
  line-height: 1.3;
  color: var(--ink);
}
h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); }
h4 { font-size: var(--t-md); }
strong, b { color: var(--ink); font-weight: 600; }
p { max-width: 72ch; }

code, pre, .code-area, .exec-output, .diff-code, .hc-snippet, .log-id,
.result-time, .line-numbers, .exec-prompt, .frust-val, .nav-frust-val,
.inline-code, .breadcrumb, .statusbar {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
.inline-code {
  font-size: .9em;
  background: var(--brand-wash);
  border: 1px solid var(--brand-line);
  border-radius: var(--r-sm);
  padding: 2px 6px;
  color: var(--brand);
}

a { color: var(--brand); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--brand-hover); }

/* ── BROWSER SURFACES ─────────────────────────────────────────── */
::selection { background: var(--brand-wash); color: var(--brand); }
input, textarea { caret-color: var(--brand); }

* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover { background-color: var(--ink-3); }

/* Two rings so focus survives on white, on indigo, and on a wash. */
:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--focus-halo);
  border-radius: var(--r-sm);
}

input[type="range"] {
  -webkit-appearance: none; appearance: none;
  height: 22px; background: transparent; cursor: pointer;
  accent-color: var(--brand);
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 6px; background: var(--sunken);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
input[type="range"]::-moz-range-track {
  height: 6px; background: var(--sunken);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; margin-top: -7px;
  background: var(--brand); border: 3px solid var(--surface);
  border-radius: var(--r-pill); box-shadow: var(--shadow-sm);
  transition: transform var(--fast);
}
input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.12); }
input[type="range"]::-moz-range-thumb {
  width: 18px; height: 18px; background: var(--brand);
  border: 3px solid var(--surface); border-radius: var(--r-pill);
}

/* ── TOP NAV ──────────────────────────────────────────────────── */
.topnav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 0 var(--s-6);
}
.topnav-left, .topnav-right { display: flex; align-items: center; gap: var(--s-4); }
.nav-divider { width: 1px; height: 24px; background: var(--line); }

.logo { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; }
.logo-mark {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  background: var(--brand); color: var(--brand-on);
  border-radius: 10px;
  font-family: var(--display); font-weight: 800; font-size: var(--t-md);
  box-shadow: var(--shadow-brand);
}
.logo-text {
  font-family: var(--display); font-weight: 800;
  font-size: var(--t-md); color: var(--ink);
  letter-spacing: -.02em;
}

.workspace { display: flex; height: 100vh; padding-top: var(--nav-h); position: relative; }
.main-area { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.main-scroll { flex: 1; overflow-y: auto; overflow-x: hidden; }
.workspace-inner {
  /* Width comes from the viewport, not from the parent. The parent widens by
     --sidebar-w when the history collapses, which used to stretch the editor
     with it; measuring from the viewport instead means the freed space becomes
     margin and the editor keeps the size it had. --rail-w is the toggle
     button's own column and --s-5 covers the scrollbar, so nothing clamps in
     one state and not the other. Wider than the old 1140 cap: the editor is
     the workspace, so it gets the room. */
  width: min(1280px, calc(100vw - var(--sidebar-w) - var(--rail-w) - var(--s-5)));
  margin: 0 auto;
  padding: var(--s-7) var(--s-9) var(--s-10);
  display: flex; flex-direction: column; gap: var(--s-6);
}

/* ── WORKBENCH NAV — the mode switcher ────────────────────────
   A segmented control on one rail, not five loose buttons. The rail
   scrolls sideways on a phone rather than wrapping, so the row keeps
   its shape and the active mode stays findable. */
.workbench-nav {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--s-2);
  overflow: hidden;
}
.workbench-nav-tabs {
  display: flex; align-items: center; gap: var(--s-1);
  overflow-x: auto; scrollbar-width: none;
}
.workbench-nav-tabs::-webkit-scrollbar { display: none; }

.nav-tab {
  display: inline-flex; align-items: center; gap: var(--s-2);
  flex: none; min-height: 40px; padding: 0 var(--s-4);
  font: inherit; font-size: var(--t-sm); font-weight: 600;
  color: var(--ink-3); background: transparent;
  border: 0; border-radius: var(--r-sm);
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background var(--fast), color var(--fast);
}
.nav-tab:hover { background: var(--sunken); color: var(--ink-2); }
.nav-tab.active {
  background: var(--brand); color: var(--brand-on);
  box-shadow: var(--shadow-brand);
}
.nav-tab .tab-icon { width: 17px; height: 17px; flex: none; stroke-width: 1.9; }
.nav-tab .tab-badge {
  font-size: var(--t-xs); font-weight: 700; line-height: 1;
  padding: 3px var(--s-2); border-radius: var(--r-pill);
  background: var(--tag-indigo-bg); color: var(--tag-indigo-fg);
}
.nav-tab.active .tab-badge {
  background: rgba(255, 255, 255, .22); color: var(--brand-on);
}

/* ── SIDEBAR ──────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  border-right: 1px solid var(--line);
  background: var(--surface);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.sidebar.collapsed { width: 0; overflow: hidden; border-right: 0; }
.sidebar-header {
  padding: var(--s-5) var(--s-5) var(--s-4);
  border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-2);
}
.sidebar-footer {
  margin-top: auto; padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--line); background: var(--raised);
}
.sidebar-label { font-size: var(--t-sm); font-weight: 700; color: var(--ink); }
.sidebar-icon { width: 18px; height: 18px; flex-shrink: 0; }
.sidebar-open-btn, .workspace-sidebar-toggle {
  background: var(--surface); border: 1px solid var(--line);
  color: var(--ink-2); border-radius: var(--r-sm);
  padding: var(--s-2); cursor: pointer; font: inherit;
  transition: background var(--fast), color var(--fast), border-color var(--fast);
}
.sidebar-open-btn:hover, .workspace-sidebar-toggle:hover {
  background: var(--brand-wash); color: var(--brand); border-color: var(--brand-line);
}

.statusbar {
  height: var(--sb-h); flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--s-6); border-top: 1px solid var(--line);
  background: var(--surface);
  font-size: var(--t-xs); color: var(--ink-3);
}
.sb-left, .sb-right { display: flex; align-items: center; gap: var(--s-3); }
.sb-sep { color: var(--line-strong); }
.sb-lang, .sb-mentor { color: var(--ink-2); font-weight: 500; }

.breadcrumb {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-sm); color: var(--ink-3); min-width: 0;
}
.bc-file { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bc-sep { color: var(--ink-3); }
.acc-icon { width: 18px; height: 18px; flex-shrink: 0; transition: transform var(--fast); }
.accordion-card.collapsed .acc-icon { transform: rotate(-90deg); }

/* ── PANELS ───────────────────────────────────────────────────
   Roomy white surfaces on a tinted canvas. 24px padding is the
   floor — that is the fix for "cramped". */
.section, .hf-card, .result-panel, .execution-panel, .diff-panel,
.editor-panel, .exec-panel, .accordion-card,
.bug-card, .challenge-card, .perf-card, .diff-section, .highfive-banner {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--s-6);
  margin: 0;
  overflow: hidden;
}
.hf-card-header, .exec-header, .diff-header-row, .result-header, .loading-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); padding-bottom: var(--s-4); margin-bottom: var(--s-5);
  border-bottom: 1px solid var(--line);
}
.result-header-top, .result-header-info { display: flex; align-items: center; gap: var(--s-3); }
.hf-card-title, .exec-title, .diff-title {
  font-size: var(--t-md); font-weight: 700; color: var(--ink);
  letter-spacing: -.012em;
}
.hf-card-body, .exec-body, .result-body { padding: 0; }
.hf-card-text, .res-block-text, .mentor-sub, .empty-sub, .footer-note {
  color: var(--ink-2); max-width: 72ch;
}
.footer-note { font-size: var(--t-sm); color: var(--ink-3); }

.hf-list, .tiplist, .checklist { list-style: none; }
.hf-list li, .tiplist li, .checklist li {
  padding: var(--s-3) 0 var(--s-3) var(--s-6);
  position: relative; border-bottom: 1px solid var(--line);
}
.hf-list li::before, .tiplist li::before, .checklist li::before {
  content: ""; position: absolute; left: var(--s-2); top: 1.1em;
  width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--brand);
}
.hf-list li:last-child, .tiplist li:last-child, .checklist li:last-child { border-bottom: 0; }

.section-label {
  display: flex; align-items: center; gap: var(--s-3);
  font-size: var(--t-md); font-weight: 700; color: var(--ink);
  letter-spacing: -.012em; margin-bottom: var(--s-5);
}
.section-label::before {
  content: ""; width: 4px; height: 20px; flex: none;
  background: var(--brand); border-radius: var(--r-pill);
}
.mt12 { margin-top: var(--s-3); }

/* ── BUTTONS ──────────────────────────────────────────────────
   Every interactive surface lifts on hover. Static hover is why the
   earlier version read as unfinished. */
.btn, .run-btn, .analyze-btn, .tool-btn, .exec-close-btn,
.exec-kill-btn, .explain-error-btn, .diff-toggle, .profile-action-btn,
.profile-theme-btn, .close-exec-btn, .submit-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 40px; padding: 0 var(--s-5);
  font-family: var(--font); font-weight: 600; font-size: var(--t-base);
  letter-spacing: -.008em;
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--r);
  cursor: pointer; white-space: nowrap;
  box-shadow: var(--shadow-sm);
  transition: background var(--fast), color var(--fast), border-color var(--fast),
              box-shadow var(--fast), transform var(--fast);
}
.btn:hover, .analyze-btn:hover, .tool-btn:hover, .diff-toggle:hover,
.profile-action-btn:hover, .profile-theme-btn:hover,
.explain-error-btn:hover, .exec-close-btn:hover {
  background: var(--brand-wash); color: var(--brand);
  border-color: var(--brand-line);
  box-shadow: var(--shadow-md); transform: translateY(-1px);
}
.btn:active, .run-btn:active, .analyze-btn:active { transform: translateY(0); }

.btn-primary, .run-btn, .submit-btn {
  min-height: 44px;
  background: var(--brand); color: var(--brand-on);
  border-color: var(--brand); box-shadow: var(--shadow-brand);
}
.btn-primary:hover, .run-btn:hover, .submit-btn:hover {
  background: var(--brand-hover); border-color: var(--brand-hover);
  color: var(--brand-on); transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(69, 48, 217, .28), 0 10px 24px rgba(69, 48, 217, .34);
}
.btn:disabled, .run-btn:disabled, .analyze-btn:disabled, .btn[disabled],
.submit-btn:disabled {
  color: var(--ink-3); border-color: var(--line);
  background: var(--sunken); box-shadow: none;
  cursor: not-allowed; transform: none;
}
.btn-sm { min-height: 32px; padding: 0 var(--s-4); font-size: var(--t-sm); }

.icon-btn, .btn-icon-wrap {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; padding: 0; min-height: 0;
  background: transparent; border: 1px solid transparent;
  border-radius: var(--r-sm); box-shadow: none;
  color: var(--ink-2); cursor: pointer;
  transition: background var(--fast), color var(--fast);
}
.icon-btn:hover { background: var(--brand-wash); color: var(--brand); transform: none; box-shadow: none; }
.exec-kill-btn {
  border-color: var(--sig-fault-line); color: var(--sig-fault);
  background: var(--sig-fault-wash); box-shadow: none;
}
.exec-kill-btn:hover {
  background: var(--sig-fault); color: var(--surface);
  border-color: var(--sig-fault); transform: translateY(-1px);
}
.analyze-btn-idle { opacity: 1; }

/* A link styled as a button is a button to the eye. */
a.btn, a.btn:hover { text-decoration: none; }
a.btn { color: var(--ink); }
a.btn:hover { color: var(--brand); }
a.btn-primary, a.btn-primary:hover { color: var(--brand-on); }

/* ── CHIPS AND TAGS ───────────────────────────────────────────
   Pale category pills. A chip's colour maps to a real category,
   consistently — they are labels, not decoration. */
.chip, .tag {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-xs); font-weight: 600; letter-spacing: .01em;
  padding: 5px var(--s-3);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  color: var(--ink-2); background: var(--sunken);
  white-space: nowrap;
}
.tag-indigo { background: var(--tag-indigo-bg); color: var(--tag-indigo-fg); border-color: transparent; }
.tag-green  { background: var(--tag-green-bg);  color: var(--tag-green-fg);  border-color: transparent; }
.tag-amber  { background: var(--tag-amber-bg);  color: var(--tag-amber-fg);  border-color: transparent; }
.tag-rose   { background: var(--tag-rose-bg);   color: var(--tag-rose-fg);   border-color: transparent; }
.tag-teal   { background: var(--tag-teal-bg);   color: var(--tag-teal-fg);   border-color: transparent; }

.chip-green {
  border-color: var(--sig-clear-line); color: var(--sig-clear);
  background: var(--sig-clear-wash);
}
.error-pill {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-xs); font-weight: 600; padding: 5px var(--s-3);
  border: 1px solid var(--sig-fault-line); border-radius: var(--r-pill);
  color: var(--sig-fault); background: var(--sig-fault-wash);
}
.ai-badge, .history-badge {
  font-size: var(--t-xs); font-weight: 700; letter-spacing: .01em;
  color: var(--tag-indigo-fg); background: var(--tag-indigo-bg);
  border-radius: var(--r-pill); padding: 3px var(--s-3);
}
.fallback-badge {
  font-size: var(--t-xs); font-weight: 700;
  color: var(--tag-amber-fg); background: var(--tag-amber-bg);
  border-radius: var(--r-pill); padding: 3px var(--s-3);
}

/* ── INPUTS ───────────────────────────────────────────────────── */
.lang-select, .stdin-area, .stdin-inline, .exec-stdin-input,
.stderr-input, .inline-terminal-input, input[type="text"],
input[type="email"], input[type="password"], textarea:not(.code-area) {
  font-family: var(--font); font-size: var(--t-base);
  min-height: 40px; padding: var(--s-2) var(--s-4);
  color: var(--ink); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  transition: border-color var(--fast), box-shadow var(--fast);
}
.stdin-area, .stdin-inline, .exec-stdin-input, .stderr-input,
.inline-terminal-input { font-family: var(--mono); font-size: var(--t-sm); }
.lang-select { font-weight: 500; cursor: pointer; padding-right: var(--s-7); }
.lang-select:hover { border-color: var(--brand-line); }
input:focus, textarea:focus, select:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-wash);
}
::placeholder { color: var(--ink-3); opacity: 1; }

/* Drawn icons only. Emoji are never icons — DESIGN.md §13. */
button svg, .icon-btn svg, .tool-btn svg, .btn svg {
  width: 18px; height: 18px; flex: none; stroke-width: 1.75;
}
.chip svg, .tag svg { width: 14px; height: 14px; stroke-width: 2; }

/* ── EDITOR ───────────────────────────────────────────────────── */
#mainEditorPanel { padding: 0; }
.editor-tabbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap;
  border-bottom: 1px solid var(--line); background: var(--raised);
  padding: var(--s-3) var(--s-5);
}
.editor-tabs { display: flex; gap: var(--s-1); }
.editor-tab {
  font-size: var(--t-sm); font-weight: 600; padding: var(--s-2) var(--s-4);
  color: var(--ink-3); background: transparent;
  border: 0; border-radius: var(--r-sm); cursor: pointer;
  transition: color var(--fast), background var(--fast);
}
.editor-tab:hover { color: var(--ink-2); background: var(--sunken); }
.editor-tab.active-tab {
  color: var(--brand); background: var(--brand-wash);
  box-shadow: inset 0 0 0 1px var(--brand-line);
}
.tab-dot {
  width: 7px; height: 7px; background: var(--accent);
  border-radius: var(--r-pill); display: inline-block; margin-left: var(--s-2);
}
/* A fixed height, so the editor is a workspace rather than a box that grows a
   line every time the student presses Enter. It had no height at all: the
   textarea fell back to its two-row default and the panel resized on every
   keystroke, which is what "the compiler keeps changing size" was. */
.editor-body {
  display: flex; min-height: 0; background: var(--surface);
  height: 58vh; min-height: 340px;
}
.line-numbers {
  padding: var(--s-4) var(--s-3); text-align: right; color: var(--ink-3);
  font-size: var(--t-sm); line-height: 1.75; user-select: none;
  border-right: 1px solid var(--line); background: var(--sunken);
  overflow: hidden; flex-shrink: 0;
}
.code-area {
  flex: 1; padding: var(--s-4) var(--s-5); border: 0; resize: none;
  font-family: var(--mono); font-size: var(--t-sm); line-height: 1.75;
  color: var(--ink); background: transparent; tab-size: 4;
  overflow-y: auto;
}
.code-area:focus { box-shadow: none; }
.editor-actions, .file-actions, .exec-actions, .result-actions {
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
}
.editor-panel > .editor-actions, .editor-panel > .result-actions {
  padding: var(--s-4) var(--s-5); border-top: 1px solid var(--line);
  background: var(--raised);
}

/* ── EXECUTION ────────────────────────────────────────────────── */
.exec-output {
  font-size: var(--t-sm); line-height: 1.7; white-space: pre-wrap;
  padding: var(--s-4) var(--s-5); background: var(--sunken);
  border: 1px solid var(--line); border-radius: var(--r);
  max-height: 340px; overflow: auto; color: var(--ink);
}
.exec-prompt { color: var(--sig-clear); font-weight: 500; }
.exec-stdin-row, .stdin-row, .stderr-row, .typing-row {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) 0; flex-wrap: wrap;
}
.editor-panel > .stderr-row {
  padding: var(--s-4) var(--s-5); border-top: 1px solid var(--line);
}
.stderr-label, .frust-label, .meter-label, .diff-col-label {
  font-size: var(--t-sm); font-weight: 600; color: var(--ink-3);
  display: inline-flex; align-items: center; gap: var(--s-2); flex: none;
}
.stderr-label svg { width: 16px; height: 16px; stroke-width: 2; color: var(--sig-held); }

/* ── THE LADDER — the signature ───────────────────────────────
   Three gates the student cannot skip. Cleared fills indigo, current
   wears a ring, locked stays hollow behind a dashed connector. The
   gate state is the product, so it is drawn, not described. */
.res-block, .hint-block, .tip-block, .analogy-block {
  display: grid;
  grid-template-columns: 36px 1fr;
  gap: var(--s-2) var(--s-4);
  align-items: start;
  padding: var(--s-5) 0;
  position: relative;
}
.res-block + .res-block, .hint-block + .hint-block { border-top: 1px solid var(--line); }

.res-block-label, .hint-label, .tip-label {
  grid-column: 2;
  font-size: var(--t-md); font-weight: 700; color: var(--ink);
  letter-spacing: -.012em;
  display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap;
}
.res-block > *:not(.res-block-label),
.hint-block > *:not(.hint-label),
.tip-block > *:not(.tip-label) { grid-column: 2; }

/* The gate disc. */
.res-block::before, .hint-block::before, .tip-block::before {
  grid-column: 1; grid-row: 1 / span 2;
  content: counter(rung); counter-increment: rung;
  width: 36px; height: 36px; display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--surface); color: var(--ink-3);
  border: 2px solid var(--line-strong);
  font-family: var(--display); font-size: var(--t-base); font-weight: 800;
  transition: background var(--med), color var(--med), border-color var(--med),
              box-shadow var(--med);
}
/* The connector between gates. */
.res-block::after, .hint-block::after {
  content: ""; position: absolute; left: 17px; top: 56px; bottom: -4px;
  width: 2px; border-radius: 2px;
  background: repeating-linear-gradient(
    to bottom, var(--line-strong) 0 4px, transparent 4px 9px);
}
.res-block:last-child::after, .hint-block:last-child::after { display: none; }

.result-body, #resultContent, .hint-ladder { counter-reset: rung; }

/* Locked — hollow, muted, dashed connector in. */
.hint-block[data-state="held"] .hint-label,
.res-block[data-state="held"] .res-block-label { color: var(--ink-3); }
.hint-block[data-state="held"]::before,
.res-block[data-state="held"]::before {
  background: var(--sunken); color: var(--ink-3); border-color: var(--line-strong);
}
.hint-block[data-state="held"] .hint-label::after {
  content: "Locked";
  font-family: var(--font); font-size: var(--t-xs); font-weight: 600;
  letter-spacing: .01em; text-transform: none;
  color: var(--sig-held); background: var(--sig-held-wash);
  border: 1px solid var(--sig-held-line); border-radius: var(--r-pill);
  padding: 3px var(--s-3);
}

/* Cleared — filled indigo, solid connector out. */
.hint-block[data-state="released"] .hint-label { color: var(--ink); }
.hint-block[data-state="released"]::before,
.res-block[data-state="released"]::before {
  background: var(--brand); color: var(--brand-on); border-color: var(--brand);
  box-shadow: var(--shadow-brand);
}
.hint-block[data-state="released"]::after,
.res-block[data-state="released"]::after { background: var(--brand); }

/* Current — where you are. A ring and a halo, no fill. */
.hint-block[data-state="current"]::before,
.res-block[data-state="current"]::before {
  background: var(--surface); color: var(--brand); border-color: var(--brand);
  box-shadow: 0 0 0 5px var(--brand-wash);
}

/* Step two names the line without touching it. */
.hint-block[data-step="2"] .res-block-text { position: relative; padding-left: var(--s-5); }
.hint-block[data-step="2"] .res-block-text::before {
  content: ""; position: absolute; left: 0; top: .72em;
  width: 12px; height: 2px; border-radius: 2px; background: var(--brand);
}

/* ── DIFF ─────────────────────────────────────────────────────── */
.diff-cols {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
}
.diff-col { padding: var(--s-4) var(--s-5); }
.diff-col + .diff-col { border-left: 1px solid var(--line); }
.diff-col-label { display: flex; margin-bottom: var(--s-3); }
.diff-before { background: var(--sig-fault-wash); }
.diff-before .diff-col-label { color: var(--sig-fault); }
.diff-after { background: var(--sig-clear-wash); }
.diff-after .diff-col-label { color: var(--sig-clear); }
.diff-code { font-size: var(--t-sm); line-height: 1.7; white-space: pre-wrap; color: var(--ink); }

/* ── HISTORY ──────────────────────────────────────────────────── */
.history-list { display: flex; flex-direction: column; gap: var(--s-1); padding: var(--s-3); }
.history-card {
  padding: var(--s-3) var(--s-4); border: 1px solid transparent;
  border-radius: var(--r-sm); cursor: pointer;
  transition: background var(--fast), border-color var(--fast), transform var(--fast);
}
.history-card:hover {
  background: var(--brand-wash); border-color: var(--brand-line);
  transform: translateX(2px);
}
.hc-top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }
.hc-type { font-size: var(--t-sm); font-weight: 700; color: var(--ink); }
.hc-meta, .log-id, .result-time { font-size: var(--t-xs); color: var(--ink-3); }
.hc-snippet {
  font-size: var(--t-xs); color: var(--ink-2); margin-top: var(--s-1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Empty states name the next action — they never shrug. */
.history-empty { padding: var(--s-8) var(--s-5); text-align: center; }
.empty-icon {
  width: 48px; height: 48px; margin: 0 auto var(--s-4);
  display: grid; place-items: center; border-radius: var(--r-pill);
  background: var(--brand-wash); color: var(--brand);
}
.empty-icon svg { width: 22px; height: 22px; stroke-width: 1.75; }
/* Signal inks, not brand: these describe a state of the student's data, and
   indigo is reserved for things that can be acted on. */
.empty-icon-fault { background: var(--sig-fault-wash); color: var(--sig-fault); }
.empty-icon-held  { background: var(--sig-held-wash);  color: var(--sig-held); }
.empty-action { margin-top: var(--s-4); }
.empty-title { font-size: var(--t-base); font-weight: 700; color: var(--ink); margin-bottom: var(--s-1); }
.empty-sub { font-size: var(--t-sm); color: var(--ink-3); margin: 0 auto; }

/* ── MENTOR CARDS ─────────────────────────────────────────────── */
.mentor-row { display: flex; align-items: stretch; gap: var(--s-3); flex-wrap: wrap; }
.mentor-card {
  flex: 1 1 180px; min-width: 0; text-align: left;
  padding: var(--s-4) var(--s-5); cursor: pointer;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); font: inherit;
  transition: border-color var(--fast), background var(--fast),
              box-shadow var(--fast), transform var(--fast);
}
.mentor-card:hover {
  border-color: var(--brand-line); box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.mentor-emoji { display: none; } /* icons are drawn, never glyphs */
.mentor-name { font-size: var(--t-base); font-weight: 700; color: var(--ink); }
.mentor-sub { font-size: var(--t-sm); color: var(--ink-3); margin-top: 2px; }

/* Selection is an action state, so it reads in the brand. The mentor's
   own colour stays on their replies, where it means tone. */
.mentor-card.active-sage, .mentor-card.active-sergeant,
.mentor-card.active-buddy, .mentor-card.active-card {
  border-color: var(--brand); background: var(--brand-wash);
  box-shadow: inset 0 0 0 1px var(--brand), var(--shadow-sm);
}
.mentor-card.active-sage .mentor-name,
.mentor-card.active-sergeant .mentor-name,
.mentor-card.active-buddy .mentor-name { color: var(--brand); }
.sage-color { color: var(--sig-clear); }
.sergeant-color { color: var(--sig-fault); }
.buddy-color { color: var(--sig-held); }
.sage-label { font-size: var(--t-xs); font-weight: 600; }

.result-avatar {
  width: 40px; height: 40px; display: grid; place-items: center;
  border-radius: var(--r-pill); background: var(--sunken);
  border: 1px solid var(--line); flex: none; color: var(--ink-2);
}
.result-sage .result-avatar {
  background: var(--sig-clear-wash); border-color: var(--sig-clear-line); color: var(--sig-clear);
}
.result-sergeant .result-avatar {
  background: var(--sig-fault-wash); border-color: var(--sig-fault-line); color: var(--sig-fault);
}
.result-buddy .result-avatar {
  background: var(--sig-held-wash); border-color: var(--sig-held-line); color: var(--sig-held);
}
.result-mentor-name { font-size: var(--t-md); font-weight: 700; color: var(--ink); }

/* ── METERS AND STATUS ────────────────────────────────────────── */
.meter-row { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) 0; font-size: var(--t-sm); }
.meter-track {
  flex: 1; height: 8px; background: var(--sunken);
  border: 1px solid var(--line); border-radius: var(--r-pill); overflow: hidden;
}
/* The fill scales rather than resizing: animating width relayouts the
   track every frame, a transform does not. */
.meter-fill {
  height: 100%; width: 100%; background: var(--brand);
  border-radius: var(--r-pill);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 600ms var(--ease);
}
.status-dot-wrap, .agent-status-wrap { display: flex; align-items: center; gap: var(--s-2); }
.status-dot, .agent-dot, .live-dot, .dot {
  width: 8px; height: 8px; background: var(--ink-3);
  border-radius: var(--r-pill); flex-shrink: 0;
}
.live-dot, .agent-dot { background: var(--sig-clear); }
.status-dot.ai-online, .agent-dot.ai-online { background: var(--sig-clear); }
.status-dot.ai-offline, .agent-dot.ai-offline { background: var(--sig-fault); }
.agent-label.ai-online, .status-text.ai-online { color: var(--sig-clear); font-weight: 500; }
.agent-label.ai-offline, .status-text.ai-offline { color: var(--sig-fault); font-weight: 500; }
.dots { display: inline-flex; gap: var(--s-1); }
.status-text, .agent-label { font-size: var(--t-sm); color: var(--ink-3); }

.frustration-control, .nav-frustration { display: flex; align-items: center; gap: var(--s-3); }
.frust-val, .nav-frust-val {
  font-family: var(--mono); font-size: var(--t-sm); font-weight: 600;
  color: var(--brand); background: var(--brand-wash);
  border-radius: var(--r-sm); padding: 2px var(--s-2);
  min-width: 28px; text-align: center;
}

/* ── SKELETONS ────────────────────────────────────────────────── */
.skel, .skel-avatar, .skel-lines { background: var(--sunken); border-radius: var(--r-sm); }
.skel { height: 14px; margin-bottom: var(--s-2); }
.skel-avatar { width: 40px; height: 40px; border-radius: var(--r-pill); }
.skel-lines > * + * { margin-top: var(--s-2); }
.skel.short { width: 62%; }
.skel.xshort { width: 34%; }

/* ── NAV MENU AND AVATAR ──────────────────────────────────────── */
.avatar-btn {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  background: var(--brand); color: var(--brand-on);
  border: 0; border-radius: var(--r-pill);
  font: inherit; font-weight: 700; font-size: var(--t-sm);
  cursor: pointer; box-shadow: var(--shadow-brand);
  transition: transform var(--fast), box-shadow var(--fast);
}
.avatar-btn:hover { transform: translateY(-1px) scale(1.04); }

/* app.js animates opacity and transform inline, so the resting state
   and the transition live here and the script only flips the values. */
.nav-menu {
  position: absolute; top: calc(100% + 12px); right: 0;
  width: 236px; z-index: 1000;
  display: flex; flex-direction: column; gap: 2px; padding: var(--s-2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow-lg);
  opacity: 0; transform: translateY(-8px); pointer-events: none;
  transition: opacity var(--med), transform var(--med);
}
.nav-menu-label {
  padding: var(--s-2) var(--s-3) var(--s-3); margin-bottom: var(--s-1);
  border-bottom: 1px solid var(--line);
  font-size: var(--t-xs); font-weight: 700; color: var(--ink-3);
  letter-spacing: .05em; text-transform: uppercase;
}
.nav-menu-item {
  width: 100%; text-align: left; padding: var(--s-3);
  border: 0; border-radius: var(--r-sm); background: transparent;
  color: var(--ink-2); font: inherit; font-size: var(--t-base);
  cursor: pointer; transition: background var(--fast), color var(--fast);
}
.nav-menu-item:hover { background: var(--brand-wash); color: var(--brand); }

/* ── MODAL ────────────────────────────────────────────────────── */
.modal-scrim {
  position: fixed; inset: 0; z-index: 10000;
  display: flex; align-items: center; justify-content: center; padding: var(--s-6);
  background: rgba(9, 12, 30, .55);
  backdrop-filter: blur(3px);
}
.modal-card {
  width: 100%; max-width: 460px; padding: var(--s-7);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
}
.modal-card h2 { font-size: var(--t-lg); margin-bottom: var(--s-3); }
.modal-card p { color: var(--ink-2); margin-bottom: var(--s-6); }
.modal-actions { display: flex; gap: var(--s-3); justify-content: flex-end; flex-wrap: wrap; }

/* ── SLIDE PANEL AND PROFILE ──────────────────────────────────── */
.slide-panel {
  position: fixed; top: 0; right: 0; height: 100vh; width: min(440px, 100vw);
  background: var(--surface); border-left: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column; z-index: 9999;
  transform: translateX(100%);
  transition: transform 280ms var(--ease);
}
.slide-panel.active { transform: translateX(0); }
.slide-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-5) var(--s-6); border-bottom: 1px solid var(--line);
  font-size: var(--t-md); font-weight: 700; color: var(--ink);
}
.slide-panel-body { flex: 1; overflow-y: auto; padding: var(--s-6); }
.profile-stat-card {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-4) var(--s-5); margin-bottom: var(--s-2);
  background: var(--raised); border: 1px solid var(--line);
  border-radius: var(--r); font-size: var(--t-base);
}
.profile-stat-card > *:last-child { font-family: var(--mono); font-weight: 700; color: var(--ink); }
#btnOpenProfile { cursor: pointer; }
#resultContent { min-width: 0; }

.profile-header { padding: var(--s-7) var(--s-6); border-bottom: 1px solid var(--line); position: relative; }
.profile-close { position: absolute; top: var(--s-4); right: var(--s-4); }
.profile-avatar-lg {
  width: 72px; height: 72px; flex-shrink: 0;
  display: grid; place-items: center; border-radius: var(--r-pill);
  background: var(--brand); color: var(--brand-on);
  font-family: var(--display); font-size: var(--t-xl); font-weight: 800;
  box-shadow: var(--shadow-brand);
}
.profile-email { font-size: var(--t-sm); color: var(--ink-3); margin-bottom: var(--s-3); }
.profile-action-btn {
  width: 100%; text-align: left; justify-content: flex-start;
  border-radius: var(--r-sm); background: var(--raised);
  border-color: var(--line); font-weight: 500; box-shadow: none;
}
.profile-action-btn.danger {
  color: var(--sig-fault); background: var(--sig-fault-wash);
  border-color: var(--sig-fault-line);
}
.profile-action-btn.danger:hover {
  background: var(--sig-fault); color: var(--surface);
  border-color: var(--sig-fault);
}

#mouse-glow, .mouse-glitter { display: none !important; }

/* ── UTILITIES ────────────────────────────────────────────────
   app.js writes these class names into innerHTML. There is
   no Tailwind here and no build step, so every class the scripts emit
   must be defined or it renders as nothing. Mapped to project tokens. */
.hidden { display: none !important; }
.custom-scroll { overflow-y: auto; }
.relative { position: relative; }
.overflow-hidden { overflow: hidden; }
.w-full { width: 100%; }
.flex { display: flex; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.items-end { align-items: flex-end; }
.justify-between { justify-content: space-between; }
.justify-center { justify-content: center; }
.flex-shrink-0 { flex-shrink: 0; }
.min-w-0 { min-width: 0; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-center { text-align: center; }
.font-medium { font-weight: 500; }
.font-mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.space-fill { flex: 1; }

.gap-1\.5 { gap: 6px; }
.gap-2 { gap: var(--s-2); }
.mb-0 { margin-bottom: 0; }
.mb-2 { margin-bottom: var(--s-2); }
.mb-3 { margin-bottom: var(--s-3); }
.mb-4 { margin-bottom: var(--s-4); }
.mt-1 { margin-top: var(--s-1); }
.mt-2 { margin-top: var(--s-2); }
.ml-2 { margin-left: var(--s-2); }
.px-5 { padding-left: var(--s-5); padding-right: var(--s-5); }
.py-6 { padding-top: var(--s-6); padding-bottom: var(--s-6); }
.h-3\.5 { height: 14px; }
.w-3\.5 { width: 14px; }
.opacity-25 { opacity: .25; }
.opacity-75 { opacity: .75; }

.text-\[10px\] { font-size: var(--t-xs); }
.text-\[11px\] { font-size: var(--t-xs); }
.text-xs { font-size: var(--t-sm); }
.text-sm { font-size: var(--t-base); }
.text-3xl {
  font-family: var(--display); font-size: var(--t-2xl);
  font-weight: 800; letter-spacing: -.025em; color: var(--ink);
}
.text-slate-100 { color: var(--ink); }
.text-slate-400 { color: var(--ink-3); }
.text-slate-500 { color: var(--ink-3); }
.text-slate-600 { color: var(--ink-2); }
.text-rose-400 { color: var(--sig-fault); }

/* ── MOTION ───────────────────────────────────────────────────
   The ladder advancing is the one orchestrated moment. Everything
   else is micro-interaction on hover and focus. */
@keyframes gate-clear {
  0%   { opacity: 0; transform: translateY(8px); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: translateY(0); }
}
.hint-block[data-state="released"], .res-block.slide-up {
  animation: gate-clear 320ms var(--ease) both;
}
@keyframes spin { to { transform: rotate(360deg); } }
.spin, .animate-spin { animation: spin 900ms linear infinite; transform-origin: center; }
@keyframes btn-shimmer { 0%, 100% { opacity: 1; } 50% { opacity: .6; } }
.btn-shimmer-anim { animation: btn-shimmer 1.2s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .btn:hover, .mentor-card:hover, .history-card:hover,
  .btn-primary:hover, .avatar-btn:hover { transform: none !important; }
}

/* ── RESPONSIVE — designed, not shrunk ────────────────────────── */
@media (max-width: 1279px) {
  :root { --sidebar-w: 248px; }
  .workspace-inner { padding: var(--s-6) var(--s-6) var(--s-9); }
}

@media (max-width: 767px) {
  .workspace { flex-direction: column; }
  .main-area { order: 1; min-height: 0; }
  .sidebar {
    order: 2; width: 100%; max-height: 42vh;
    border-right: 0; border-top: 1px solid var(--line);
  }
  .sidebar.collapsed { display: none; }

  /* On a phone the editor goes first. A student opened this to paste a
     traceback, not to pick a mentor. */
  /* The sidebar stacks below the editor here rather than sitting beside it,
     so there is no sidebar width to subtract. */
  .workspace-inner {
    width: 100%;
    padding: var(--s-4) var(--s-4) var(--s-7); gap: var(--s-4);
  }
  .editor-body { height: 48vh; min-height: 260px; }
  #rightWorkspaceWrapper { order: -1; }

  .section, .hf-card, .result-panel, .execution-panel, .diff-panel,
  .editor-panel, .exec-panel, .accordion-card, .bug-card,
  .challenge-card, .perf-card, .diff-section, .highfive-banner {
    padding: var(--s-5);
  }
  .diff-cols { grid-template-columns: 1fr; }
  .diff-col + .diff-col { border-left: 0; border-top: 1px solid var(--line); }
  .editor-tabbar, .editor-panel > .editor-actions,
  .editor-panel > .stderr-row { padding: var(--s-3) var(--s-4); }
  .mentor-card { flex-basis: 100%; }

  /* The nav is rebuilt for the phone, not squeezed. The server and AI
     wording collapses to its two dots, which is the whole signal. */
  .topnav { padding: 0 var(--s-4); gap: var(--s-3); flex-wrap: nowrap; }
  .topnav-left { flex: 1; min-width: 0; }
  .topnav-left, .topnav-right { gap: var(--s-3); }
  .logo-text { font-size: var(--t-base); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .status-text, .agent-label, #navUsername, .nav-divider { display: none; }
  .status-dot-wrap, .agent-status-wrap { gap: 0; }
}

@media (max-width: 480px) {
  /* The filename loses to the mark: the file is named again in the
     editor tab two rows down; the product is named nowhere else. */
  .breadcrumb { display: none; }
  .res-block, .hint-block, .tip-block, .analogy-block {
    grid-template-columns: 30px 1fr; gap: var(--s-2) var(--s-3);
  }
  .res-block::before, .hint-block::before, .tip-block::before {
    width: 30px; height: 30px; font-size: var(--t-sm);
  }
  .res-block::after, .hint-block::after { left: 14px; top: 48px; }
  .btn, .run-btn, .analyze-btn, .tool-btn { padding: 0 var(--s-4); }
}

@media (min-width: 1920px) {
  .workspace-inner { max-width: 1320px; padding-left: var(--s-10); padding-right: var(--s-10); }
}

/* ── CODE ANALYSIS REPORT ─────────────────────────────────────────
   The mentor's answer, in the panel. Three parts, in the order a
   student needs them: the count, the one mistake to fix first (the
   ladder), then everything else the file is carrying.

   Every value here is a token. The report is a light surface first;
   the dark block below is a second design, not an inversion.
   ────────────────────────────────────────────────────────────── */

.slide-panel-body > * + * { margin-top: var(--s-6); }

/* ── Header ─────────────────────────────────────────────────── */
.report-head {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  box-shadow: var(--shadow-sm);
}
.report-title {
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 600;
  line-height: 1.15;
  color: var(--ink);
  margin: 0;
}
.report-sub {
  margin: var(--s-2) 0 0;
  font-size: var(--t-sm);
  color: var(--ink-3);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2);
}
.report-file {
  font-family: var(--mono);
  color: var(--ink-2);
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 2px var(--s-2);
  /* A 60-character filename must not push the count off the row. */
  max-width: 100%;
  overflow-wrap: anywhere;
}

/* One even row, never a 3+1 orphan: there are at most four tiles (total plus
   three categories) and the panel is fixed-width, so equal flex beats an
   auto-fit grid that wraps the last one onto its own line. */
.report-tiles {
  display: flex;
  gap: var(--s-3);
  margin-top: var(--s-5);
}
.report-tile { flex: 1 1 0; min-width: 0; }
.report-tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}
.tile-label {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--ink-3);
}
.tile-num {
  font-family: var(--display);
  font-size: var(--t-xl);
  font-weight: 700;
  line-height: 1;
}
/* Hue carries category, not severity - these are the label hues from
   the tag set, used consistently wherever a category is named. */
.tile-total    { color: var(--sig-fault); }
.tile-syntax   { color: var(--tag-amber-fg); }
.tile-logic    { color: var(--tag-teal-fg); }
.tile-spelling { color: var(--tag-rose-fg); }

/* ── Section headings ───────────────────────────────────────── */
.report-section-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 var(--s-4);
}
.group-count {
  flex: none;
  font-size: var(--t-xs);
  font-weight: 700;
  border-radius: var(--r-pill);
  padding: 3px var(--s-3);
}
.group-count-syntax   { color: var(--tag-amber-fg); background: var(--tag-amber-bg); }
.group-count-logic    { color: var(--tag-teal-fg);  background: var(--tag-teal-bg); }
.group-count-spelling { color: var(--tag-rose-fg);  background: var(--tag-rose-bg); }

/* ── Findings ───────────────────────────────────────────────── */
.report-group {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  box-shadow: var(--shadow-sm);
}
.finding {
  border-left: 3px solid var(--line-strong);
  border-radius: 0 var(--r) var(--r) 0;
  background: var(--raised);
  padding: var(--s-4) var(--s-5);
  transition: transform var(--fast), box-shadow var(--fast);
}
.finding + .finding { margin-top: var(--s-3); }
.finding:hover {
  transform: translateX(2px);
  box-shadow: var(--shadow-sm);
}
.finding-syntax   { border-left-color: var(--tag-amber-fg); }
.finding-logic    { border-left-color: var(--tag-teal-fg); }
.finding-spelling { border-left-color: var(--tag-rose-fg); }

.finding-title {
  margin: 0;
  font-size: var(--t-base);
  font-weight: 700;
  color: var(--ink);
  line-height: 1.4;
}
.finding-lead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2);
  margin: var(--s-3) 0 0;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  background: var(--sunken);
  font-size: var(--t-sm);
  line-height: 1.55;
  color: var(--ink-2);
}
.finding-lead-label {
  flex: none;
  font-size: var(--t-xs);
  font-weight: 700;
  color: var(--ink-3);
}
.finding-lead-label::after { content: ' \2192'; }
.finding-lead-value { overflow-wrap: anywhere; }
.finding-lead-value.is-code {
  font-family: var(--mono);
  color: var(--ink);
}
.finding-syntax .finding-lead   { background: var(--tag-amber-bg); }
.finding-logic .finding-lead    { background: var(--tag-teal-bg); }
.finding-spelling .finding-lead { background: var(--tag-rose-bg); }
.finding-syntax .finding-lead-label   { color: var(--tag-amber-fg); }
.finding-logic .finding-lead-label    { color: var(--tag-teal-fg); }
.finding-spelling .finding-lead-label { color: var(--tag-rose-fg); }

.finding-detail {
  margin: var(--s-3) 0 0;
  font-size: var(--t-base);
  line-height: 1.65;
  color: var(--ink-2);
}

/* ── Empty report — names the next action, never a blank panel ── */
.report-empty {
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
  padding: var(--s-6);
}
.report-empty p {
  margin: 0;
  font-size: var(--t-base);
  line-height: 1.65;
  color: var(--ink-2);
}
.report-empty-clear {
  border-style: solid;
  border-color: var(--sig-clear-line);
  background: var(--sig-clear-wash);
}
.report-empty-clear .report-section-title { color: var(--sig-clear); }

.report-concept {
  margin: var(--s-4) 0 0;
  font-size: var(--t-sm);
  color: var(--ink-3);
}

@media (prefers-reduced-motion: reduce) {
  .finding:hover { transform: none; }
}

/* ── PROBLEM SPLIT VIEW ───────────────────────────────────────────
   Opening a problem used to set flex-direction: row inline on
   .workspace-inner, which is a column containing seven panels - the
   nav tabs included - so every one of them was laid out side by side
   and collapsed. Nothing cleared it afterwards either, which is what
   crushed the course reader to a one-character column.

   The layout lives here instead, and it only ever moves the two
   panels that belong in a split: the description and the editor.
   Hidden siblings are display:none, so grid never allots them a cell.
   ────────────────────────────────────────────────────────────── */
.workspace-inner.split-view {
  display: grid;
  grid-template-columns: minmax(300px, 2fr) 3fr;
  align-items: start;
}
/* Placed explicitly rather than left to auto-flow: the container also holds
   the nav, several hidden panels and a trailing spacer, and auto-flow gave
   the nav a cell and pushed the editor onto its own row. */
.workspace-inner.split-view > * { grid-column: 1 / -1; }
.workspace-inner.split-view > #problemDescriptionPane {
  grid-column: 1;
  grid-row: 2;
  position: sticky;
  top: var(--s-5);
  /* .editor-panel is a block with overflow:hidden, so the description was
     clipped at the panel edge and nothing scrolled - the tail of every
     problem was unreachable. Flex column instead: the header keeps its
     height, #probDescContent takes the rest and scrolls itself. */
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 140px);
  overflow: hidden;
}
/* A flex child defaults to min-height:auto, which refuses to shrink below its
   content - the scroll would never engage without this. */
.workspace-inner.split-view > #problemDescriptionPane > #probDescContent {
  flex: 1 1 auto;
  min-height: 0;
}
.workspace-inner.split-view > #problemDescriptionPane > :first-child { flex-shrink: 0; }
.workspace-inner.split-view > #rightWorkspaceWrapper {
  grid-column: 2;
  grid-row: 2;
}

/* One column below the laptop breakpoint: a 300px description beside a
   300px editor helps nobody. The description leads, the editor follows. */
@media (max-width: 1023px) {
  .workspace-inner.split-view {
    grid-template-columns: 1fr;
  }
  .workspace-inner.split-view > #problemDescriptionPane,
  .workspace-inner.split-view > #rightWorkspaceWrapper {
    grid-column: 1 / -1;
    grid-row: auto;
  }
  .workspace-inner.split-view > #problemDescriptionPane {
    position: static;
    max-height: 46vh;
  }
}

/* ── COURSE READER ───────────────────────────────────────────────
   A flex child's min-width is auto, so the lesson pane refused to
   shrink politely and then collapsed instead. The contents-of-the-
   course rail keeps its width; the reader keeps a floor. */
#courseToc { flex: 0 0 250px; min-width: 0; }
#courseLessonContent { flex: 1 1 auto; min-width: 0; }

@media (max-width: 767px) {
  #courseArenaPanel > div:last-child { flex-direction: column; }
  #courseToc {
    flex: 0 0 auto;
    width: 100%;
    max-height: 34vh;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
}

/* ── FLOATING PROBLEM-CHAT BUTTON ────────────────────────────────
   Was a 50x50 square of --primary with no icon inside and no radius,
   parked bottom-left: the stray purple block. It is a real control
   now, and switchWorkbenchView hides it when the problem view closes. */
#btnToggleProblemChat {
  /* Fixed to the viewport, clear of both the left rail and the status bar.
     At bottom-left it sat on top of the sidebar's own footer text. */
  position: fixed;
  bottom: calc(var(--s-6) + 28px);
  right: var(--s-6);
  width: 52px;
  height: 52px;
  border-radius: var(--r-pill);
  background: var(--brand);
  color: var(--brand-on);
  border: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 40;
  box-shadow: var(--shadow-brand), var(--shadow-md);
  transition: transform var(--fast), background var(--fast);
}
#btnToggleProblemChat:hover {
  background: var(--brand-hover);
  transform: translateY(-2px);
}
#btnToggleProblemChat:active { transform: translateY(0); }
#btnToggleProblemChat svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── DIALOGS ─────────────────────────────────────────────────────
   Replacing window.alert / confirm / prompt. Reuses .modal-scrim and
   .modal-card; only the form parts are new. */
.dlg-label {
  display: block;
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: var(--s-2);
}
.dlg-input {
  width: 100%;
  min-height: 40px;
  padding: 0 var(--s-3);
  font-size: var(--t-base);
  font-family: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  margin-bottom: var(--s-3);
}
.dlg-input:hover { border-color: var(--brand-line); }
.dlg-error {
  margin: calc(var(--s-2) * -1) 0 var(--s-3);
  font-size: var(--t-sm);
  color: var(--sig-fault);
}
.btn-danger {
  color: var(--brand-on);
  background: var(--sig-fault);
  border: 1px solid var(--sig-fault);
}
.btn-danger:hover { filter: brightness(.93); }

/* ── TOASTS ──────────────────────────────────────────────────────
   For things that only need acknowledging. Bottom-centre so it never
   collides with the chat button in the bottom-left corner. */
#toastHost {
  position: fixed;
  bottom: var(--s-8);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  z-index: 200;
  pointer-events: none;
}
.toast {
  padding: var(--s-3) var(--s-5);
  max-width: min(92vw, 460px);
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  box-shadow: var(--shadow-md);
  opacity: 1;
  transition: opacity var(--fast), transform var(--fast);
}
.toast-out { opacity: 0; transform: translateY(6px); }
.toast-clear { border-color: var(--sig-clear-line); background: var(--sig-clear-wash); }
.toast-fault { border-color: var(--sig-fault-line); background: var(--sig-fault-wash); }

/* ── API ERROR IN THE RESULT PANEL ───────────────────────────── */
.api-error {
  border-color: var(--sig-fault-line);
  background: var(--sig-fault-wash);
}
.api-error .report-section-title { color: var(--sig-fault); }

@media (prefers-reduced-motion: reduce) {
  #btnToggleProblemChat:hover { transform: none; }
  .toast-out { transform: none; }
}

/* ── PROBLEM HEADER META ─────────────────────────────────────────
   The topics row (#probTopicsDisplay) did not exist in the markup at
   all, so openProblem threw setting it and the description, the chat
   reset and the editor clear that followed never ran - the problem
   opened blank. Chips reuse the .tag set rather than inline styles. */
.prob-difficulty {
  padding: 3px var(--s-3);
  font-size: var(--t-xs);
  font-weight: 700;
  border-radius: var(--r-pill);
  color: var(--sig-clear);
  background: var(--sig-clear-wash);
  border: 1px solid var(--sig-clear-line);
}
.prob-topics { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* ── REPORT, second pass ─────────────────────────────────────────
   Matches the Figma "Code analysis report" (frame 10) now that the
   ladder is out of the panel: numbered cards inside each group, the
   evidence strip set in mono, and the fix at the end behind a button.

   Numbering is back because the ladder no longer owns it here. If the
   ladder returns to this panel, DESIGN.md's rule applies again and
   these numbers come out.

   The palette is tokens, not the hexes this block first shipped with.
   Those were stock Tailwind (#f59e0b, #64748b) plus a hardcoded dark
   chip (#27272a on #ffffff) that sat outside any [data-theme] scope, so
   the report rendered its dark treatment in light mode too. */

.finding-title {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  margin-bottom: var(--s-2);
}
.finding-num {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  font-size: var(--t-xs);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  border-radius: 50%;
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--line-strong);
}

/* The 3px edge is the categorical marker: held for a logic mistake, fault for
   a syntax one. Kept deliberately - it is what separates the two groups at a
   glance. Signal inks, so it means the same thing here as everywhere else. */
.finding-logic {
  border-left: 3px solid var(--sig-held);
}
.finding-logic .finding-num {
  color: var(--ink);
  background: var(--sig-held-wash);
  border-color: var(--sig-held-line);
}
.finding-syntax {
  border-left: 3px solid var(--sig-fault);
}
.finding-syntax .finding-num {
  color: var(--ink);
  background: var(--sunken);
  border-color: var(--line);
}

/* The evidence/headline callout strip matching screenshot design */
.finding-lead {
  display: block;
  padding: 10px 14px;
  margin: var(--s-2) 0 var(--s-3);
  border-radius: 6px;
  font-size: 13.5px;
  line-height: 1.5;
}
.finding-logic .finding-lead {
  background: var(--sig-held-wash);
  border: 1px solid var(--sig-held-line);
  color: var(--ink);
}
.finding-logic .finding-lead-label {
  color: var(--sig-held);
  font-weight: 700;
}
.finding-logic .finding-lead-value {
  color: var(--ink);
  font-weight: 500;
}
.finding-syntax .finding-lead {
  background: var(--sunken);
  border: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--mono);
}
.finding-syntax .finding-lead-label {
  color: var(--ink-3);
  font-weight: 600;
  font-family: var(--sans);
}
.finding-syntax .finding-lead-value,
.finding-lead-value.is-code {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
}

/* ── THE FIX ─────────────────────────────────────────────────────
   Last card in the report. The corrected line stays behind a click:
   the student reads what is wrong before the answer is on screen,
   which is the one piece of the ladder worth keeping here. */
.fix-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-6);
  box-shadow: var(--shadow-sm);
}
.fix-card-head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.fix-card-head .report-section-title { margin-bottom: 0; }
.fix-line-tag {
  font-family: var(--mono);
  font-size: var(--t-xs);
  color: var(--brand);
  background: var(--brand-wash);
  border: 1px solid var(--brand-line);
  border-radius: var(--r-sm);
  padding: 2px var(--s-2);
}
.fix-line-tag:empty { display: none; }

#btnRevealFix { margin-top: var(--s-4); }

.fix-body { margin-top: var(--s-4); }
.fix-code {
  margin: 0;
  font-family: var(--mono);
  font-size: var(--t-sm);
  line-height: 1.7;
  color: var(--ink);
  background: var(--sig-clear-wash);
  border: 1px solid var(--sig-clear-line);
  border-radius: var(--r);
  padding: var(--s-4);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.fix-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-top: var(--s-3);
}
.chat-code-block {
  margin: 8px 0;
  padding: 8px;
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  font: 12px/1.5 var(--font-mono);
}

.chat-inline-code {
  padding: 1px 4px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--bg);
  font: 12px/1.4 var(--font-mono);
}

/* ── PROBLEM STUDIO ──────────────────────────────────────────────
   A problem opens as a brief (left) and the editor with a Checks panel
   (right). Tokens only. Pass/fail colours appear on example results
   alone: they describe the student's code, never the chrome. */
.studio-brief { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }
.studio-head {
  padding: var(--s-5) var(--s-6) var(--s-4);
  background: var(--raised);
  border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: var(--s-3);
}
.studio-head-row { display: flex; align-items: center; gap: var(--s-3); }
.studio-num {
  font: 600 var(--t-xs)/1 var(--mono);
  color: var(--tag-indigo-fg); background: var(--tag-indigo-bg);
  padding: var(--s-1) var(--s-2); border-radius: var(--r-sm);
}
.studio-num:empty { display: none; }
.studio-title { flex: 1; min-width: 0; font: 700 var(--t-lg)/1.25 var(--font); color: var(--ink); }
.studio-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.studio-body { padding: var(--s-6); color: var(--ink); font-size: var(--t-base); line-height: 1.6; overflow-y: auto; }
.studio-prose p + p { margin-top: var(--s-3); }
.studio-prose { margin-bottom: var(--s-6); }
.studio-example {
  margin-top: var(--s-4); padding: var(--s-4) var(--s-5);
  background: var(--sunken); border-radius: var(--r);
}
.studio-example-title, .studio-subhead {
  font: 700 var(--t-sm)/1.3 var(--font); color: var(--ink-2);
  text-transform: uppercase; letter-spacing: .06em; margin-bottom: var(--s-2);
}
.studio-subhead { margin-top: var(--s-6); display: flex; align-items: center; gap: var(--s-2); }
.studio-io { display: grid; grid-template-columns: max-content 1fr; gap: var(--s-1) var(--s-4); font-size: var(--t-sm); }
.studio-io dt { color: var(--ink-3); font-weight: 600; }
.studio-io dd { min-width: 0; overflow-wrap: anywhere; }
.studio-io code, .studio-error, .studio-printed pre { font-family: var(--mono); font-size: var(--t-sm); color: var(--ink); }
.studio-constraints { padding-left: var(--s-5); font-size: var(--t-sm); color: var(--ink-2); }
.studio-constraints li + li { margin-top: var(--s-1); }

.studio-checks { margin-top: var(--s-4); border-radius: var(--r-lg); border: 1px solid var(--line); background: var(--surface); }
.studio-checks-bar {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--line); background: var(--raised);
}
.studio-seg { display: inline-flex; padding: 3px; gap: 2px; background: var(--sunken); border-radius: var(--r-pill); }
.studio-seg button {
  border: 0; background: transparent; color: var(--ink-3); cursor: pointer;
  font: 600 var(--t-sm)/1 var(--font); padding: var(--s-2) var(--s-4); border-radius: var(--r-pill);
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}
.studio-seg button[aria-selected="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.studio-summary { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--t-sm); font-weight: 600; color: var(--ink-3); }
.studio-summary[data-state="pass"] { color: var(--sig-clear); }
.studio-summary[data-state="fail"] { color: var(--sig-fault); }
.studio-checks-body { padding: var(--s-4); max-height: 340px; overflow-y: auto; display: flex; flex-direction: column; gap: var(--s-3); }
.studio-case { padding: var(--s-3) var(--s-4); border-radius: var(--r); background: var(--sunken); border: 1px solid transparent; }
.studio-case.is-pass { background: var(--sig-clear-wash); border-color: var(--sig-clear-line); }
.studio-case.is-fail { background: var(--sig-fault-wash); border-color: var(--sig-fault-line); }
.studio-case-name { display: flex; align-items: center; gap: var(--s-2); font-weight: 700; font-size: var(--t-sm); color: var(--ink); margin-bottom: var(--s-2); }
.studio-verdict { font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .06em; }
.is-pass .studio-verdict { color: var(--sig-clear); }
.is-fail .studio-verdict { color: var(--sig-fault); }
.studio-error { white-space: pre-wrap; margin: 0; color: var(--sig-fault); }
.studio-note { font-size: var(--t-sm); color: var(--ink-3); }
.studio-printed summary { cursor: pointer; font-size: var(--t-sm); color: var(--ink-2); }
.studio-printed pre { white-space: pre-wrap; margin-top: var(--s-2); padding: var(--s-3); background: var(--sunken); border-radius: var(--r-sm); }
.studio-review { padding-top: var(--s-2); border-top: 1px solid var(--line); font-size: var(--t-sm); color: var(--ink); }
.studio-review .studio-subhead { margin-top: var(--s-2); }
.studio-advisory { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-3); }
.studio-complexity { display: flex; gap: var(--s-5); margin-bottom: var(--s-2); color: var(--ink-2); }
.studio-complexity strong { font-family: var(--mono); color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .studio-seg button { transition: none; }
}
