@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');

:root {
  --bg: #000000;
  --bg-elevated: #0a0a0a;
  --phosphor: #00FF41;
  --phosphor-dim: #00aa2a;
  --phosphor-glow: rgba(0, 255, 65, 0.4);
  --warning: #ffd93d;
  --warning-dim: #b89a2a;
  --scanline: rgba(0, 255, 65, 0.03);

  /* Color semantics:
       phosphor green  = system / chrome / what the tool says
       cyan blue       = what the USER wrote (any input they author)
       warning yellow  = what the AI returned (ai-output, review, anomalies) */
  --user-input:      #00ddff;
  --user-input-dim:  #0088aa;
  --user-input-glow: rgba(0, 221, 255, 0.4);

  --font-mono: "JetBrains Mono", "Fira Code", "IBM Plex Mono", ui-monospace, monospace;
  --fs-base: 14px;
  --fs-chrome: 11px;
  --fs-title: 18px;
  --fs-header: 24px;
}

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

html, body {
  /* No fixed height / overflow:hidden any more - the page is intentionally
     longer than the viewport so the rendered iframe lives below the fold
     and students have to scroll past the code viewer to reach it. */
  background: var(--bg);
  color: var(--phosphor);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  text-shadow: 0 0 1px var(--phosphor-glow);
  overflow-x: hidden;
}

body { animation: crt-flicker 150ms infinite; }

@keyframes crt-flicker {
  0%, 100% { opacity: 1; }
  47% { opacity: 0.99; }
  50% { opacity: 0.97; }
  53% { opacity: 0.99; }
}

/* Scanline overlay */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 2px,
    var(--scanline) 2px,
    var(--scanline) 3px
  );
  z-index: 9000;
}

/* CRT vignette / curvature illusion */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  border-radius: 2vmin;
  box-shadow: inset 0 0 12vmin rgba(0,0,0,0.65);
  z-index: 9001;
}

/* ---------- Layout ---------- */
/* .app is exactly one viewport tall: header + side-by-side editors +
   diagnostics. The page viewer sits in a separate .page-block sibling
   below, sized to a second viewport, reachable only by scrolling.
   Padding here intentionally generous so the cursor has comfortable
   "safe zones" outside the scrollable panels - makes it obvious where
   to put the mouse to wheel-scroll the PAGE vs the panel underneath. */
.app {
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 20px 28px;
  gap: 18px;
  box-sizing: border-box;
}

.app-header {
  font-size: var(--fs-chrome);
  display: flex;
  justify-content: space-between;
  align-items: center;
  letter-spacing: 0.1em;
}

.app-header .logo {
  font-size: var(--fs-title);
  letter-spacing: 0.2em;
}

.app-header .meta {
  color: var(--phosphor-dim);
  display: flex;
  align-items: center;
  gap: 14px;
}

.meta-link {
  color: var(--phosphor-dim);
  text-decoration: none;
  letter-spacing: 0.1em;
  font-size: var(--fs-chrome);
}
.meta-link:hover {
  color: var(--phosphor);
  text-shadow: 0 0 4px var(--phosphor);
}

/* Tokens/sec readout next to the status indicator, updated after each
   successful synthesize / sync. Visible benchmark for comparing model
   sizes or prompt shapes. */
.gen-stats {
  font-size: 10px;
  letter-spacing: 0.05em;
  color: var(--phosphor-dim);
  margin-left: 6px;
}

/* First-screen layout: markdown viewer (4 sections) and code viewer
   side by side, filling the .app's remaining vertical space after
   the header and before the diagnostics. Big gap between viewers so
   there's room to wheel-scroll the page without your cursor sitting
   on top of a panel. */
.viewers-top {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
  min-height: 0;
}
#viewer-md, #viewer-code { min-height: 0; }

@media (max-width: 900px) {
  .viewers-top {
    grid-template-columns: 1fr;
    grid-auto-rows: minmax(0, 1fr);
  }
}

/* Below-the-fold container for the rendered page viewer. Generous top
   padding gives a visible "you scrolled past the editors" beat before
   the iframe begins, and side padding matches the editors above. */
.page-block {
  padding: 32px 28px 24px;
  box-sizing: border-box;
}
.page-block #viewer-page {
  height: calc(100vh - 56px);
  display: flex;
  flex-direction: column;
}

/* ---------- Viewer (ASCII frame fallback: CSS border + glyph corners) ---------- */
.viewer {
  position: relative;
  border: 1px solid var(--phosphor);
  display: flex;
  flex-direction: column;
  background: var(--bg);
  min-height: 0;
}

.viewer::before, .viewer::after {
  position: absolute;
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  color: var(--phosphor);
  background: var(--bg);
  padding: 0 2px;
  pointer-events: none;
}
.viewer::before { content: '┘'; bottom: -7px; left: -3px; }
.viewer::after  { content: '└'; top: -7px; right: -3px;
  /* visual flip: not strictly accurate ASCII, but reads as a corner glyph */
}

.viewer-title {
  position: absolute;
  top: -10px;
  left: 12px;
  background: var(--bg);
  padding: 0 8px;
  font-size: var(--fs-chrome);
  letter-spacing: 0.15em;
  color: var(--phosphor);
  z-index: 2;
}
.viewer-title::before { content: '┌─[ '; color: var(--phosphor-dim); }
.viewer-title::after  { content: ' ]─'; color: var(--phosphor-dim); }

.viewer-body {
  flex: 1;
  position: relative;
  padding: 16px 12px 8px 12px;
  min-height: 0;
  overflow: hidden;
}

/* Scope to direct-child textareas only. The code editor's textarea lives
   nested inside .editor, so this rule MUST NOT match it — otherwise it
   overrides the transparent text/caret on the shadow textarea and the
   user sees plain phosphor green covering the Prism-highlighted pre. */
.viewer-body > textarea, .viewer-body > iframe {
  width: 100%;
  height: 100%;
  background: var(--bg);
  color: var(--phosphor);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: none;
  outline: none;
  resize: none;
  caret-color: var(--phosphor);
}

.viewer-body > textarea::placeholder { color: var(--phosphor-dim); }

.viewer-body > iframe { background: white; }

/* ---------- Markdown viewer: 4 sectioned panels ---------- */
.markdown-sections {
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  padding: 16px 12px 8px 12px;
}

.md-section { display: flex; flex-direction: column; gap: 6px; }

.md-section-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-bottom: 2px;
  border-bottom: 1px dashed var(--phosphor-dim);
}
.md-section-label {
  font-size: var(--fs-chrome);
  letter-spacing: 0.2em;
  color: var(--phosphor);
}

.md-section textarea {
  background: var(--bg);
  color: var(--user-input);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: none;
  outline: none;
  resize: none;
  min-height: 4.5em;
  padding: 6px 0;
  line-height: 1.45;
  white-space: pre-wrap;
  caret-color: var(--user-input);
  text-shadow: 0 0 1px var(--user-input-glow);
  /* No internal scrollbar; the textarea grows with content (see
     autoGrowTextarea in app.js) and the outer .markdown-sections
     container handles overflow with a single phosphor scrollbar. */
  overflow: hidden;
}
.md-section textarea::placeholder { color: var(--phosphor-dim); font-style: italic; }

/* ---------- Phosphor-themed scrollbars ---------- */
/* Default browser scrollbars look wrong on this UI. Theming any
   scrollable area inside the markdown viewer and the diagnostics
   panel to match the phosphor / warning palette. Code viewer keeps
   its own VS Code-style scrollbars further down. */
.markdown-sections,
.markdown-sections *,
.diagnostics-body {
  scrollbar-width: thin;
  scrollbar-color: var(--phosphor-dim) transparent;
}
.diagnostics-body { scrollbar-color: var(--warning-dim) transparent; }

.markdown-sections::-webkit-scrollbar,
.markdown-sections *::-webkit-scrollbar,
.diagnostics-body::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
.markdown-sections::-webkit-scrollbar-track,
.markdown-sections *::-webkit-scrollbar-track,
.diagnostics-body::-webkit-scrollbar-track {
  background: transparent;
}
.markdown-sections::-webkit-scrollbar-thumb,
.markdown-sections *::-webkit-scrollbar-thumb {
  background: var(--phosphor-dim);
  border: 2px solid var(--bg);
}
.markdown-sections::-webkit-scrollbar-thumb:hover,
.markdown-sections *::-webkit-scrollbar-thumb:hover {
  background: var(--phosphor);
}
.diagnostics-body::-webkit-scrollbar-thumb {
  background: var(--warning-dim);
  border: 2px solid var(--bg);
}
.diagnostics-body::-webkit-scrollbar-thumb:hover {
  background: var(--warning);
}

/* VS Code-themed scrollbars for the code editor shadow textarea */
.editor-display,
.editor-input {
  scrollbar-width: thin;
  scrollbar-color: #424242 #1e1e1e;
}
.editor-display::-webkit-scrollbar,
.editor-input::-webkit-scrollbar {
  width: 14px;
  height: 14px;
}
.editor-display::-webkit-scrollbar-track,
.editor-input::-webkit-scrollbar-track {
  background: #1e1e1e;
}
.editor-display::-webkit-scrollbar-thumb,
.editor-input::-webkit-scrollbar-thumb {
  background: #424242;
}
.editor-display::-webkit-scrollbar-thumb:hover,
.editor-input::-webkit-scrollbar-thumb:hover {
  background: #4f4f4f;
}

.btn--mini {
  font-size: 9px;
  letter-spacing: 0.15em;
  padding: 2px 4px;
  color: var(--phosphor-dim);
}
.btn--mini::before, .btn--mini::after { color: var(--phosphor-dim); opacity: 0.7; }
.btn--mini:hover::before, .btn--mini:hover::after { color: var(--phosphor); opacity: 1; }

/* ---------- Template picker + whole-spec review ---------- */
.md-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: var(--fs-chrome);
  padding-bottom: 4px;
  border-bottom: 1px dashed var(--phosphor-dim);
}
.md-template-label {
  letter-spacing: 0.2em;
  color: var(--phosphor-dim);
}
.md-template-select {
  background: var(--bg);
  color: var(--phosphor);
  border: 1px solid var(--phosphor-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  padding: 4px 8px;
  letter-spacing: 0.08em;
  cursor: pointer;
  outline: none;
}
.md-template-select:focus { border-color: var(--phosphor); }

.md-review-output {
  padding: 10px 12px;
  border: 1px solid var(--warning);
  background: rgba(255, 217, 61, 0.04);
  font-size: var(--fs-chrome);
  color: var(--warning);
  white-space: pre-wrap;
  line-height: 1.55;
}
.md-review-output.is-loading { color: var(--phosphor-dim); border-color: var(--phosphor-dim); }
.md-review-output .review-title {
  display: block;
  font-weight: 700;
  letter-spacing: 0.2em;
  margin-bottom: 6px;
  color: var(--warning);
}
.md-review-output .dismiss {
  display: block;
  margin-top: 8px;
  font-size: 9px;
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
.md-review-output .dismiss:hover { color: var(--phosphor); }

.ai-output {
  margin-top: 4px;
  padding: 8px 10px;
  border-left: 2px solid var(--warning);
  background: rgba(255, 217, 61, 0.04);
  font-size: var(--fs-chrome);
  color: var(--warning);
  white-space: pre-wrap;
  line-height: 1.5;
}
.ai-output.is-loading { color: var(--phosphor-dim); border-left-color: var(--phosphor-dim); }
.ai-output .dismiss {
  display: block;
  margin-top: 6px;
  font-size: 9px;
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
.ai-output .dismiss:hover { color: var(--phosphor); }

/* ---------- Code viewer: VS Code Dark+ surface, shadow-textarea editor ----
   The code panel is intentionally NOT phosphor-themed. The pedagogical goal
   is for students to recognize what VS Code looks like, since that is what
   they will graduate to. The viewer's outer frame stays on-brand (phosphor
   border, ASCII title) but the editing surface itself is genuine Dark+. */

.editor {
  position: relative;
  width: 100%;
  height: 100%;
  background: #1e1e1e;        /* VS Code Dark+ editor background */
}

.editor-display,
.editor-input {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: 1.5;
  tab-size: 2;
  /* Wrap long lines so students don't have to scroll horizontally to
     read or edit. pre-wrap preserves indentation; overflow-wrap: anywhere
     also breaks unbreakable runs (long URLs, base64, etc.). Both layers
     must use identical wrap settings or the cursor drifts off the tokens. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  overflow: auto;
  border: 0;
  background: transparent;
}

.editor-display {
  z-index: 1;
  pointer-events: none;
  color: #d4d4d4;             /* VS Code default foreground */
  text-shadow: none;
}
.editor-display code { font: inherit; background: none; padding: 0; color: inherit; }

.editor-input {
  z-index: 2;
  color: transparent;
  caret-color: #aeafad;        /* VS Code cursor */
  resize: none;
  outline: none;
}
.editor-input::placeholder { color: #6a6a6a; }
.editor-input::selection   { background: #264f78; }   /* VS Code selection */

/* ---------- Prism token theme — VS Code Dark+ ----------
   These colors are taken straight from VS Code's built-in Dark+ theme
   so the editing surface is visually identical to what students will
   see in a real VS Code window. */

.token.comment,
.token.prolog,
.token.cdata             { color: #6a9955; font-style: italic; }     /* green */
.token.doctype,
.token.doctype .name     { color: #569cd6; }                          /* blue */

/* HTML tag names + their punctuation: VS Code blue */
.token.tag,
.token.tag > .punctuation,
.token.tag .punctuation,
.token.tag .token.tag,
.token.tag .token.namespace { color: #569cd6; }

/* Attribute names: light cyan */
.token.attr-name         { color: #9cdcfe; }

/* Strings + attribute values + URLs: orange */
.token.attr-value,
.token.attr-value .punctuation,
.token.string,
.token.url               { color: #ce9178; }

/* Numbers + booleans + constants: light green */
.token.number,
.token.boolean,
.token.constant          { color: #b5cea8; }

/* Punctuation, operators: default foreground */
.token.punctuation       { color: #d4d4d4; }
.token.operator          { color: #d4d4d4; }
.token.entity            { color: #d7ba7d; }

/* CSS: selectors gold-tan, properties cyan, units like numbers */
.token.selector,
.token.class-name        { color: #d7ba7d; }
.token.property          { color: #9cdcfe; }
.token.unit              { color: #b5cea8; }

/* JS: keywords purple, function names pale yellow */
.token.keyword           { color: #c586c0; }
.token.symbol            { color: #569cd6; }
.token.function          { color: #dcdcaa; }
.token.builtin           { color: #4ec9b0; }
.token.regex             { color: #d16969; }

.viewer-footer {
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  padding: 6px 12px 8px;
  font-size: var(--fs-chrome);
  border-top: 1px dashed var(--phosphor-dim);
}

.viewer-header {
  display: flex;
  justify-content: flex-end;
  gap: 16px;
  padding: 14px 12px 6px;
  font-size: var(--fs-chrome);
  border-bottom: 1px dashed var(--phosphor-dim);
}

/* ---------- Buttons (bracket text only) ---------- */
.btn {
  background: none;
  border: none;
  color: var(--phosphor);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.12em;
  cursor: pointer;
  padding: 2px 4px;
  text-shadow: 0 0 1px var(--phosphor-glow);
  transition: text-shadow 100ms;
}
.btn::before { content: '[ '; color: var(--phosphor-dim); }
.btn::after  { content: ' ]'; color: var(--phosphor-dim); }
.btn:hover { text-shadow: 0 0 6px var(--phosphor); }
.btn:hover::before, .btn:hover::after { color: var(--phosphor); }
.btn:active { background: var(--phosphor); color: var(--bg); text-shadow: none; }
.btn:active::before, .btn:active::after { color: var(--bg); }
.btn:disabled {
  color: var(--phosphor-dim);
  cursor: not-allowed;
  text-shadow: none;
}
.btn--secondary { color: var(--phosphor-dim); font-size: 10px; }

/* btn--ai: yellow text + bracket glyphs to mark a button that
   invokes the AI. Compose with .btn--mini (per-section ASK AI) or
   .btn--secondary (REVIEW, CHECK COMMENTS). Two-class specificity so
   it wins over the base .btn color regardless of declaration order. */
.btn.btn--ai { color: var(--warning); text-shadow: 0 0 1px var(--warning); }
.btn.btn--ai::before, .btn.btn--ai::after { color: var(--warning-dim); }
.btn.btn--ai:hover { text-shadow: 0 0 6px var(--warning); }
.btn.btn--ai:hover::before, .btn.btn--ai:hover::after { color: var(--warning); }
.btn.btn--ai:active { background: var(--warning); color: var(--bg); text-shadow: none; }
.btn.btn--ai:active::before, .btn.btn--ai:active::after { color: var(--bg); }

/* ---------- Comment-check feedback overlay on viewer 2 ---------- */
/* Sits over the bottom half of the editor when the student clicks
   // CHECK COMMENTS //. The editor itself stays visible above so the
   student can see what lines the feedback references. */
.code-review-output {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 55%;
  overflow-y: auto;
  background: rgba(0, 0, 0, 0.92);
  border-top: 2px solid var(--warning);
  padding: 12px 14px 10px;
  color: var(--warning);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  line-height: 1.55;
  white-space: pre-wrap;
  z-index: 4;
}
.code-review-output.is-loading { color: var(--phosphor-dim); border-top-color: var(--phosphor-dim); }
.code-review-output .review-title {
  display: block;
  font-weight: 700;
  letter-spacing: 0.2em;
  margin-bottom: 6px;
  color: var(--warning);
}
.code-review-output .dismiss {
  display: block;
  margin-top: 8px;
  font-size: 9px;
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}
.code-review-output .dismiss:hover { color: var(--phosphor); }

/* ---------- Generating overlay ---------- */
.generating {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-title);
  letter-spacing: 0.25em;
  color: var(--phosphor);
  background: rgba(0,0,0,0.85);
  z-index: 5;
  pointer-events: none;
  text-shadow: 0 0 8px var(--phosphor);
}
.generating.is-hidden { display: none; }

/* ---------- Diagnostics ---------- */
.diagnostics {
  border-top: 1px solid var(--warning-dim);
  background: var(--bg);
  font-size: var(--fs-chrome);
  color: var(--warning);
}
.diagnostics-toggle {
  width: 100%;
  background: none;
  border: none;
  color: var(--warning);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  text-align: left;
  padding: 6px 12px;
  cursor: pointer;
  text-shadow: 0 0 2px var(--warning);
}
.diagnostics-body {
  padding: 8px 12px 12px;
  max-height: 30vh;
  overflow: auto;
  display: none;
  white-space: pre-wrap;
  font-size: var(--fs-chrome);
  line-height: 1.5;
}
.diagnostics.is-open .diagnostics-body { display: block; }
.diagnostics-empty { border-top-color: var(--phosphor-dim); }
.diagnostics-empty .diagnostics-toggle {
  color: var(--phosphor-dim);
  text-shadow: none;
}

/* ---------- Boot sequence ---------- */
.boot {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 10000;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  padding: 8vh 12vw;
  font-size: var(--fs-base);
  cursor: pointer;
}
.boot.is-done { opacity: 0; pointer-events: none; transition: opacity 400ms; }
.boot-line { white-space: pre; min-height: 1.4em; }
.boot-cursor::after { content: '█'; animation: blink 600ms steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* ---------- Ambient anomaly flickers ---------- */
.anomaly {
  position: fixed;
  color: var(--warning);
  font-size: var(--fs-chrome);
  letter-spacing: 0.12em;
  cursor: pointer;
  z-index: 8000;
  opacity: 0;
  text-shadow: 0 0 3px var(--warning);
}
.anomaly.is-on { animation: anomaly-flicker 1400ms ease-in-out forwards; }
@keyframes anomaly-flicker {
  0%   { opacity: 0; }
  15%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; }
}

[data-scramble] { display: inline-block; }

/* ---------- Mode toggle (header) ----------
   Two side-by-side tabs that switch the markdown viewer between the SDD
   workflow (4 spec panels) and Vibecode workflow (single freeform
   textarea). Both tabs share the same phosphor-green chrome - vibecode
   is a lower-structure container for the same prompt-craft skill, not
   an editorialized "warning" mode, so the UI does not visually frame
   one as better than the other. */
.mode-toggle {
  display: inline-flex;
  gap: 2px;
  margin-right: 6px;
}
.mode-tab {
  background: none;
  border: none;
  color: var(--phosphor-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  padding: 2px 6px;
  cursor: pointer;
  text-shadow: none;
}
.mode-tab:hover { color: var(--phosphor); text-shadow: 0 0 4px var(--phosphor); }
.mode-tab[aria-selected="true"] {
  color: var(--phosphor);
  text-shadow: 0 0 4px var(--phosphor);
  background: rgba(0, 255, 65, 0.08);
}

/* ---------- Mode visibility -----------
   Default (no body class) renders as SDD - .mode-only-vibecode elements
   stay hidden until body.mode-vibecode is set. */
.mode-only-vibecode { display: none; }
body.mode-vibecode .mode-only-vibecode { display: block; }
body.mode-vibecode .mode-only-sdd      { display: none !important; }

/* The SDD wrapper preserves the prior flex-column-with-gap layout that
   .markdown-sections used to provide to its 4 .md-section children
   directly. Now that an extra wrapping div sits between them, the
   wrapper has to carry that layout itself. */
.sdd-sections { display: flex; flex-direction: column; gap: 14px; flex: 1 1 auto; min-height: 0; }

/* In vibecode mode, the block fills the remaining vertical space inside
   .markdown-sections, with the history block sitting above the prompt
   textarea. */
body.mode-vibecode .vibecode-block {
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1 1 auto;
  min-height: 0;
}

/* ---------- Vibecode block ----------
   Single freeform prompt + scrollable history of prior prompts. The
   history is the student's portable prompt-craft artifact - COPY
   exports it as markdown so they can carry it into SDD panels as
   raw material when they switch modes. */
.vibecode-history {
  border: 1px dashed var(--phosphor-dim);
  padding: 10px 12px;
  max-height: 200px;
  overflow-y: auto;
}
.vibecode-history-label {
  font-size: var(--fs-chrome);
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
  margin-bottom: 6px;
}
.vibecode-history-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.vibecode-turn {
  display: flex;
  gap: 8px;
  color: var(--user-input);
  text-shadow: 0 0 1px var(--user-input-glow);
  font-size: var(--fs-base);
  line-height: 1.45;
  white-space: pre-wrap;
  word-break: break-word;
}
.vibecode-turn-index {
  flex: 0 0 auto;
  color: var(--phosphor-dim);
  font-size: var(--fs-chrome);
  margin-top: 3px;
  user-select: none;
}
.vibecode-turn-text { flex: 1 1 auto; }

.vibecode-prompt {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 auto;
  min-height: 0;
}
.vibecode-label {
  font-size: var(--fs-chrome);
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
}
.vibecode-prompt textarea {
  flex: 1 1 auto;
  min-height: 240px;
  width: 100%;
  background: var(--bg);
  color: var(--user-input);
  caret-color: var(--user-input);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: 1px solid var(--phosphor-dim);
  outline: none;
  resize: none;
  padding: 10px 12px;
  line-height: 1.5;
  text-shadow: 0 0 1px var(--user-input-glow);
}
.vibecode-prompt textarea:focus { border-color: var(--phosphor); }
.vibecode-prompt textarea::placeholder { color: var(--phosphor-dim); font-style: italic; }

/* ---------- Stage progression (SDD v0.2 five-stage loop) ----------
   The strip below the header shows where the student is in the loop:
   Markdown -> Markdown QC -> Code -> Code QC -> Render. The current
   stage is highlighted; later stages are dim. Return-to-Markdown is
   the global escape hatch from any non-markdown stage and resets all
   forward state. */
.stage-progress {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  padding: 4px 0;
  border-top:    1px solid var(--phosphor-dim);
  border-bottom: 1px solid var(--phosphor-dim);
  margin-bottom: 8px;
}
.stage-list {
  list-style: none;
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 0;
  padding: 0;
}
.stage-step {
  color: var(--phosphor-dim);
  padding: 2px 6px;
}
.stage-step.is-active {
  color: var(--phosphor);
  text-shadow: 0 0 4px var(--phosphor);
  background: rgba(0, 255, 65, 0.08);
}
.stage-step.is-past {
  color: var(--phosphor-dim);
  text-decoration: line-through;
  text-decoration-color: var(--phosphor-dim);
}
.stage-sep { color: var(--phosphor-dim); }
.stage-return {
  background: none;
  border: 1px solid var(--phosphor-dim);
  color: var(--phosphor);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  padding: 3px 10px;
  cursor: pointer;
}
.stage-return:hover {
  border-color: var(--phosphor);
  text-shadow: 0 0 4px var(--phosphor);
}

/* ---------- Stage-based visibility (SDD v0.2 only) ----------
   data-sdd-stage="<stage>" on a section means "show only when SDD mode
   is in this stage." In vibecode mode the attribute is ignored. */
body.mode-sdd [data-sdd-stage] { display: none; }
body.mode-sdd.stage-markdown    #viewer-md     { display: flex; }
body.mode-sdd.stage-markdown-qc #viewer-mdqc   { display: flex; }
body.mode-sdd.stage-synthesized #viewer-code   { display: flex; }
body.mode-sdd.stage-code-qc     #viewer-codeqc { display: flex; }
body.mode-sdd.stage-render      .page-block    { display: block; }

/* Vibecode mode never enters the QC stages; hide those views. The
   existing #viewer-md and #viewer-code stay visible as before. */
body.mode-vibecode #viewer-mdqc,
body.mode-vibecode #viewer-codeqc {
  display: none;
}

/* SDD mode is single-column at the .viewers-top level - each stage
   shows one viewer, full width. Vibecode mode keeps the v0.1 two-
   column layout (spec + code side by side). */
body.mode-sdd .viewers-top { grid-template-columns: 1fr; }

/* SDD synthesized stage shows audited spec on the left + streaming
   code on the right, so the student can compare intent and output
   as the model writes. */
body.mode-sdd.stage-synthesized .viewers-top { grid-template-columns: 1fr 1.2fr; }

/* In the SDD render stage, .viewers-top has no visible children -
   collapse it so the iframe (which sits in .page-block, the sibling
   of .app) is what the student sees, not an empty pane plus scroll. */
body.mode-sdd.stage-render .viewers-top,
body.mode-sdd.stage-render .app { min-height: 0; }
body.mode-sdd.stage-render .viewers-top { display: none; }

/* ---------- QC views (Markdown QC and Code QC) ---------- */
.viewer-qc .viewer-body.qc-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  overflow: hidden;
}
.viewer-qc .viewer-body.qc-body--three {
  grid-template-columns: 1fr 1fr 1fr;
}
.qc-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  gap: 6px;
  border: 1px dashed var(--phosphor-dim);
  padding: 10px 12px;
  overflow-y: auto;
}
.qc-pane-label {
  font-size: var(--fs-chrome);
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
}
.qc-spec-display {
  flex: 1 1 auto;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--user-input);
  text-shadow: 0 0 1px var(--user-input-glow);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  line-height: 1.5;
  margin: 0;
}
.qc-placeholder {
  flex: 1 1 auto;
  color: var(--phosphor-dim);
  font-style: italic;
  font-size: var(--fs-base);
  line-height: 1.5;
}

/* ---------- QC checklist rows ----------
   Each panel group contains 4 rows. Each row is a fieldset with a
   legend (category + helper question), three radio answers, and an
   optional Note textarea. The category labels (Contradiction:,
   Ambiguity:, etc.) appear here because the checklist IS the canonical
   inspection surface - those labels are part of what trains the
   cognitive moves. They never appear in Ask AI output (constraint #3). */
.qc-panel-group {
  border-bottom: 1px solid var(--phosphor-dim);
  padding-bottom: 14px;
  margin-bottom: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.qc-panel-group:last-child {
  border-bottom: none;
  margin-bottom: 0;
}
.qc-panel-heading {
  font-size: var(--fs-chrome);
  letter-spacing: 0.2em;
  color: var(--phosphor);
  font-weight: 700;
}
.qc-row {
  border: 1px dashed var(--phosphor-dim);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.qc-row-legend {
  font-size: var(--fs-base);
  line-height: 1.45;
  padding: 0;
}
.qc-row-category {
  color: var(--phosphor);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.qc-row-question {
  color: var(--phosphor);
  text-shadow: 0 0 1px var(--phosphor-glow);
}
.qc-row-controls {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  align-items: center;
  font-size: var(--fs-chrome);
  letter-spacing: 0.08em;
}
.qc-row-answer {
  color: var(--phosphor-dim);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.qc-row-answer input[type="radio"] {
  accent-color: var(--phosphor);
  cursor: pointer;
}
.qc-row-answer:hover { color: var(--phosphor); }
.qc-row-answer input:checked + * { color: var(--phosphor); }
.qc-row-note-label {
  font-size: var(--fs-chrome);
  letter-spacing: 0.15em;
  color: var(--phosphor-dim);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.qc-row-note {
  background: var(--bg);
  color: var(--user-input);
  caret-color: var(--user-input);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: 1px solid var(--phosphor-dim);
  outline: none;
  resize: vertical;
  padding: 6px 8px;
  line-height: 1.45;
  text-shadow: 0 0 1px var(--user-input-glow);
}
.qc-row-note:focus { border-color: var(--phosphor); }

/* ---------- Code QC artifact pane: tabs + iframe + code display ---------- */
.qc-artifact-tabs {
  display: flex;
  gap: 2px;
  margin-bottom: 6px;
}
.qc-artifact-tab {
  background: none;
  border: 1px solid var(--phosphor-dim);
  color: var(--phosphor-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  padding: 3px 10px;
  cursor: pointer;
}
.qc-artifact-tab:hover {
  border-color: var(--phosphor);
  color: var(--phosphor);
  text-shadow: 0 0 4px var(--phosphor);
}
.qc-artifact-tab[aria-selected="true"] {
  color: var(--phosphor);
  border-color: var(--phosphor);
  background: rgba(0, 255, 65, 0.08);
  text-shadow: 0 0 4px var(--phosphor);
}
.qc-code-frame {
  flex: 1 1 auto;
  width: 100%;
  border: 1px solid var(--phosphor-dim);
  background: white;
  min-height: 240px;
}
.qc-code-display {
  flex: 1 1 auto;
  background: #1e1e1e;
  color: #d4d4d4;
  text-shadow: none;
  font-family: var(--font-mono);
  font-size: 12px;
  border: 1px solid var(--phosphor-dim);
  padding: 8px 10px;
  margin: 0;
  overflow: auto;
  white-space: pre;
}
.qc-code-display code { font: inherit; background: none; padding: 0; color: inherit; }

/* ============================================================
   v0.3 — chooser, tabbed workspace, QC slideouts, repair loopback,
   export. Reuses the existing tokens and the .btn / .md-section /
   .qc-row / .editor surfaces. Older mode/stage rules above are dead
   (their classes are no longer emitted) but left in place harmlessly.
   ============================================================ */

/* ---------- Path gating ---------- */
.app    { display: none; }                 /* overrides the earlier display:flex base */
#chooser { display: none; }
body.path-choosing #chooser { display: flex; }
body.path-sdd .app, body.path-vibecode .app { display: flex; }

.path-only-sdd, .path-only-vibecode { display: none; }
body.path-sdd      .path-only-sdd      { display: block; }
body.path-vibecode .path-only-vibecode { display: block; }
/* vibecode prompt block needs to stay a flex column when shown */
body.path-vibecode .vibecode-block {
  display: flex; flex-direction: column; gap: 14px; flex: 1 1 auto; min-height: 0;
}

/* ---------- Chooser screen ---------- */
.chooser {
  position: fixed;
  inset: 0;
  z-index: 50;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  padding: 6vh 6vw;
  background: var(--bg);
}
.chooser-logout {
  position: absolute;
  top: 20px;
  right: 24px;
  color: var(--phosphor-dim);
  text-decoration: none;
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
}
.chooser-logout:hover { color: var(--phosphor); text-shadow: 0 0 4px var(--phosphor); }

.chooser-logo {
  font-size: var(--fs-header);
  letter-spacing: 0.22em;
  color: var(--phosphor);
  text-shadow: 0 0 6px var(--phosphor-glow);
}
.chooser-prompt {
  font-size: var(--fs-chrome);
  letter-spacing: 0.25em;
  color: var(--phosphor-dim);
}
.chooser-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  width: 100%;
  max-width: 880px;
}
@media (max-width: 720px) { .chooser-cards { grid-template-columns: 1fr; } }
.chooser-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--phosphor-dim);
  color: var(--phosphor);
  font-family: var(--font-mono);
  padding: 22px 22px 18px;
  cursor: pointer;
  transition: border-color 120ms, box-shadow 120ms;
}
.chooser-card:hover {
  border-color: var(--phosphor);
  box-shadow: inset 0 0 24px rgba(0,255,65,0.06), 0 0 10px rgba(0,255,65,0.15);
}
.chooser-card-title {
  font-size: var(--fs-title);
  letter-spacing: 0.18em;
  color: var(--phosphor);
  text-shadow: 0 0 4px var(--phosphor-glow);
}
.chooser-card-desc {
  font-size: var(--fs-base);
  line-height: 1.55;
  color: var(--phosphor-dim);
}
.chooser-card-go {
  margin-top: auto;
  font-size: var(--fs-chrome);
  letter-spacing: 0.2em;
  color: var(--warning);
}
.chooser-note {
  font-size: var(--fs-chrome);
  letter-spacing: 0.12em;
  color: var(--warning-dim);
  text-align: center;
}

/* ---------- Header path badge ---------- */
.path-badge {
  font-size: var(--fs-chrome);
  letter-spacing: 0.18em;
  color: var(--phosphor);
  border: 1px solid var(--phosphor-dim);
  padding: 1px 6px;
}

/* ---------- Tab bar ---------- */
.tabs {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  border-top: 1px solid var(--phosphor-dim);
  border-bottom: 1px solid var(--phosphor-dim);
  padding: 4px 0;
  flex-wrap: wrap;
}
.tabs-main { display: flex; gap: 4px; flex-wrap: wrap; }
.tab {
  background: none;
  border: 1px solid transparent;
  border-bottom: none;
  color: var(--phosphor-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.12em;
  padding: 6px 14px;
  cursor: pointer;
}
.tab:hover { color: var(--phosphor); text-shadow: 0 0 4px var(--phosphor); }
.tab[aria-selected="true"] {
  color: var(--phosphor);
  border-color: var(--phosphor-dim);
  background: rgba(0,255,65,0.08);
  text-shadow: 0 0 4px var(--phosphor);
}
.tabs-aux { display: flex; gap: 8px; }
.qc-toggle {
  background: none;
  border: 1px solid var(--warning-dim);
  color: var(--warning);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  padding: 5px 10px;
  cursor: pointer;
}
.qc-toggle:hover { border-color: var(--warning); text-shadow: 0 0 4px var(--warning); }

/* ---------- Tab panels ---------- */
.tab-panels { flex: 1; min-height: 0; display: flex; }
.tab-panel { display: none; flex: 1; min-height: 0; }
.tab-panel.is-active { display: flex; }
.tab-panel > .viewer { flex: 1; min-height: 0; width: 100%; }

/* ---------- Artifact banner (code tab) ---------- */
.artifact-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 6px 14px;
  margin: 8px 12px 0;
  border: 1px solid var(--warning);
  background: rgba(255,217,61,0.05);
}
.artifact-tag {
  font-size: var(--fs-chrome);
  letter-spacing: 0.18em;
  font-weight: 700;
  color: var(--warning);
}
.artifact-hint { font-size: 10px; letter-spacing: 0.05em; color: var(--warning-dim); }

/* Comments-only annotation bar (code tab). Sits between the editor and the
   footer; arms when a code line is clicked. */
.comment-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 12px;
  border-top: 1px dashed var(--phosphor-dim);
}
.comment-bar-target {
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  color: var(--phosphor-dim);
  white-space: nowrap;
}
.comment-bar-input {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--bg);
  color: var(--user-input);
  caret-color: var(--user-input);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: 1px solid var(--phosphor-dim);
  outline: none;
  padding: 4px 8px;
  text-shadow: 0 0 1px var(--user-input-glow);
}
.comment-bar-input:focus { border-color: var(--user-input); }
.comment-bar-input:disabled { opacity: 0.4; }
.comment-bar-input::placeholder { color: var(--phosphor-dim); font-style: italic; }

/* ---------- Preview tab ---------- */
.preview-body { padding: 8px 12px; }
.preview-body > iframe { width: 100%; height: 100%; background: white; border: none; }

/* Eye-doctor flip toggle: LATEST (green) vs PREVIOUS (amber), in-frame. */
.ver-toggle { display: inline-flex; align-items: center; gap: 8px; margin-right: auto; }   /* VIEWING toggle anchors left; other controls stay right */
.ver-toggle-label { font-size: 10px; letter-spacing: 0.15em; color: var(--phosphor-dim); }
.ver-toggle .ver-opt {
  background: none;
  border: 1px solid var(--phosphor-dim);
  color: var(--phosphor-dim);
  font-family: var(--font-mono);
  font-size: var(--fs-chrome);
  letter-spacing: 0.1em;
  padding: 3px 12px;
  cursor: pointer;
}
.ver-toggle .ver-opt + .ver-opt { border-left: none; }
.ver-toggle .ver-opt:hover { color: var(--phosphor); }
.ver-toggle .ver-opt[data-ver="latest"].is-active {
  background: var(--phosphor); color: var(--bg); border-color: var(--phosphor);
}
.ver-toggle .ver-opt[data-ver="previous"].is-active {
  background: var(--warning); color: var(--bg); border-color: var(--warning);
}
/* amber frame cue while looking at the previous version */
.preview-body.viewing-previous { outline: 2px solid var(--warning); outline-offset: -2px; }

/* ---------- Spec slide-out: edit the markdown source beside the render ----
   Slides in from the LEFT (source-left / output-right, IDE style). A working
   copy of the spec; COMMIT writes it back and re-synthesizes in place. */
:root { --spec-w: min(460px, 92vw); }
.spec-slideout {
  position: fixed; top: 0; left: 0;
  height: 100vh; width: var(--spec-w);
  background: var(--bg-elevated);
  border-right: 1px solid var(--phosphor);
  box-shadow: 8px 0 24px rgba(0,0,0,0.6);
  z-index: 61;
  transform: translateX(-100%);
  transition: transform 180ms ease-out;
  display: flex; flex-direction: column;
}
.spec-slideout.is-open { transform: translateX(0); }
.spec-slideout-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 16px; border-bottom: 1px solid var(--phosphor-dim);
}
.spec-slideout-title { font-size: var(--fs-title); letter-spacing: 0.16em; color: var(--phosphor); }
.spec-slideout-close {
  background: none; border: none; color: var(--phosphor-dim);
  font-family: var(--font-mono); font-size: var(--fs-chrome); letter-spacing: 0.1em; cursor: pointer;
}
.spec-slideout-close:hover { color: var(--phosphor); }
.spec-slideout-body {
  flex: 1 1 auto; overflow-y: auto; padding: 14px 16px;
  display: flex; flex-direction: column; gap: 14px;
  scrollbar-width: thin; scrollbar-color: var(--phosphor-dim) transparent;
}
.spec-edit-section { display: flex; flex-direction: column; gap: 5px; }
.spec-edit-label {
  font-size: var(--fs-chrome); letter-spacing: 0.18em; color: var(--phosphor);
  border-bottom: 1px dashed var(--phosphor-dim); padding-bottom: 3px;
}
.spec-edit-area {
  background: var(--bg); color: var(--user-input); caret-color: var(--user-input);
  font-family: var(--font-mono); font-size: var(--fs-base);
  border: 1px solid var(--phosphor-dim); outline: none; resize: vertical;
  min-height: 4.5em; padding: 8px 10px; line-height: 1.45;
  text-shadow: 0 0 1px var(--user-input-glow);
}
.spec-edit-area:focus { border-color: var(--user-input); }
.spec-edit-section.just-guided .spec-edit-label { color: var(--warning); }
.spec-slideout-footer {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 10px 16px; border-top: 1px solid var(--phosphor-dim);
}
.spec-slideout-hint { font-size: 10px; color: var(--phosphor-dim); letter-spacing: 0.05em; }

/* Guidance panel inside the slide-out: yellow = AI guidance, the student
   adapts the suggested wording and places it themselves (no auto-insert). */
.spec-guidance {
  border: 1px solid var(--warning); background: rgba(255,217,61,0.06);
  padding: 10px 12px; display: flex; flex-direction: column; gap: 6px;
}
.spec-guidance-title { font-size: var(--fs-chrome); letter-spacing: 0.16em; color: var(--warning); font-weight: 700; }
.spec-guidance-line { font-size: var(--fs-base); line-height: 1.5; color: var(--warning); }
.spec-guidance-key { font-weight: 700; }
.spec-guidance-sugg {
  font-size: var(--fs-base); line-height: 1.45; color: var(--warning); font-style: italic;
  border-left: 2px solid var(--warning-dim); padding-left: 8px;
}
.spec-guidance-place { border-top: 1px dashed var(--warning-dim); padding-top: 6px; margin-top: 2px; }
.spec-guidance-place b { font-weight: 700; }
.spec-guidance-place i { font-style: italic; }
.spec-guidance-dismiss {
  align-self: flex-start; background: none; border: 1px solid var(--warning-dim);
  color: var(--warning); font-family: var(--font-mono); font-size: 10px;
  letter-spacing: 0.1em; padding: 3px 8px; cursor: pointer;
}

/* When the source is open, push the live render to the right of it. */
body.spec-open .tab-panel[data-panel="preview"] .preview-body { padding-left: calc(var(--spec-w) + 12px); }

/* ---------- Repair Loopback ---------- */
.repair-bar {
  border-top: 1px dashed var(--phosphor-dim);
  padding: 8px 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.repair-label { font-size: var(--fs-chrome); letter-spacing: 0.15em; color: var(--user-input-dim); }
.repair-row { display: flex; gap: 12px; align-items: stretch; }
.repair-input {
  flex: 1 1 auto;
  min-height: 2.6em;
  background: var(--bg);
  color: var(--user-input);
  caret-color: var(--user-input);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: 1px solid var(--phosphor-dim);
  outline: none;
  resize: vertical;
  padding: 8px 10px;
  line-height: 1.45;
  text-shadow: 0 0 1px var(--user-input-glow);
}
.repair-input:focus { border-color: var(--user-input); }
.repair-input::placeholder { color: var(--phosphor-dim); font-style: italic; }
.repair-hint { font-size: 10px; letter-spacing: 0.05em; color: var(--phosphor-dim); }

/* Troubleshoot diagnosis panel (amber = AI output, per the color
   convention). Step 1 of the loop: diagnosis + Socratic nudge + the
   choice to reveal the concrete spec fix. */
.repair-troubleshoot {
  border: 1px solid var(--warning);
  background: rgba(255, 217, 61, 0.05);
  padding: 10px 12px;
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.repair-ts-title {
  font-size: var(--fs-chrome);
  letter-spacing: 0.18em;
  font-weight: 700;
  color: var(--warning);
}
.repair-ts-line {
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--warning);
  margin: 0;
}
.repair-ts-key { font-weight: 700; letter-spacing: 0.04em; color: var(--warning); }
.repair-ts-nudge { font-style: italic; }
.repair-ts-actions { display: flex; gap: 16px; margin-top: 2px; }


/* ---------- Export tab ---------- */
.export-body {
  display: flex;
  flex-direction: column;
  gap: 18px;
  overflow-y: auto;
  padding: 16px 16px 20px;
}
.export-lead { font-size: var(--fs-base); line-height: 1.6; color: var(--phosphor-dim); max-width: 70ch; }
.export-lead code { color: var(--warning); }
.export-lead em { color: var(--phosphor); font-style: normal; }
.export-group {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  border: 1px dashed var(--phosphor-dim);
  padding: 12px 14px;
}
.export-group-title { font-size: var(--fs-chrome); letter-spacing: 0.2em; color: var(--phosphor); }
.export-subhead { font-size: 10px; letter-spacing: 0.08em; color: var(--phosphor-dim); margin-top: 6px; }
.export-hint { font-size: 10px; color: var(--phosphor-dim); line-height: 1.5; max-width: 70ch; }
.export-status { font-size: var(--fs-chrome); letter-spacing: 0.1em; color: var(--warning); min-height: 1.2em; }

/* ---------- QC slideouts ---------- */
.qc-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 60;
}
.qc-slideout {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: min(580px, 94vw);
  background: var(--bg-elevated);
  border-left: 1px solid var(--phosphor);
  box-shadow: -8px 0 24px rgba(0,0,0,0.6);
  z-index: 61;
  transform: translateX(100%);
  transition: transform 180ms ease-out;
  display: flex;
  flex-direction: column;
}
.qc-slideout.is-open { transform: translateX(0); }
.qc-slideout-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid var(--phosphor-dim);
}
.qc-slideout-title { font-size: var(--fs-title); letter-spacing: 0.18em; color: var(--phosphor); }
.qc-slideout-close {
  background: none; border: none; color: var(--phosphor-dim);
  font-family: var(--font-mono); font-size: var(--fs-chrome);
  letter-spacing: 0.1em; cursor: pointer;
}
.qc-slideout-close:hover { color: var(--phosphor); }
.qc-slideout-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px 16px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  scrollbar-width: thin;
  scrollbar-color: var(--phosphor-dim) transparent;
}
.qc-slideout-intro { font-size: var(--fs-chrome); line-height: 1.55; color: var(--phosphor-dim); font-style: italic; }
.qc-improve { display: flex; flex-direction: column; gap: 6px; }
.qc-improve-label { font-size: var(--fs-chrome); letter-spacing: 0.18em; color: var(--warning); }
.qc-improve-note {
  min-height: 5em;
  background: var(--bg);
  color: var(--user-input);
  caret-color: var(--user-input);
  font-family: var(--font-mono);
  font-size: var(--fs-base);
  border: 1px solid var(--phosphor-dim);
  outline: none;
  resize: vertical;
  padding: 8px 10px;
  line-height: 1.45;
  text-shadow: 0 0 1px var(--user-input-glow);
}
.qc-improve-note:focus { border-color: var(--phosphor); }
