/* Trace viewer styles — warm sepia (dark) / warm cream (light) palette,
   terracotta accent, JetBrains Mono. Three-column console layout. */

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

:root {
  /* Dark theme — warm sepia */
  --bg-primary:   #1a1612;
  --bg-secondary: #252119;
  --bg-tertiary:  #332d23;
  --text-primary:   #e8e3d8;
  --text-secondary: #aca595;
  --accent-primary:   #c17d5a;
  --accent-secondary: #a66b4f;
  --border-color: #3d3728;
  --success: #10b981;
  --warning: #f59e0b;
  --danger:  #ef4444;
  --transition: all 0.2s ease;

  --tag-bg: rgba(193, 125, 90, 0.14);
  --tag-border: rgba(193, 125, 90, 0.4);
  --tag-color: #d99a7c;

  --session-0: #c17d5a;
  --session-1: #a98a4b;
  --session-2: #8a9b5c;
  --session-3: #9b6b85;
  --session-4: #b66a4a;

  --thinking: #b39a6a;
  --thinking-bg: rgba(179, 154, 106, 0.10);
}

[data-theme="light"] {
  /* Light theme — warm cream */
  --bg-primary:   #faf8f3;
  --bg-secondary: #f3f0e8;
  --bg-tertiary:  #e8e4d9;
  --text-primary:   #2d2a23;
  --text-secondary: #6b655a;
  --border-color: #d9d4c8;
  --accent-primary:   #a66b4f;
  --accent-secondary: #8d5d45;

  --tag-bg: transparent;
  --tag-border: var(--accent-primary);
  --tag-color: var(--accent-primary);

  --session-0: #a66b4f;
  --session-1: #8a7240;
  --session-2: #6f7d45;
  --session-3: #80526a;
  --session-4: #97553a;

  --thinking: #8a7240;
  --thinking-bg: rgba(138, 114, 64, 0.08);
}

html, body {
  font-family: 'JetBrains Mono', 'SF Mono', Monaco, Inconsolata, 'Fira Mono',
               'Source Code Pro', monospace;
  font-size: 14.5px;
  line-height: 1.6;
  background-color: var(--bg-primary);
  color: var(--text-primary);
  transition: background-color 0.2s ease, color 0.2s ease;
}

a {
  color: var(--accent-primary);
  text-decoration: none;
  text-underline-offset: 2px;
}
a:hover { text-decoration: underline; color: var(--accent-secondary); }
code { font: inherit; background: var(--bg-tertiary); padding: 1px 5px; border-radius: 3px; font-size: 0.9em; }
.muted { color: var(--text-secondary); }

/* ---------- Custom tooltip ---------------------------------------- */
/* Floating panel rendered at the body level by assets/tooltip.js so it
   ALWAYS escapes ancestor `overflow: hidden / auto` clipping contexts
   (the sticky scrollable left rail on the run page would otherwise
   crop a pseudo-element tooltip). Triggered by data-tip="…" anywhere. */
.tt-pop {
  position: fixed;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: 'JetBrains Mono', 'SF Mono', monospace;
  font-size: 0.72rem;
  font-weight: 500;
  font-style: normal;
  line-height: 1.45;
  letter-spacing: 0;
  text-transform: none;
  text-align: left;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: 0.4rem;
  box-shadow: 0 10px 28px rgba(20, 16, 11, 0.32);
  max-width: 280px;
  width: max-content;
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
  transform: translateY(3px);
  transition: opacity 0.12s ease, transform 0.12s ease;
  --tt-arrow-x: 50%;
}
.tt-pop.tt-show {
  opacity: 1;
  transform: translateY(0);
}
.tt-pop::before {
  content: '';
  position: absolute;
  left: var(--tt-arrow-x);
  width: 8px;
  height: 8px;
  background: var(--bg-tertiary);
  transform: translateX(-50%) rotate(45deg);
}
.tt-pop[data-arrow-pos="below"]::before {
  bottom: -5px;
  border-right: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
}
.tt-pop[data-arrow-pos="above"]::before {
  top: -5px;
  border-left: 1px solid var(--border-color);
  border-top: 1px solid var(--border-color);
}
/* Anything carrying data-tip stays hoverable; the cursor change is
   element-specific (cost-missing / no-eval-marker etc. set their own). */

/* Missing-cost em-dash. Dotted underline + help cursor tell the reader
   it's worth hovering; the data-tip attribute supplies the message. */
.cost-missing {
  cursor: help;
  text-decoration: underline dotted color-mix(in srgb, var(--text-secondary) 60%, transparent);
  text-underline-offset: 3px;
}

/* "not evaluated" marker — agent didn't produce a final_model so the
   eval harness never ran. Different vocabulary from cost-missing because
   it represents a *run outcome* (the agent didn't finish the work)
   rather than missing telemetry. Quiet but legible. */
.no-eval-marker {
  cursor: help;
  display: inline-block;
  font-size: 0.74rem;
  font-style: italic;
  color: var(--text-secondary);
  background: var(--bg-tertiary);
  border: 1px dashed color-mix(in srgb, var(--text-secondary) 35%, transparent);
  border-radius: 3px;
  padding: 0.05rem 0.4rem;
  white-space: nowrap;
}

/* Empty big-score state — dim the placeholder em-dash so it doesn't
   shout "0% accuracy". The "not evaluated" chip below carries the
   actual meaning. */
.score-big-empty {
  color: var(--text-secondary);
  opacity: 0.4;
}
.score-big-empty::after { display: none; }   /* drop the trailing "%" */
.hidden { display: none !important; }
.mono { font-family: inherit; }

/* ---------- Navbar -------------------------------------------------- */
.topbar {
  background-color: var(--bg-primary);
  border-bottom: 1px solid var(--border-color);
  padding: 0;
  position: sticky;
  top: 0;
  z-index: 100;
}
.topbar-inner {
  max-width: 100%;
  padding: 0 1.5rem;
  display: flex;
  align-items: stretch;
  gap: 1.5rem;
  min-height: 48px;
}
.topbar .logo {
  display: flex;
  align-items: center;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.02em;
  white-space: nowrap;
  text-decoration: none;
}
.topbar .logo:hover { text-decoration: none; }
.topbar .logo-sub {
  display: flex;
  align-items: center;
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 0.92rem;
  letter-spacing: 0;
  margin-left: 0.25rem;
  text-decoration: none;
  transition: color 0.15s ease;
}
.topbar .logo-sub:hover { color: var(--accent-primary); text-decoration: none; }
.topbar .logo-accent {
  background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.topbar .back {
  font-size: 0.95rem;
  color: var(--text-secondary);
  display: flex;
  align-items: center;
}
.topbar .back:hover { color: var(--accent-primary); text-decoration: none; }
.breadcrumb {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  font-size: 0.8rem;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.breadcrumb a { color: var(--text-secondary); }
.breadcrumb a:hover { color: var(--accent-primary); }
.breadcrumb .sep { opacity: 0.5; }
.breadcrumb .current { color: var(--text-primary); }
.topbar-meta {
  color: var(--text-secondary);
  font-size: 0.72rem;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.8rem;
}

/* Section tabs — pinned to the top of the center column so they read as
   section-level navigation. Underline + icon style: stronger active
   indicator (terracotta bar) than the previous folder-fill approach, and
   reinforces "terracotta accent = currently-selected" across the site
   (mirrors the index page's row-hover left-edge). */
.tab-nav {
  display: flex;
  gap: 0.15rem;
  margin-bottom: 1.1rem;
  border-bottom: 1px solid var(--border-color);
  padding: 0 0.15rem;
  align-items: stretch;
  /* Pin to the top under the navbar so a user 800px deep in a long
     trace can still switch to Judge or Workspace without scrolling
     back. Background needs to be solid so trace content scrolling
     behind doesn't show through. z-index sits below the topbar's 100. */
  position: sticky;
  top: 48px;
  background: var(--bg-primary);
  z-index: 30;
}
.tab-btn {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-secondary);
  padding: 0.65rem 0.95rem 0.7rem;
  font: inherit;
  font-size: 0.86rem;
  font-weight: 500;
  cursor: pointer;
  position: relative;
  bottom: -1px;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.tab-btn svg {
  color: currentColor;
  opacity: 0.7;
  transition: opacity 0.15s ease;
  flex: none;
}
.tab-btn:hover {
  color: var(--text-primary);
}
.tab-btn:hover svg { opacity: 0.95; }
.tab-btn.active {
  color: var(--accent-primary);
  font-weight: 600;
  border-bottom-color: var(--accent-primary);
}
.tab-btn.active svg { opacity: 1; }

.theme-toggle {
  background: none;
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  padding: 0.3rem;
  border-radius: 0.375rem;
  cursor: pointer;
  transition: var(--transition);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* The topbar uses align-items: stretch so children fill its height. The
     theme toggle should hug its icon instead — anchor it to its own height. */
  align-self: center;
  height: 28px;
  width: 28px;
  /* Pin the toggle to the right of the navbar regardless of what's
     between it and the logo. On the run page .topbar-meta already has
     margin-left: auto and consumes the slack first; this line is a no-op
     there but ensures the landing page (no meta) still right-aligns. */
  margin-left: auto;
}
.theme-toggle:hover { background-color: var(--bg-tertiary); }
.theme-icon { width: 16px; height: 16px; display: none; }
.theme-icon-sun { display: block; }
[data-theme="light"] .theme-icon-sun { display: none; }
[data-theme="light"] .theme-icon-moon { display: block; }

/* ---------- Page-level loading shield ------------------------------- */
/* Covers the empty page scaffolding while load() fetches + renders.
   Same background as the page so the reveal is a clean fade-out, not a
   flashing card. Sits above everything (z-index 1000) and ignores
   pointer events when hidden so it can't intercept clicks after fading. */
.page-loading {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background-color: var(--bg-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.28s ease, visibility 0s linear 0s;
}
.page-loading.hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.28s ease, visibility 0s linear 0.28s;
}
.page-loading-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
}
.page-loading-spinner {
  width: 32px;
  height: 32px;
  border: 2.5px solid var(--bg-tertiary);
  border-top-color: var(--accent-primary);
  border-radius: 50%;
  animation: page-loading-spin 0.85s linear infinite;
}
.page-loading-label {
  font-size: 0.78rem;
  color: var(--text-secondary);
  letter-spacing: 0.04em;
  text-transform: lowercase;
}
@keyframes page-loading-spin { to { transform: rotate(360deg); } }
/* Honor reduced-motion preferences — show a pulsing dot instead of spinning. */
@media (prefers-reduced-motion: reduce) {
  .page-loading-spinner {
    border-color: var(--accent-primary);
    animation: page-loading-pulse 1.6s ease-in-out infinite;
  }
  @keyframes page-loading-pulse {
    0%, 100% { opacity: 0.35; }
    50%      { opacity: 1; }
  }
}

/* ---------- Layout -------------------------------------------------- */
.layout {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr) 310px;
  gap: 1.5rem;
  padding: 1.5rem;
  max-width: 100%;
  align-items: start;
}
.rail {
  position: sticky;
  top: 70px;
  max-height: calc(100vh - 88px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.rail::-webkit-scrollbar { width: 4px; }
.content { min-width: 0; display: flex; flex-direction: column; gap: 2rem; }

/* ---------- Cards / sections --------------------------------------- */
.card {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 1.2rem 1.25rem;
}
.section { display: none; }
.section.active { display: block; }
/* Each section's header is now just an optional meta row (controls or
   description). The tab strip above acts as the divider, so no heavy
   border on the header — just a little breathing room below it. */
.section-header {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
  margin-bottom: 0.8rem;
}
.section-header:empty { display: none; }
.section-header .section-desc {
  font-size: 0.8rem;
  flex-basis: 100%;
  margin: 0;
  line-height: 1.55;
}
.section-controls {
  margin-left: auto;
  display: flex;
  gap: 0.9rem;
  align-items: center;
  font-size: 0.78rem;
  color: var(--text-secondary);
}
.section-controls label { user-select: none; cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; }
.section-controls input[type="checkbox"] { accent-color: var(--accent-primary); cursor: pointer; }

/* Trace toolbar — a left summary + a right control cluster. The summary
   anchors the toolbar on the left (used to be dead air) and the cluster
   keeps related controls together. */
.trace-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
  padding: 0.5rem 0.85rem;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
}
.trace-toolbar-summary { display: flex; align-items: center; min-width: 0; }
.trace-toolbar-count {
  font-size: 0.78rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.trace-toolbar-controls {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  margin-left: auto;
}
.trace-jump {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: var(--text-secondary);
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.35rem;
  padding: 0.05rem 0.35rem 0.05rem 0.45rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.trace-jump:focus-within {
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 12%, transparent);
}
.trace-jump svg { color: var(--text-secondary); flex: none; opacity: 0.85; }
.trace-jump input[type="number"] {
  width: 4.25rem;
  background: transparent;
  color: var(--text-primary);
  border: none;
  padding: 0.25rem 0;
  font: inherit;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  outline: none;
  -moz-appearance: textfield;
  appearance: textfield;
}
.trace-jump input[type="number"]::-webkit-outer-spin-button,
.trace-jump input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.trace-jump input::placeholder { color: var(--text-secondary); opacity: 0.7; }
.trace-jump input.jump-miss {
  color: var(--session-4);
  animation: jump-miss-shake 0.4s ease;
}
@keyframes jump-miss-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-2px); }
  75% { transform: translateX(2px); }
}
.toggle-label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
}
.toggle-label input[type="checkbox"] { accent-color: var(--accent-primary); cursor: pointer; }

/* Session divider — heavier visual break than the old single-line banner.
   A numbered chip flanked by horizontal rules. Sits on its own bg so it
   visually breaks the timeline thread without it bleeding through. */
.session-divider {
  display: grid;
  grid-template-columns: 1fr auto auto 1fr;
  align-items: center;
  gap: 0.9rem;
  margin: 1.5rem 0 1rem;
  position: relative;
  z-index: 2;
}
.session-rule {
  height: 1px;
  background: color-mix(in srgb, var(--accent-primary) 35%, var(--border-color));
}
.session-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.35rem 0.85rem;
  background: linear-gradient(135deg, var(--bg-tertiary), var(--bg-secondary));
  border: 1px solid var(--border-color);
  border-radius: 999px;
}
.session-chip-n {
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--accent-primary);
  letter-spacing: -0.005em;
}
.session-chip-total {
  font-size: 0.7rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.session-chip-meta {
  display: inline-flex;
  gap: 0.45rem;
  align-items: baseline;
  font-size: 0.72rem;
  color: var(--text-primary);
}
.session-divider.session-0 .session-rule { background: color-mix(in srgb, var(--session-0) 35%, var(--border-color)); }
.session-divider.session-1 .session-rule { background: color-mix(in srgb, var(--session-1) 35%, var(--border-color)); }
.session-divider.session-2 .session-rule { background: color-mix(in srgb, var(--session-2) 35%, var(--border-color)); }
.session-divider.session-3 .session-rule { background: color-mix(in srgb, var(--session-3) 35%, var(--border-color)); }
.session-divider.session-4 .session-rule { background: color-mix(in srgb, var(--session-4) 35%, var(--border-color)); }

/* Summary footer — utilities at the bottom of the left rail card. The
   run-id is no longer a top-level prominent element; it's tucked here
   beside the Download button. */
.summary-footer {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin-top: 0.4rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border-color);
}
.summary-footer .btn { width: 100%; justify-content: center; }
.summary-footer .run-id-block { margin: 0; }

/* ---------- Left rail: back link, summary card, run-id ------------- */
.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
  color: var(--text-secondary);
  padding: 0.4rem 0.5rem;
  border-radius: 0.375rem;
  width: max-content;
  transition: var(--transition);
}
.back-link:hover {
  color: var(--accent-primary);
  background-color: var(--bg-tertiary);
  text-decoration: none;
}

.summary-card { padding: 1.3rem 1.3rem 1.1rem; }
.summary-label {
  display: inline-block;
  font-size: 0.65rem;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  margin-bottom: 0.4rem;
}
.summary-title {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.25;
  letter-spacing: -0.01em;
  word-break: break-word;
  margin-bottom: 0.35rem;
}
.summary-sub {
  font-size: 0.8rem;
  color: var(--text-secondary);
  margin-bottom: 1rem;
  word-break: break-word;
}
.summary-score {
  margin: 0.6rem 0 0.9rem;
  padding: 0.7rem 0;
  border-top: 1px solid var(--border-color);
  border-bottom: 1px solid var(--border-color);
}
.score-big {
  font-size: 2.7rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--accent-primary);
}
.score-big::after {
  content: '%';
  font-size: 1.1rem;
  margin-left: 0.15rem;
  color: var(--text-secondary);
  font-weight: 500;
}
/* Mini bar below the score — absolute 0–100% scale so the magnitude has
   visual anchor. 14% reads very differently from 70% at a glance. */
.score-bar {
  height: 4px;
  background: var(--bg-tertiary);
  border-radius: 2px;
  overflow: hidden;
  margin: 0.55rem 0 0.3rem;
}
.score-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
  border-radius: 2px;
  transition: width 0.4s ease;
}
.score-sub {
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-top: 0.1rem;
  font-variant-numeric: tabular-nums;
}
/* Run ID — muted by default since it's only needed to copy. The whole
   row is a single subtle line with the path on the left and a small copy
   button on the right. It brightens on hover so users discover the
   interaction; pressing it triggers a brief border-flash + icon swap. */
.run-id-block {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 1rem;
  padding: 0.25rem 0.4rem 0.25rem 0.55rem;
  background: transparent;
  border: 1px dashed transparent;
  border-radius: 0.375rem;
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease;
}
.run-id-block code {
  background: transparent;
  padding: 0;
  font-size: 0.66rem;
  color: var(--text-secondary);
  word-break: break-all;
  line-height: 1.4;
  flex: 1;
  min-width: 0;
}
.run-id-block:hover {
  background-color: var(--bg-tertiary);
  border-color: var(--border-color);
}
.run-id-block:hover code { color: var(--text-primary); }

.copy-btn {
  position: relative;
  flex: none;
  background: transparent;
  border: none;
  color: var(--text-secondary);
  padding: 0.2rem;
  border-radius: 0.25rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  transition: color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}
.copy-btn:hover { color: var(--accent-primary); background: var(--bg-secondary); }
.copy-btn:active { transform: scale(0.92); }
.copy-btn .icon-copy,
.copy-btn .icon-check {
  position: absolute;
  inset: 0;
  margin: auto;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.copy-btn .icon-check {
  opacity: 0;
  transform: scale(0.4);
  color: var(--success);
}

/* "copied" toast — hidden until the .copied class is added, then fades up. */
.copy-feedback {
  position: absolute;
  right: 0.3rem;
  top: -1.4rem;
  background: var(--accent-primary);
  color: var(--bg-primary);
  font-size: 0.62rem;
  font-weight: 700;
  padding: 0.12rem 0.4rem;
  border-radius: 3px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}

/* "Copied" state — fires once on press. The CSS animation handles the
   border pulse; the JS removes .copied after ~1.3s. */
.run-id-block.copied {
  animation: copy-flash 0.9s ease;
  border-color: var(--accent-primary);
  background-color: var(--bg-tertiary);
}
.run-id-block.copied .icon-copy { opacity: 0; transform: scale(0.6); }
.run-id-block.copied .icon-check { opacity: 1; transform: scale(1); }
.run-id-block.copied .copy-feedback {
  opacity: 1;
  transform: translateY(0);
  animation: copy-toast 1.2s ease both;
}

@keyframes copy-flash {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-primary) 40%, transparent); }
  60%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent-primary) 0%,  transparent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@keyframes copy-toast {
  0%   { opacity: 0; transform: translateY(6px); }
  15%  { opacity: 1; transform: translateY(0); }
  75%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-2px); }
}
/* Two-column grid: label on the left, value right-aligned against the
   card's right edge. Right-aligning the values cleans up the column —
   the eye reads down a single rule of tabular numerals. */
.summary-stats {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.5rem 1.25rem;
  font-size: 0.82rem;
  margin-bottom: 0.6rem;
}
.summary-stats dt {
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.7rem;
  align-self: center;
}
.summary-stats dd {
  color: var(--text-primary);
  margin: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
/* Inline muted suffix inside a summary-stats dd — e.g. "GPT 5.4 via Codex". */
.summary-stats .stat-sub {
  color: var(--text-secondary);
  font-weight: 400;
  font-size: 0.85em;
  letter-spacing: 0.01em;
  margin-left: 0.2rem;
  opacity: 0.85;
}
/* Per-theme accuracy — collapsible. Only HealthBench-style benchmarks
   emit by_theme; closed by default keeps the rail compact for everyone
   else. The summary row stays a single line and the bars only mount
   when the user expands it. */
.summary-themes {
  margin: 0.4rem 0 1rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border-color);
}
.summary-disclosure {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  list-style: none;
  padding: 0.15rem 0;
}
.summary-disclosure::-webkit-details-marker { display: none; }
.summary-disclosure::before {
  content: '▸';
  display: inline-block;
  font-size: 0.7rem;
  color: var(--accent-primary);
  transition: transform 0.2s ease;
  width: 0.7rem;
}
.summary-themes[open] .summary-disclosure::before { transform: rotate(90deg); }
.summary-disclosure .summary-label { margin-bottom: 0; }
.summary-disclosure-meta {
  margin-left: auto;
  font-size: 0.66rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.summary-themes-body {
  padding-top: 0.55rem;
}
.summary-themes-body .theme-row {
  display: grid;
  grid-template-columns: 1fr max-content;
  align-items: center;
  gap: 0.5rem;
  padding: 0.2rem 0;
}
.summary-themes-body .theme-name {
  font-size: 0.74rem;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.summary-themes-body .theme-pct {
  font-size: 0.7rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.summary-themes-body .theme-bar {
  grid-column: 1 / -1;
  height: 4px;
  background-color: var(--bg-tertiary);
  border-radius: 2px;
  overflow: hidden;
}
.summary-themes-body .theme-bar > div {
  height: 100%;
  background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
}

.summary-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.8rem;
  border-radius: 0.375rem;
  font: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: var(--transition);
  border: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-primary);
}
.btn:hover { background-color: var(--bg-tertiary); border-color: var(--accent-primary); text-decoration: none; }
.btn-primary {
  background-color: var(--accent-primary);
  color: var(--bg-primary);
  border-color: var(--accent-primary);
}
.btn-primary:hover { background-color: var(--accent-secondary); border-color: var(--accent-secondary); color: var(--bg-primary); }

/* ---------- Section nav (left rail) -------------------------------- */
.section-nav {
  display: flex;
  flex-direction: column;
  border-left: 1px solid var(--border-color);
  padding-left: 0.6rem;
  gap: 0.05rem;
}
.section-nav-link {
  font-size: 0.75rem;
  padding: 0.35rem 0.5rem;
  border-radius: 0.25rem;
  color: var(--text-secondary);
  position: relative;
}
.section-nav-link:hover { color: var(--text-primary); background-color: var(--bg-tertiary); text-decoration: none; }
.section-nav-link.active {
  color: var(--accent-primary);
  font-weight: 600;
}
.section-nav-link.active::before {
  content: '';
  position: absolute;
  left: -0.6rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 60%;
  background-color: var(--accent-primary);
  border-radius: 1px;
}

/* ---------- Chips -------------------------------------------------- */
.chip {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 600;
  padding: 0.12rem 0.45rem;
  border-radius: 3px;
  color: var(--tag-color);
  background: var(--tag-bg);
  border: 1px solid var(--tag-border);
  vertical-align: middle;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
/* Status chips use the warm session palette (olive / clay / gold) so they
   sit cohesively in the rest of the page instead of looking like neon. */
.chip.good { color: var(--session-2); background: rgba(111, 125, 69, 0.14); border-color: rgba(111, 125, 69, 0.45); }
.chip.bad  { color: var(--session-4); background: rgba(151, 85, 58, 0.14);  border-color: rgba(151, 85, 58, 0.45); }
.chip.warn { color: var(--session-1); background: rgba(168, 138, 75, 0.14); border-color: rgba(168, 138, 75, 0.45); }
[data-theme="light"] .chip.good { color: #56612e; }
[data-theme="light"] .chip.bad  { color: #97553a; }
[data-theme="light"] .chip.warn { color: #7a6224; }
.chip.accent {
  color: var(--accent-primary);
  background: var(--tag-bg);
  border-color: var(--tag-border);
}

/* ===================================================================
   Landing page (run list)
   =================================================================== */

.container {
  max-width: 1380px;
  margin: 0 auto;
  padding: 1.5rem 2rem 4rem;
}

/* ---------- Page hero — title + corpus-stat strip, then a
   (benchmark × base-model) matrix that doubles as primary navigation.
   The matrix replaces the old marketing paragraph and orients
   visitors to the corpus shape in one glance. */
.page-head {
  border-bottom: 1px solid var(--border-color);
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--bg-secondary) 55%, var(--bg-primary)),
    var(--bg-primary)
  );
}
.page-head-inner {
  padding-top: 1.7rem;
  padding-bottom: 1.6rem;
  /* Title at the top alone. Below: matrix (left) + vertical stats
     column (right). The stats fill the formerly-empty right side and
     visually balance the matrix's heatmap weight. */
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}
.page-head h1 {
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.15;
  margin: 0;
  color: var(--text-primary);
}
.hero-body {
  display: grid;
  grid-template-columns: minmax(0, 720px) auto;
  gap: 2.5rem;
  align-items: start;
}
.hero-stats {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  min-width: 140px;
  padding-top: 0.2rem;
}
.stat-tile {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
}
.stat-num {
  font-size: 1.05rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
  letter-spacing: -0.012em;
  line-height: 1;
}
.stat-label {
  font-size: 0.76rem;
  color: var(--text-secondary);
  letter-spacing: 0.01em;
}
.stat-meta {
  font-size: 0.7rem;
  color: var(--text-secondary);
  opacity: 0.72;
  margin-top: 0.5rem;
  letter-spacing: 0.01em;
}
@media (max-width: 880px) {
  .page-head h1 { font-size: 1.4rem; }
  .hero-body {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .hero-stats {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 1.2rem;
  }
}

/* ---------- Matrix --------------------------------------------------- */
/* Compact grid: 1 label column on the left + N base-model columns.
   Each cell shows run count + best accuracy. Shade is normalized
   per-row so cells in the same row can be compared (different benchmarks
   have different accuracy ranges). Cells are buttons; clicking sets
   the (benchmark, base-model) filter pair. */
.matrix-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  /* Cap the matrix so cells stay near-square instead of sprawling
     across the full container — at 1380px the cells became 11:1 bars,
     which read as four side-by-side bar charts rather than a heatmap. */
  max-width: 720px;
}
.matrix-grid {
  display: grid;
  gap: 2px;
  /* grid-template-columns set inline */
}
.matrix-corner { /* top-left blank cell */ }
.matrix-colhead {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: none;
  letter-spacing: 0.005em;
  padding: 0 0.5rem 0.4rem;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.matrix-rowhead {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--text-primary);
  padding: 0 0.85rem 0 0;
  text-align: right;
  align-self: center;
  white-space: nowrap;
  letter-spacing: -0.005em;
}
.matrix-cell {
  --cell-intensity: 0;
  appearance: none;
  font: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.35rem 0.4rem;
  min-height: 34px;
  border: 1px solid color-mix(in srgb, var(--border-color) 60%, transparent);
  border-radius: 3px;
  /* Stronger ramp — 52% high end gives terracotta saturation enough to
     read the heatmap; low end stays close to bg-secondary. */
  background: color-mix(in srgb,
                        var(--accent-primary) calc(var(--cell-intensity) * 52%),
                        var(--bg-secondary));
  color: var(--text-primary);
  transition: transform 0.12s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  position: relative;
}
.matrix-cell:hover:not(:disabled) {
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 1px var(--accent-primary), 0 6px 16px rgba(20, 16, 11, 0.12);
  z-index: 1;
}
.matrix-cell:focus-visible {
  outline: none;
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 35%, transparent);
}
.matrix-cell:active:not(:disabled) { transform: translateY(1px); }
.matrix-acc {
  font-size: 0.76rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
  line-height: 1;
  color: var(--text-primary);
}
.matrix-cell-empty {
  cursor: default;
  background: transparent;
  border-style: dashed;
  border-color: color-mix(in srgb, var(--border-color) 60%, transparent);
}
.matrix-empty {
  color: var(--text-secondary);
  opacity: 0.5;
  font-size: 0.9rem;
}

.matrix-legend {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.68rem;
  color: var(--text-secondary);
  padding: 0.1rem 0.1rem 0;
  align-self: flex-end;
}
.legend-label { white-space: nowrap; }
.legend-label-right { letter-spacing: 0.02em; }
.legend-scale {
  display: inline-flex;
  gap: 2px;
}
.legend-step {
  --cell-intensity: 0;
  width: 14px;
  height: 10px;
  border-radius: 2px;
  border: 1px solid color-mix(in srgb, var(--border-color) 60%, transparent);
  background: color-mix(in srgb,
                        var(--accent-primary) calc(var(--cell-intensity) * 52%),
                        var(--bg-secondary));
}

@media (max-width: 760px) {
  .matrix-colhead { font-size: 0.64rem; }
  .matrix-rowhead { font-size: 0.72rem; padding-right: 0.4rem; }
  .matrix-cell { min-height: 24px; padding: 0.25rem 0.2rem; }
  .matrix-acc { font-size: 0.68rem; }
}

/* ---------- Filter dock ---------------------------------------------- */
/* Chips lead, search trails. Filters are the primary action for this
   audience; search is the fallback for when you know a substring. */
.filter-dock {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.4rem 0 0.6rem;
  flex-wrap: wrap;
}
.filter-search {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  padding: 0 0.7rem;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
  margin-left: auto;
  min-width: 200px;
  max-width: 260px;
  flex: 0 1 240px;
}
.filter-search:focus-within {
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 12%, transparent);
}
.filter-search .filter-icon { color: var(--text-secondary); flex: none; opacity: 0.85; }
.filter-search input[type="search"] {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.8rem;
  padding: 0.48rem 0;
  min-width: 0;
}
.filter-search input::placeholder { color: var(--text-secondary); opacity: 0.7; }

.filter-group {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

/* When a filter is engaged, give its trigger a terracotta tint so the
   user can see at a glance which filters are active. */
.cs-active .cs-trigger {
  border-color: color-mix(in srgb, var(--accent-primary) 55%, var(--border-color));
  background-color: color-mix(in srgb, var(--accent-primary) 8%, var(--bg-secondary));
  color: var(--accent-primary);
}
.cs-active .cs-caret { color: var(--accent-primary); }

/* View controls — group + sort + result count + clear. Sits between
   the filter dock and the run table. */
.view-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.1rem 0 0.9rem;
  flex-wrap: wrap;
}
.view-controls-left {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.view-controls-right {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  font-size: 0.78rem;
}

/* ---------- Custom dropdown (built on top of <select>) -------------- */
/* Wraps a native <select> with a styled trigger button + popover menu.
   The native control is kept (visually hidden but keyboard-focusable)
   so existing change listeners and form behavior still work. */
.cs {
  position: relative;
  display: inline-block;
}
.cs-native {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
  /* Keep focusable for keyboard users falling back from the custom UI. */
}
.cs-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  background-color: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  padding: 0.5rem 0.7rem 0.5rem 0.8rem;
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
  white-space: nowrap;
}
.cs-trigger:hover { border-color: var(--accent-primary); }
.cs-open .cs-trigger {
  border-color: var(--accent-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 12%, transparent);
}
.cs-caret {
  color: var(--text-secondary);
  flex: none;
  transition: transform 0.18s ease;
}
.cs-open .cs-caret { transform: rotate(180deg); color: var(--accent-primary); }

.cs-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 100%;
  max-width: 22rem;
  max-height: 320px;
  overflow-y: auto;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  box-shadow: 0 12px 28px rgba(20, 16, 11, 0.18);
  list-style: none;
  margin: 0;
  padding: 0.25rem 0;
  z-index: 50;
  animation: cs-menu-open 0.14s ease;
}
@keyframes cs-menu-open {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}
.cs-option {
  padding: 0.4rem 0.85rem;
  font-size: 0.82rem;
  color: var(--text-primary);
  cursor: pointer;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
  border-left: 2px solid transparent;
  transition: background-color 0.1s ease, color 0.1s ease;
}
.cs-option:hover,
.cs-option.focused {
  background-color: var(--bg-tertiary);
}
.cs-option.active {
  color: var(--accent-primary);
  font-weight: 600;
  border-left-color: var(--accent-primary);
}

/* Result count + clear-filters link live in .view-controls-right. */
.results-count { font-variant-numeric: tabular-nums; }
.link-btn {
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.78rem;
  color: var(--accent-primary);
  cursor: pointer;
}
.link-btn:hover { color: var(--accent-secondary); text-decoration: underline; }

/* Empty/loading state */
.empty-state {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--text-secondary);
  font-size: 0.9rem;
}
.empty-state .btn { margin-top: 0.8rem; }

/* ---------- Run table ------------------------------------------------ */
.exp-group { margin-bottom: 1.7rem; }
.exp-group .exp-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.1rem 0.25rem 0.5rem;
  border-bottom: 1px solid var(--border-color);
  margin-bottom: 0;
  flex-wrap: wrap;
}
.exp-head-title {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.exp-head-meta {
  font-size: 0.72rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.005em;
}
.exp-group .exp-name {
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.exp-name-sep {
  color: var(--text-secondary);
  opacity: 0.6;
  font-weight: 400;
}
.exp-name-model {
  font-weight: 500;
  color: var(--text-secondary);
}

.runtable {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  /* Don't clip — tooltips need to escape the table edges. Rounded
     corners are applied to the corner cells instead. */
  margin-top: 0.4rem;
}
.runtable thead th {
  background-color: color-mix(in srgb, var(--bg-secondary) 70%, var(--bg-tertiary));
}
.runtable thead th:first-child { border-top-left-radius: 0.5rem; }
.runtable thead th:last-child  { border-top-right-radius: 0.5rem; }
.runtable tbody tr:last-child td:first-child { border-bottom-left-radius: 0.5rem; }
.runtable tbody tr:last-child td:last-child  { border-bottom-right-radius: 0.5rem; }
.runtable th {
  font-weight: 600;
  color: var(--text-secondary);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  white-space: nowrap;
  text-align: left;
  padding: 0.5rem 0.85rem;
  border-bottom: 1px solid var(--border-color);
}
.runtable td {
  padding: 0.55rem 0.85rem;
  font-size: 0.82rem;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-color);
  position: relative;
  vertical-align: middle;
}
.runtable tr:last-child td { border-bottom: none; }

/* Hover/focus state — uses bg-tertiary so it doesn't collide with the
   thead bg (the old hover state made hovered rows visually merge with
   the header). Adds a thin terracotta left-edge accent for at-a-glance. */
.runtable tbody tr {
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.runtable tbody tr:hover,
.runtable tbody tr:focus-visible {
  background-color: var(--bg-tertiary);
  outline: none;
}
.runtable tbody tr:hover td:first-child::before,
.runtable tbody tr:focus-visible td:first-child::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--accent-primary);
}

/* Column widths — declare intent rather than letting browsers guess. */
.runtable .col-task    { width: auto; }
.runtable .col-agent   { width: 1%; min-width: 11rem; }
.runtable .col-acc     { width: 14rem; }
.runtable .col-num     { width: 1%; text-align: right; font-variant-numeric: tabular-nums; }
.runtable .col-verdict { width: 1%; text-align: right; }

/* ---------- Task cell (benchmark / model / seed combined) ------------ */
.task-cell { display: flex; flex-direction: column; gap: 0.15rem; line-height: 1.3; }
.task-primary {
  color: var(--text-primary);
  font-weight: 600;
  font-size: 0.92rem;
  letter-spacing: -0.005em;
}
.task-secondary {
  color: var(--text-secondary);
  font-size: 0.74rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.seed-pill {
  display: inline-block;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 3px;
  padding: 0 0.35rem;
  font-size: 0.65rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* ---------- Agent cell ----------------------------------------------- */
.agent-name {
  color: var(--text-primary);
  font-weight: 500;
}
.agent-harness {
  display: inline-block;
  margin-left: 0.5rem;
  font-size: 0.68rem;
  color: var(--text-secondary);
  letter-spacing: 0.01em;
  opacity: 0.7;
  white-space: nowrap;
}
.agent-harness::before {
  content: '·';
  margin-right: 0.4rem;
  opacity: 0.7;
}
.agent-tag {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent-primary);
  background: var(--tag-bg);
  border: 1px solid var(--tag-border);
  padding: 0 0.35rem;
  border-radius: 3px;
  margin-left: 0.2rem;
  vertical-align: 1px;
  white-space: nowrap;
}

/* ---------- Accuracy cell (inline bar + number) ---------------------- */
.acc-cell {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 0.5rem;
}
.acc-bar {
  height: 5px;
  background: var(--bg-tertiary);
  border-radius: 3px;
  overflow: hidden;
  min-width: 5rem;
}
.acc-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
  border-radius: 3px;
}
.acc-num {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text-primary);
  font-size: 0.85rem;
}
.acc-err {
  color: var(--text-secondary);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
}

/* ---------- Judge column: dots + flag pills -------------------------- */
/* "Scan for problems" pattern: OK is a near-invisible muted dot (you can
   tell it was checked); FLAG is a saturated clay pill with a warning
   glyph + the axis short-label (contam / model). Big visual delta means
   the eye lands on flags from the other side of the table — and the
   label tells you which axis tripped without needing the tooltip. */
.col-verdict { min-width: 9rem; }

/* One combined badge per row collapses the (contamination,
   disallowed_model) judge axes into a single scannable read:
     ok      → subtle olive pill with a check     ("clean")
     flag    → terracotta pill with warning glyph ("flagged: contam, model")
     pending → muted em-dash + label              ("pending")
   The per-axis raw verdict text lives in the data-tip tooltip. */
.vbadge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.18rem 0.55rem 0.18rem 0.5rem;
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: middle;
  line-height: 1;
  border: 1px solid transparent;
  cursor: help;
}
.vbadge svg { flex: none; }
/* Clean and pending recede — only flagged carries the full pill chrome.
   That asymmetry is intentional: the eye scans down the column looking
   for problems, and the cost of false positives (loud clean rows) is
   higher than missed positives. */
.vbadge-ok {
  color: var(--session-2);
  background: transparent;
  border-color: transparent;
  padding: 0;
}
.vbadge-ok svg { width: 14px; height: 14px; opacity: 0.85; }
[data-theme="light"] .vbadge-ok { color: #5a6b3d; }

.vbadge-flag {
  color: var(--session-4);
  background: color-mix(in srgb, var(--session-4) 18%, transparent);
  border-color: color-mix(in srgb, var(--session-4) 55%, transparent);
}
[data-theme="light"] .vbadge-flag {
  color: #8b3f23;
  background: color-mix(in srgb, var(--session-4) 12%, transparent);
}
.vbadge-pending {
  color: var(--text-secondary);
  background: transparent;
  border-color: transparent;
  padding: 0;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  opacity: 0.55;
}
.runtable tbody tr:hover .vbadge-flag {
  background: color-mix(in srgb, var(--session-4) 22%, transparent);
}
.runtable tbody tr:hover .vbadge-ok svg { opacity: 1; }

/* ---------- Trace events ------------------------------------------- */
/* The trace renders as a connected chain: a thin vertical "thread" runs
   the full length of the list, and every event has a small circular node
   sitting on it (like a timeline). The thread is the same line for every
   event, so the visual reads as one continuous chain rather than separate
   cards stacked together. */

#trace {
  display: flex;
  flex-direction: column;
  gap: 0;
  position: relative;
  /* The continuous thread line — drawn once on #trace so it never breaks
     between events. NODE_X (88px) is shared with .event::after below. */
}
#trace::before {
  content: '';
  position: absolute;
  left: 88px;
  top: 0.4rem;
  bottom: 0.4rem;
  width: 2px;
  background: var(--border-color);
  border-radius: 1px;
  z-index: 0;
}

/* Each event is a 2-column row: marker (turn # + meta) | body */
.event {
  position: relative;
  display: grid;
  grid-template-columns: 78px 1fr;
  gap: 1.4rem;            /* gap accommodates the node on the thread */
  padding: 0.95rem 0;
  z-index: 1;             /* sit above the thread line */
}

/* The node — a filled circle on the thread, aligned with the event's first row.
   Color follows the session palette so you can scan sessions at a glance. */
.event::after {
  content: '';
  position: absolute;
  left: 82px;             /* 88px (thread) - 6px (half of 12px node) + 0 */
  top: 1.15rem;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--accent-primary);
  border: 3px solid var(--bg-primary);
  box-shadow: 0 0 0 1px var(--border-color);
  box-sizing: border-box;
  z-index: 2;
}
.event.session-0::after { background: var(--session-0); }
.event.session-1::after { background: var(--session-1); }
.event.session-2::after { background: var(--session-2); }
.event.session-3::after { background: var(--session-3); }
.event.session-4::after { background: var(--session-4); }

/* Hollow node for non-agent events (system / result / standalone user) so
   they read as different from agent turns at a glance. */
.event.role-system::after,
.event.role-end::after,
.event.role-user::after {
  background: var(--bg-primary);
  border-color: var(--accent-primary);
  width: 10px;
  height: 10px;
  top: 1.25rem;
  left: 84px;
  box-shadow: 0 0 0 1px var(--border-color);
}

/* Marker column — all secondary info, muted. The colored node on the
   thread carries the session affiliation, so the marker only needs:
     - turn number (large, the primary affordance)
     - time-of-day (HH:MM:SS — date is on hover tooltip)
     - elapsed since run start (small chip below)
   Clicking the marker copies a permalink to this event. */
.event-marker {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  font-size: 0.7rem;
  color: var(--text-secondary);
  gap: 0.15rem;
  user-select: none;
  padding-top: 0.1rem;
  cursor: pointer;
  transition: opacity 0.15s ease;
}
.event-marker:hover { opacity: 1; }
.event-marker.linked { opacity: 1; }
.event-marker.linked .turn-num { color: var(--accent-primary); }

.turn-num {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-secondary);
  line-height: 1;
  margin-bottom: 0.35rem;
  font-variant-numeric: tabular-nums;
  transition: color 0.15s ease;
}
.turn-num::before {
  content: '#';
  font-size: 0.7rem;
  font-weight: 500;
  color: var(--text-secondary);
  margin-right: 1px;
  vertical-align: 0.15em;
  opacity: 0.7;
}
.event-marker:hover .turn-num { color: var(--accent-primary); }

.turn-role {
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-secondary);
  background: transparent;
  padding: 0;
  margin-bottom: 0.35rem;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ev-time {
  font-size: 0.74rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: help;
}
.ev-sub-tag {
  font-size: 0.58rem;
  margin-top: 0.2rem;
  color: var(--accent-primary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}

/* Permalink-linked flash: brief accent ring on the event when scrolled to. */
.event-flash {
  animation: event-flash 1.4s ease;
}
@keyframes event-flash {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-primary) 35%, transparent); }
  30%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent-primary) 25%, transparent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Event body */
.event-body {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  min-width: 0;
  padding-left: 0.5rem;  /* sit right of the vertical thread */
}

/* Generic block label (icon + uppercase text) used by Output, Todo, etc. */
.block-label {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 0.3rem;
}
.block-label svg { opacity: 0.7; }
.block-label-inline {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Each agent block (text, thought, standalone output) is its own card with
   the same shape & border, so the trace reads as a vertical stack of
   like-sized "speech bubbles" instead of mixed prose / boxed content. The
   tool-call panel keeps its own dark terminal aesthetic. */
.block-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 0.7rem 0.95rem;
  font-size: 0.95rem;
  color: var(--text-primary);
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.65;
}
.agent-text {
  /* The agent's "voice" — most prominent, plain. */
}
.standalone-output {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 0.7rem 0.95rem;
}

/* Thinking — same card shape as agent text, but tinted, italic, and given
   a dashed border so it reads as a thought-balloon outline (ephemeral,
   speculative). The tint + italic + dashes signal "internal monologue"
   instead of the agent's spoken voice. */
.agent-thinking {
  background-color: var(--thinking-bg);
  border-style: dashed;
  border-color: color-mix(in srgb, var(--thinking) 55%, var(--border-color));
  font-size: 0.9rem;
  font-style: italic;
  line-height: 1.6;
  white-space: normal;
}
.agent-thinking summary {
  cursor: pointer;
  color: var(--thinking);
  font-weight: 700;
  font-style: normal;
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}
.agent-thinking summary::-webkit-details-marker { display: none; }
.agent-thinking summary svg { opacity: 0.8; }
.agent-thinking[open] summary { margin-bottom: 0.45rem; }
.agent-thinking .thinking-body {
  white-space: pre-wrap;
  word-break: break-word;
}

/* Tool call card — args + paired output in one connected card */
.tool-call {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  overflow: hidden;
}
.tool-call > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.7rem;
  padding: 0.45rem 0.75rem;
  background: var(--bg-tertiary);
  border-bottom: 1px solid var(--border-color);
  color: var(--text-primary);
}
.tool-call > summary::-webkit-details-marker { display: none; }
.tool-call > summary svg { color: var(--accent-primary); }
.tool-call .tool-name {
  color: var(--accent-primary);
  font-weight: 700;
  letter-spacing: 0.01em;
  font-size: 0.78rem;
}
.tool-id {
  font-size: 0.66rem;
  color: var(--text-secondary);
  margin-left: auto;
  font-weight: 400;
  opacity: 0.75;
}
.tool-exit {
  font-size: 0.66rem;
  color: var(--text-secondary);
  margin-left: 0.4rem;
}
.tool-args {
  background-color: var(--bg-primary);
  padding: 0.6rem 0.85rem;
  font-size: 0.78rem;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text-primary);
}
.tool-args pre { white-space: pre-wrap; word-break: break-word; font: inherit; }
.tool-result {
  border-top: 1px solid var(--border-color);
  background-color: var(--bg-primary);
}
.tool-result-head {
  font-size: 0.65rem;
  color: var(--text-secondary);
  padding: 0.3rem 0.85rem;
  background-color: var(--bg-tertiary);
  border-bottom: 1px solid var(--border-color);
  display: flex;
  gap: 0.7rem;
  align-items: center;
}
.tool-result-label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-secondary);
}
.tool-result-label svg { color: var(--success); opacity: 0.85; }
.tool-result-body {
  font-size: 0.78rem;
  padding: 0.65rem 0.85rem;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 280px;
  overflow: auto;
  color: var(--text-primary);
}
.tool-call.expanded .tool-result-body { max-height: none; }
.tool-result-body.error {
  background-color: rgba(239, 68, 68, 0.07);
  color: var(--danger);
}

/* Plain ".bash-cmd" — used outside tool cards (Edit/Write paths). Subtle
   monospaced tag, not a full terminal. */
.bash-cmd {
  background-color: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 0.8rem;
  padding: 0.45rem 0.7rem;
  border-radius: 0.25rem;
  white-space: pre-wrap;
  word-break: break-word;
}
.bash-cmd::before {
  content: "$ ";
  color: var(--accent-primary);
  font-weight: 700;
}

/* Bash tool calls — render args + output as one connected terminal panel.
   Uses a warm-sepia "terminal" palette in both themes, but the dark theme
   uses a *deeper* warm-black so the panel reads as an inset screen against
   the page's warm-dark body (otherwise the terminal disappears into the bg). */
.tool-bash {
  --term-bg:        #0d0a06;   /* dark mode default: deeper than page bg #1a1612 */
  --term-bg-elev:   #15110a;
  --term-border:    #2e271a;
  --term-fg:        #e8e3d8;
  --term-fg-dim:    #d6c9b5;
  --term-muted:     #8a7d68;
  --term-prompt:    #d4af5a;   /* warm gold prompt */
  --term-accent:    #c17d5a;   /* terracotta tool name (matches site accent) */
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35);
}
[data-theme="light"] .tool-bash {
  /* Light mode: terminal stays dark against the cream page — high
     contrast on its own, no shadow needed. */
  --term-bg:        #1a1612;
  --term-bg-elev:   #221c14;
  --term-border:    #3d3728;
  box-shadow: none;
}
.tool-bash {
  background-color: var(--term-bg) !important;
  border-color: var(--term-border) !important;
}
.tool-bash > summary {
  background-color: var(--term-bg-elev);
  border-bottom-color: var(--term-border);
  color: var(--term-fg);
}
.tool-bash > summary svg { color: var(--term-prompt); }
.tool-bash .tool-name { color: var(--term-accent); }
.tool-bash .tool-id   { color: var(--term-muted); }
.tool-bash .tool-exit { color: var(--term-muted); }
.tool-bash .block-label-inline { color: var(--term-muted); }

.tool-bash .tool-args {
  background-color: var(--term-bg);
  color: var(--term-fg);
  padding: 0.55rem 0.85rem 0.35rem;
  font-size: 0.84rem;
}
.tool-bash .tool-args .bash-cmd {
  background: transparent;
  padding: 0;
  border-radius: 0;
  color: var(--term-fg);
  font-size: inherit;
}
.tool-bash .tool-args .bash-cmd::before {
  content: "$ ";
  color: var(--term-prompt);
  font-weight: 700;
}
.tool-bash .tool-args .muted {
  color: var(--term-muted) !important;
  margin-top: 6px;
  font-size: 0.74rem;
}

.tool-bash .tool-result { border-top: 1px dashed var(--term-border); background: transparent; }
.tool-bash .tool-result-head {
  background-color: transparent;
  color: var(--term-muted);
  border-bottom: none;
  padding: 0.25rem 0.85rem 0.15rem;
  font-size: 0.62rem;
}
.tool-bash .tool-result-label { color: var(--term-muted); }
.tool-bash .tool-result-label svg { color: var(--term-prompt); opacity: 0.8; }
.tool-bash .tool-result-body {
  background-color: var(--term-bg);
  color: var(--term-fg-dim);
  font-size: 0.82rem;
  padding: 0.35rem 0.85rem 0.7rem;
}
.tool-bash .tool-result-body.error {
  background-color: rgba(239, 68, 68, 0.10);
  color: #fca5a5;
}

/* Tight checklist rhythm — also reset white-space here because the
   enclosing tool-args has pre-wrap (which was rendering JS-template
   newlines as visible gaps between todos). */
.todo-list {
  margin: 0;
  padding: 0;
  list-style: none;
  white-space: normal;
}
.todo-item {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  padding: 0.05rem 0;
  font-size: 0.85rem;
  line-height: 1.35;
  white-space: normal;
}
.todo-item.done { text-decoration: line-through; color: var(--text-secondary); opacity: 0.7; }
.todo-item .check { color: var(--accent-primary); flex: none; }

/* Session-init block — the run's opening orientation card. Fact grid:
   small uppercase labels in the left column, values on the right. */
.session-init-block {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 0.85rem 1rem;
}
.session-init-head {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-secondary);
  margin-bottom: 0.55rem;
}
.session-init-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem 1rem;
  font-size: 0.82rem;
  margin: 0;
  align-items: baseline;
}
.session-init-grid dt {
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.66rem;
}
.session-init-grid dd { color: var(--text-primary); margin: 0; }
.session-init-grid code { font-size: 0.78rem; }

/* Session-ended row — quiet, no heavy banner. Meta on top, then the
   agent's closing message as plain prose. */
.result-meta {
  font-size: 0.72rem;
  display: flex;
  gap: 0.85rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}

/* ---------- Metrics ------------------------------------------------ */
.metric-grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.metric-card {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 1rem 1.2rem;
}
.metric-card h4 {
  margin: 0 0 0.7rem;
  font-size: 0.65rem;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.metric-row {
  display: flex;
  justify-content: space-between;
  padding: 0.3rem 0;
  border-bottom: 1px dashed var(--border-color);
  font-size: 0.8rem;
}
.metric-row:last-of-type { border-bottom: none; }
.metric-row .v { color: var(--text-primary); }
.metric-bar {
  height: 3px;
  background-color: var(--bg-tertiary);
  border-radius: 2px;
  overflow: hidden;
  margin-top: 2px;
  margin-bottom: 4px;
}
.metric-bar > div {
  height: 100%;
  background: linear-gradient(90deg, var(--accent-primary), var(--accent-secondary));
}

/* ---------- Right rail: system metrics ------------------------------ */
.rail-right { font-size: 0.78rem; }
.rail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.4rem;
}
.rail-header h3 {
  margin: 0;
  font-size: 0.72rem;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.btn-small { font-size: 0.68rem; padding: 0.25rem 0.55rem; }
.btn .btn-icon {
  flex: none;
  opacity: 0.75;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.btn:hover .btn-icon { opacity: 1; }
/* The external-link icon's arrow naturally points up-right; give it a
   tiny nudge on hover to reinforce "this opens elsewhere." */
.btn:hover .btn-icon { transform: translate(0.5px, -0.5px); }

.metric-card-grid {
  display: grid;
  gap: 0.4rem;
  grid-template-columns: 1fr;
}

.metric-card-mini {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 0.35rem 0.55rem 0.25rem;
}
.metric-card-title {
  display: block;
  text-align: center;
  font-size: 0.66rem;
  color: var(--text-secondary);
  font-weight: 600;
  margin-bottom: 0.15rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.metric-card-mini canvas {
  width: 100% !important;
  height: 100px !important;
}

/* ---------- Token usage block (left rail) -------------------------- */
.summary-tokens-block {
  margin: 0.4rem 0 1rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border-color);
}
.summary-tokens-block .summary-label { margin-bottom: 0.55rem; }
.summary-tokens {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.28rem 0.85rem;
  font-size: 0.78rem;
  margin: 0;
}
.summary-tokens dt {
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.66rem;
  align-self: center;
}
.summary-tokens dd {
  color: var(--text-primary);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---------- Show-all metrics modal --------------------------------- */
.modal { position: fixed; inset: 0; z-index: 1000; }
.modal.hidden { display: none; }
.modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(20, 16, 11, 0.55);
  backdrop-filter: blur(2px);
}
.modal-panel {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(95vw, 1100px);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 0.6rem;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.3);
  overflow: hidden;
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.85rem 1.2rem;
  border-bottom: 1px solid var(--border-color);
  background-color: var(--bg-secondary);
}
.modal-head h3 { margin: 0; font-size: 0.95rem; font-weight: 600; }
.modal-close {
  background: transparent;
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.25rem 0.55rem;
  border-radius: 0.375rem;
  cursor: pointer;
  font-family: inherit;
}
.modal-close:hover { background: var(--bg-tertiary); border-color: var(--accent-primary); color: var(--accent-primary); }

.metric-card-grid-modal {
  padding: 1.2rem;
  overflow: auto;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 1rem;
}
.metric-card-grid-modal .metric-card-mini { padding: 0.85rem 1rem 0.7rem; }
.metric-card-grid-modal .metric-card-mini canvas { height: 260px !important; }
.metric-card-grid-modal .metric-card-title { font-size: 0.82rem; }

/* ---------- Workspace ---------------------------------------------- */
.workspace-layout {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 0.75rem;
  align-items: start;
}
#ws-tree {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 0.5rem 0.7rem;
  max-height: 70vh;
  overflow: auto;
  font-size: 0.75rem;
}
#ws-tree .ws-dir {
  font-weight: 700;
  color: var(--text-secondary);
  margin-top: 0.5rem;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
#ws-tree .ws-dir:first-child { margin-top: 0; }
#ws-tree .ws-file {
  padding: 0.18rem 0.3rem;
  cursor: pointer;
  border-radius: 3px;
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
}
#ws-tree .ws-file:hover { color: var(--accent-primary); background-color: var(--bg-tertiary); }
#ws-tree .ws-file.active { color: var(--accent-primary); background-color: var(--bg-tertiary); font-weight: 600; }
#ws-tree .ws-file.skipped { color: var(--text-secondary); opacity: 0.6; cursor: default; }
#ws-tree .ws-file.skipped:hover { background-color: transparent; color: var(--text-secondary); }
#ws-tree .ws-file .size { color: var(--text-secondary); font-size: 0.68rem; opacity: 0.7; }

#ws-file {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 1rem 1.2rem;
  min-height: 200px;
  max-height: 70vh;
  overflow: auto;
}
#ws-file h4 { margin: 0 0 0.6rem; font-size: 0.82rem; color: var(--text-primary); }

/* Code surface — uses the existing bg-tertiary palette token so it's a
   slightly darker warm surface than the workspace card (which sits on
   bg-secondary). No yellow/sepia tint; just the next step on the same
   neutral warm scale, in both light and dark. */
#ws-file pre {
  font-size: 0.82rem;
  white-space: pre;
  overflow: auto;
  margin: 0;
  color: var(--text-primary);
  background-color: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 0.375rem;
  padding: 0.85rem 1rem;
  line-height: 1.6;
}
#ws-file pre code { font: inherit; background: transparent; padding: 0; }

/* ---------- Syntax highlighting (highlight.js) — warm sepia theme --- */
.hljs { color: var(--text-primary); background: transparent; }
.hljs-comment, .hljs-quote {
  color: var(--text-secondary);
  font-style: italic;
}
.hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-meta-keyword {
  color: var(--accent-primary);
  font-weight: 600;
}
.hljs-built_in, .hljs-type, .hljs-class .hljs-title, .hljs-title.class_ {
  color: var(--accent-primary);
}
.hljs-string, .hljs-regexp, .hljs-meta-string {
  color: var(--session-2);     /* warm olive */
}
.hljs-number, .hljs-symbol, .hljs-bullet, .hljs-link {
  color: var(--session-1);     /* warm gold */
}
.hljs-title, .hljs-name, .hljs-section, .hljs-function .hljs-title, .hljs-title.function_ {
  color: var(--session-1);
  font-weight: 500;
}
.hljs-attr, .hljs-attribute, .hljs-property {
  color: var(--accent-secondary);
}
.hljs-variable, .hljs-template-variable, .hljs-params {
  color: var(--text-primary);
}
.hljs-punctuation, .hljs-operator {
  color: var(--text-secondary);
}
.hljs-tag, .hljs-meta, .hljs-meta-keyword {
  color: var(--text-secondary);
}
.hljs-tag .hljs-name { color: var(--accent-primary); }
.hljs-tag .hljs-attr { color: var(--session-1); }
.hljs-deletion { color: var(--danger); }
.hljs-addition { color: var(--success); }
.hljs-doctag, .hljs-strong { font-weight: 700; }
.hljs-emphasis { font-style: italic; }

/* ---------- Logs / prompt ------------------------------------------ */
.log-box {
  margin-bottom: 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  background-color: var(--bg-secondary);
}
.log-box > summary {
  cursor: pointer;
  padding: 0.55rem 0.9rem;
  font-size: 0.78rem;
  font-weight: 600;
  list-style: none;
  color: var(--text-primary);
}
.log-box > summary::-webkit-details-marker { display: none; }
.log-box > summary::before { content: "▸ "; color: var(--accent-primary); }
.log-box[open] > summary::before { content: "▾ "; }
.logpre {
  font-size: 0.74rem;
  white-space: pre-wrap;
  word-break: break-word;
  background-color: var(--bg-primary);
  border-top: 1px solid var(--border-color);
  padding: 0.7rem 0.9rem;
  max-height: 50vh;
  overflow: auto;
  color: var(--text-primary);
  margin: 0;
  border-radius: 0 0 0.5rem 0.5rem;
}

#prompt {
  font-size: 0.84rem;
  white-space: pre-wrap;
  word-break: break-word;
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 1.1rem 1.3rem;
  color: var(--text-primary);
  line-height: 1.7;
}

/* ---------- Judge verdict cards ------------------------------------ */
.verdict-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.2rem;
}
.verdict-card {
  background-color: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 0.5rem;
  padding: 0.85rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.85rem;
}
/* No accent left-border — the icon already carries the status cue and
   keeps the card visually consistent with the rest of the warm palette. */
.verdict-icon {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.95rem;
}
.verdict-card.good .verdict-icon { background: rgba(111, 125, 69, 0.18); color: var(--session-2); }
.verdict-card.bad  .verdict-icon { background: rgba(151, 85, 58, 0.18);  color: var(--session-4); }
.verdict-body { display: flex; flex-direction: column; gap: 0.15rem; }
.verdict-label {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.verdict-text { font-size: 0.85rem; color: var(--text-primary); font-weight: 500; }

/* ---------- Judge -------------------------------------------------- */
/* Items render via the same trace renderer (renderCodexItem). We just
   space them out — no card chrome or left border, so the focus stays on
   the inner content (terminal commands, thoughts, todos). */
.judge-stream { display: flex; flex-direction: column; gap: 0.8rem; }
.judge-item { padding: 0; background: transparent; border: none; }

/* Diff blocks (Edit tool) — warm "olive" add / "clay" remove so they
   harmonize with the sepia palette instead of being neon red/green. */
.diff-remove, .diff-add {
  padding: 4px 8px;
  border-radius: 4px;
  margin-top: 4px;
  font-size: 0.78rem;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: inherit;
}
.diff-remove {
  background-color: rgba(151, 85, 58, 0.12);
  color: var(--session-4);
  border-left: 2px solid rgba(151, 85, 58, 0.45);
}
.diff-add {
  background-color: rgba(111, 125, 69, 0.14);
  color: var(--session-2);
  border-left: 2px solid rgba(111, 125, 69, 0.45);
}
[data-theme="light"] .diff-remove { color: #97553a; }
[data-theme="light"] .diff-add    { color: #56612e; }

/* ---------- Scrollbars --------------------------------------------- */
* { scrollbar-width: thin; scrollbar-color: var(--border-color) transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 3px; }
*::-webkit-scrollbar-thumb:hover { background: var(--accent-primary); }

/* ---------- Toolbar "Metrics" button -------------------------------- */
/* The canonical "open metrics in a modal" entry point. Visible at every
   width — at wide screens you click it to inspect a chart full-size; at
   narrow screens the rail is hidden, so this is the only path in. The
   rail-internal "Show all" button is intentionally hidden (below) so
   the two don't compete. */
.metrics-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  padding: 0.35rem 0.7rem;
  border-radius: 0.375rem;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  cursor: pointer;
  transition: var(--transition);
}
.metrics-btn:hover {
  border-color: var(--accent-primary);
  color: var(--accent-primary);
}
.metrics-btn svg { color: var(--accent-primary); flex: none; }

/* Rail-internal "Show all" button — superseded by the toolbar Metrics
   button to avoid duplicate affordances at wide widths. */
#show-all-metrics { display: none !important; }

/* ---------- Responsive --------------------------------------------- */
/* At medium widths the right rail no longer fits as a third column —
   hide it, but surface the metrics-modal entry point in the trace
   toolbar so users still reach the same content in one click. We
   deliberately don't STACK the rail because scrolling past hundreds of
   trace events to reach the metrics defeats their "always visible"
   purpose. */
@media (max-width: 1280px) {
  .layout { grid-template-columns: 300px minmax(0, 1fr); }
  .rail-right { display: none; }
  /* metrics-btn is already display: inline-flex at all widths. */
}
@media (max-width: 900px) {
  .layout { grid-template-columns: 1fr; padding: 1rem; gap: 1rem; }
  .rail-left {
    position: static;
    max-height: none;
    overflow: visible;
  }
  .workspace-layout { grid-template-columns: 1fr; }
  .topbar-inner { gap: 0.6rem; }
}
