/* ============================================================================
   RETRIVIUM — components
   Load after tokens.css and base.css.

   Naming: block / block--modifier / block__element.
   Class names here are PRODUCTION names. The approved comp in
   reference/retrivium-design-v1.html uses short prototype names; the mapping
   table is in COMPONENTS.md. Build against these, not against the comp.
   ============================================================================ */

/* ============================================================================
   1 · APP SHELL
   The session surface is phone-shaped at every viewport. It never exceeds
   --app-max, because the cue has to survive a phone and a session that looks
   different on desktop is a different repetition (§9.2, context consistency).
   ============================================================================ */
.app-shell {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--app-max);
  margin-inline: auto;
  min-height: 100dvh;
  background: var(--color-surface);
  color: var(--color-text);
}

/* Framed presentation — used on Records/Map/marketing surfaces, never in the PWA. */
.app-shell--framed {
  min-height: 31rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-app);
  box-shadow: var(--shadow-2), var(--shadow-hairline);
  overflow: hidden;
}

.page-shell {
  width: min(100% - 2rem, var(--page-max));
  margin-inline: auto;
  padding-block: var(--space-6);
}
.page-header {
  display: grid;
  grid-template-columns: minmax(8rem, 2fr) minmax(0, 7fr) minmax(0, 3fr);
  gap: var(--space-5);
  align-items: start;
}
.page-header > div { grid-column: 2; }
.page-header h1 { margin-top: var(--space-2); font-size: clamp(var(--text-2xl), 4vw, 2.4rem); }
.page-actions { max-width: 30rem; margin: var(--space-8) auto 0; }

.map-tracks { display: grid; gap: var(--space-5); margin-top: var(--space-8); }
.map-track {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  background: var(--color-surface);
  overflow: hidden;
}
.map-track > summary {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  cursor: pointer;
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
}
.map-track[open] > summary { border-bottom: 1px solid var(--color-border); }
.map-strand { padding: var(--space-5); border-top: 1px solid var(--color-border-soft); }
.map-strand:first-of-type { border-top: 0; }
.map-strand h2 { margin-top: var(--space-1); font-size: var(--text-xl); }
.map-nodes {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.map-node {
  min-width: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface-sunk);
  overflow: hidden;
}
.map-node__edges {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px dashed var(--color-border);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-subtle);
  overflow-wrap: anywhere;
}
.map-node__link { display: grid; gap: var(--space-1); padding: var(--space-3); text-decoration: none; }
.map-node__link:hover strong { text-decoration: underline; }
.map-node__id, .map-node__link > span:last-child { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--color-text-subtle); }
.map-node--rung-1, .map-node--rung-2, .map-node--rung-3 { border-color: var(--color-state); }
.map-node--rung-4, .map-node--rung-5, .map-node--rung-6 { background: var(--color-state-wash); border-color: var(--color-state); }
.map-node--lost { border-color: var(--color-loss); }
.map-node__loss { color: var(--color-loss) !important; }

.concept-record { margin-block: var(--space-5); min-height: calc(100dvh - (2 * var(--space-5))); }
.evidence-heading { margin-top: var(--space-6); }
.dependency-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); }
.dependency-link { display: block; margin-top: var(--space-2); font-family: var(--font-mono); font-size: var(--text-sm); }

.criterion-card {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(8rem, 2fr) minmax(0, 5fr);
  gap: var(--space-5);
  align-items: center;
  margin-top: var(--space-8);
  padding: var(--space-6);
  border: 1px solid var(--color-state);
  border-radius: var(--radius-xl);
  background: var(--color-state-wash);
}
.criterion-card__value {
  font-family: var(--font-mono);
  font-size: 2.5rem;
  font-weight: var(--weight-bold);
  color: var(--color-state);
  text-align: center;
}
.time-records {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-8);
}
.time-records h2 { grid-column: 1 / -1; }
.time-card { padding: var(--space-5); border: 1px solid var(--color-border); border-radius: var(--radius-xl); background: var(--color-surface); }
.time-card dl { display: grid; gap: var(--space-3); margin-top: var(--space-4); }
.time-card dl div { display: flex; justify-content: space-between; gap: var(--space-3); border-bottom: 1px solid var(--color-border-soft); }
.time-card dt { color: var(--color-text-muted); }
.time-card dd { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

@media (max-width: 60rem) {
  .page-header { grid-template-columns: 8rem minmax(0, 1fr); }
  .page-header > div { grid-column: 2; }
  .map-nodes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .time-records { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 36rem) {
  .page-shell { width: min(100% - 1rem, var(--page-max)); padding-block: var(--space-3); }
  .page-header { grid-template-columns: 1fr; }
  .page-header > div { grid-column: 1; }
  .page-header .logo { display: none; }
  .map-strand { padding: var(--space-3); }
  .map-nodes, .dependency-list, .time-records, .criterion-card { grid-template-columns: minmax(0, 1fr); }
  .criterion-card__value { text-align: left; }
  .concept-record { margin-block: 0; min-height: 100dvh; border-radius: 0; }
}

.app-status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.55rem var(--space-5) 0.35rem;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  color: var(--color-text-subtle);
}

/* ============================================================================
   2 · BANDS
   Exactly one band is live per screen state. The rest recede but stay
   readable — they hold information the learner may need to check, and
   opacity below ~.55 pushes body text under AA.
   ============================================================================ */
.logo { display: inline-flex; align-items: center; gap: 0.6em; }
.logo__word {
  text-transform: uppercase;
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wordmark);
  line-height: 1;
}
.logo--sm .logo__word { font-size: var(--text-md); }
.logo--md .logo__word { font-size: var(--text-xl); }
.logo--lg .logo__word { font-size: var(--text-2xl); }
.logo__lift { color: var(--color-action); }

.band {
  padding: var(--band-inset);
  border-top: 1px solid var(--color-border-soft);
  transition: opacity var(--dur-base) var(--ease-out);
}
.band:first-of-type { border-top: 0; }

.band--live  { background: var(--color-surface-sunk); }

/* Receded by TOKEN REMAP, not by opacity.
   Opacity was the obvious implementation and it is the wrong one: at the .6
   needed to read as receded, body text lands at 2.8:1. Shifting the text down
   one step of the ramp instead reads as just as quiet and stays above 4.5:1,
   because the floor (--color-text-subtle) is itself an AA colour. */
.band--quiet {
  --color-text: var(--color-text-muted);
  --color-text-muted: var(--color-text-subtle);
  color: var(--color-text);
}

/* After commit the prompt stops being the demand and becomes the thing the
   correction refers to. It stays pinned so feedback is never correlated from
   memory — this is the §10.2 requirement, and it is not optional. */
.band--ref {
  opacity: 0.78;
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--color-surface);
}

/* ============================================================================
   3 · ACTION BAR
   One primary action per screen state, pinned to the bottom, and the only
   garnet thing on screen. Making it structural is what makes the rule
   impossible to violate by accident.
   ============================================================================ */
.action-bar {
  margin-top: auto;
  padding: var(--action-inset);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  position: sticky;
  bottom: 0;
  z-index: var(--z-action);
}

.btn {
  display: block;
  width: 100%;
  text-align: center;
  padding: 0.82rem var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--color-action);
  color: var(--color-action-text);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  letter-spacing: -0.006em;
  box-shadow: var(--shadow-1);
  min-height: 44px;                       /* touch target floor */
  transition: filter var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:hover  { filter: brightness(1.07); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .5; cursor: not-allowed; filter: none; transform: none; }

/* Ghost — for actions that are not the session's forward motion
   (Open the map, Done, Back to the item). */
.btn--ghost {
  background: none;
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  box-shadow: none;
}
.btn--ghost:hover { border-color: var(--color-text-muted); filter: none; }

/* State — for stepping the trace. Never for a session action. */
.btn--state { background: var(--color-state); color: var(--color-state-text); }

.btn-link {
  display: block;
  width: 100%;
  margin-top: var(--space-2);
  text-align: center;
  font-size: var(--text-md);
  color: var(--color-text-muted);
  text-decoration: underline;
  text-decoration-color: var(--color-border);
  text-underline-offset: 3px;
  min-height: 32px;
}
.btn-link:hover { color: var(--color-text); text-decoration-color: var(--color-text-muted); }

.auth-form {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}
.field-label {
  display: block;
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-semi);
  color: var(--color-text-muted);
}
.flash { margin-top: var(--space-3); }

/* ============================================================================
   4 · TYPE ROLES
   Each of these owns one size from the scale. Do not mix.
   ============================================================================ */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}

/* The if–then plan. The largest type in the product — larger than any number.
   That is the hierarchy the evidence supports (d = 0.65 vs everything else). */
.plan {
  margin-top: var(--space-2);
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  font-weight: var(--weight-semi);
  text-wrap: balance;
}
.plan em { font-style: normal; color: var(--color-action); }

/* The item prompt. Same size as .plan — they never appear together. */
.prompt {
  font-size: var(--text-2xl);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-display);
  font-weight: var(--weight-bold);
  text-wrap: balance;
}

/* The session's learning goal, and capability statements at close. */
.goal {
  margin-top: var(--space-2);
  font-size: var(--text-base);
  line-height: var(--leading-snug);
}

/* Capability statement on the concept page. */
.capability {
  font-size: var(--text-xl);
  line-height: var(--leading-snug);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-tight);
}

.note {
  margin-top: var(--space-2);
  font-size: var(--text-md);
  line-height: var(--leading-normal);
  color: var(--color-text-muted);
}
.note strong, .note b { color: var(--color-text); font-weight: var(--weight-semi); }

/* Inline code inside prose. */
.mono { font-family: var(--font-mono); font-size: 0.92em; }

/* ============================================================================
   5 · CODE
   Code is the most legible element on the page. Syntax classes live in code.css.
   ============================================================================ */
.code-box {
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--color-code-bg);
  border-radius: var(--radius-lg);
  overflow-x: auto;
}

/* ============================================================================
   6 · ANSWER INPUT
   No peek-before-commit path exists. The field is monospace because what is
   typed is usually a value, not prose.
   ============================================================================ */
.field {
  width: 100%;
  margin-top: var(--space-3);
  padding: 0.78rem 0.85rem;
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  font-family: var(--font-mono);
  font-size: var(--text-base);
  min-height: 44px;
}
.field::placeholder { color: var(--color-text-subtle); }
.field--committed {
  border-color: var(--color-text-muted);
  background: var(--color-surface-sunk);
}
.field[readonly] { cursor: default; }

.practice-form {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}
.choice-field {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-3) 0 0;
  padding: 0;
  border: 0;
}
.choice-option {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  cursor: pointer;
}
.choice-option:has(input:checked) {
  border-color: var(--color-state);
  background: var(--color-state-wash);
}
.choice-option input { margin-top: 0.22em; accent-color: var(--color-state); }
.parsons-field {
  display: grid;
  gap: var(--space-3);
  margin: var(--space-3) 0 0;
  padding: 0;
  border: 0;
}
.parsons-field legend {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.parsons-slot {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: var(--space-3);
  align-items: center;
}
.parsons-slot label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.parsons-select {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  padding: 0.65rem 2.2rem 0.65rem 0.75rem;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}
.parsons-select:focus-visible { outline: 2px solid var(--color-state); outline-offset: 2px; }
.reveal-pending { visibility: hidden; }

/* Optional pre-commit confidence tap. One tap, removable if it slows sessions
   without producing calibration insight. */
.confidence { display: flex; gap: 0.35rem; margin-top: var(--space-2); }
.confidence button {
  flex: 1 1 0;
  padding: 0.32rem 0.3rem;
  min-height: 32px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.confidence button:hover { border-color: var(--color-text-muted); color: var(--color-text); }
.confidence button[aria-pressed="true"] {
  border-color: var(--color-state);
  color: var(--color-state);
  font-weight: var(--weight-semi);
}

/* ============================================================================
   7 · BLOCK PLAN
   Progress is shown at BLOCK granularity only. There is no item count and no
   shrinking remainder — nothing to sprint toward at the end of a session.
   ============================================================================ */
.block-plan { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: var(--space-2); }
.block-chip {
  padding: 0.14rem 0.55rem;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-pill);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  color: var(--color-text-subtle);
}
.block-chip--done { border-color: var(--color-state); color: var(--color-state); }
.block-chip--now  { border-color: var(--color-text); color: var(--color-text); font-weight: var(--weight-semi); }

/* ============================================================================
   8 · CONSISTENCY STRIP
   A trailing window, never a chain. There is no state here that can "break",
   and no repair to buy. Four day-states, each distinguishable without colour.
   Always give the strip role="img" and an aria-label with the counts.
   ============================================================================ */
.consistency { display: flex; gap: 0.22rem; margin-top: var(--space-2); }
.consistency__day {
  flex: 1 1 0;
  height: 0.5rem;
  border: 1px solid var(--color-text-subtle);
  border-radius: var(--radius-pill);
}
.consistency__day--cue  { background: var(--color-state); border-color: var(--color-state); }
.consistency__day--off  {                       /* done, outside the cue window */
  background: linear-gradient(to right, var(--color-state) 0 50%, transparent 50% 100%);
  border-color: var(--color-state);
}
.consistency__day--miss { background: none; }   /* hollow. Never red. Never a warning. */
.consistency__day--rest { border-style: dashed; } /* planned rest is first-class */

/* ============================================================================
   9 · RUNG LADDER
   Six rungs. State is encoded three ways — fill, hatch, and numeral — so it
   survives greyscale, colour-blindness, and a screenshot.
   The ladder MUST be able to render a lost rung. A display that only rises
   is a fiction.
   ============================================================================ */
.rung-ladder { display: flex; gap: 0.18rem; margin-top: var(--space-3); }
.rung {
  flex: 1 1 0;
  height: 1.7rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--color-text-subtle);
}
.rung--held {
  background: var(--color-state);
  border-color: var(--color-state);
  color: var(--color-state-text);
}
.rung--lost {
  border-color: var(--color-loss);
  color: var(--color-loss);
  background: repeating-linear-gradient(
    135deg,
    light-dark(rgba(142,36,56,.22), rgba(232,139,156,.22)) 0 2px,
    transparent 2px 6px
  );
}
.rung--target { border-style: dashed; border-color: var(--color-text-muted); color: var(--color-text-muted); }
.rung--asserted {                            /* manual override — never counts (§4.2 r6) */
  border-style: dotted;
  color: var(--color-text-subtle);
  background: none;
}

/* Retrievability sparkline wrapper. The line must be able to go down, and the
   failed-check marker is drawn in --color-loss. */
.retrievability { margin-top: var(--space-3); color: var(--color-text-muted); }
.retrievability svg { width: 100%; height: auto; }

/* ============================================================================
   10 · EVIDENCE LEDGER
   The refusals matter more than the passes — they are the reason the claim
   above them means anything. Render both lists, always.
   ============================================================================ */
.evidence { margin-top: var(--space-3); }
.evidence__row {
  display: grid;
  grid-template-columns: 0.9rem 1fr;
  gap: var(--space-2);
  align-items: baseline;
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--color-border-soft);
  font-size: var(--text-sm);
}
.evidence__glyph { font-family: var(--font-mono); color: var(--color-counted); }
.evidence__row--refused { color: var(--color-text-subtle); }
.evidence__row--refused .evidence__glyph { color: var(--color-text-subtle); }
.evidence__family { font-family: var(--font-mono); }
.evidence__reason { font-style: italic; }

/* ============================================================================
   11 · VERDICT AND FEEDBACK
   Task-directed, never person-directed. The struck-through committed answer
   beside the real one makes the DISCREPANCY the object of attention.
   ============================================================================ */
.verdict {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}
.verdict--incorrect { color: var(--color-loss); }
.verdict--correct   { color: var(--color-text); }   /* no colour. No celebration. */
.verdict__glyph { font-family: var(--font-mono); font-size: 1.05rem; }

.answer-pair { display: flex; flex-wrap: wrap; gap: var(--space-6); margin-top: var(--space-2); }
.answer-pair > div { min-width: 0; }
.answer-pair__label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}
.answer-pair__value {
  font-family: var(--font-mono);
  font-size: var(--text-xl);
  font-weight: var(--weight-semi);
  font-variant-numeric: tabular-nums;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.answer-pair__value--given {
  color: var(--color-loss);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.answer-pair__value--actual { color: var(--color-state); }

/* Elaborated feedback. All four terms are required by the content linter:
   goal · discrepancy · why-it-failed · next-step. Correctness-only is a defect. */
.feedback dt {
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--color-text-subtle);
}
.feedback dd {
  margin-top: 0.2rem;
  font-size: var(--text-lg);
  line-height: var(--leading-normal);
}

.misconception {
  margin-top: var(--space-3);
  padding: 0.42rem 0.65rem;
  border: 1px solid var(--color-loss);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-loss);
}

.inline-correction {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.inline-correction h2 { margin-top: var(--space-1); font-size: var(--text-lg); }

.session-outcome { margin-top: var(--space-4); font-size: var(--text-lg); }
.capability-list { display: grid; gap: var(--space-2); margin-top: var(--space-2); }
.capability-list li { padding-left: var(--space-3); border-left: 2px solid var(--color-state); }
.capability-list__lost { margin-top: var(--space-5); }
.capability-list--lost li { border-left-color: var(--color-loss); color: var(--color-text-muted); }
.level-grid { display: grid; gap: var(--space-2); margin-top: var(--space-2); }
.level-grid div { display: grid; gap: var(--space-1); }
.level-grid span { color: var(--color-text-muted); font-size: var(--text-md); }
.xp-boundary { margin-top: var(--space-1); font-variant-numeric: tabular-nums; }
.next-check-heading { margin-top: var(--space-4); }

/* ============================================================================
   12 · HINT LADDER
   Four ordered levels. Level 1 is a QUESTION, not an answer. Level 4 is always
   reachable and always ends the attempt as aided — state the cost, never
   punish the choice.
   ============================================================================ */
.hint-ladder {
  margin-top: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.hint {
  display: grid;
  grid-template-columns: 1.4rem 1fr auto;
  gap: var(--space-2);
  align-items: baseline;
  padding: 0.42rem 0.6rem;
  border-top: 1px solid var(--color-border-soft);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}
.hint:first-child { border-top: 0; }
.hint__level { font-family: var(--font-mono); color: var(--color-text-subtle); }
.hint__cost  { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--color-text-subtle); }
.hint--taken { background: var(--color-surface-sunk); color: var(--color-text); }
.hint--terminal .hint__cost { color: var(--color-attention); }

/* ============================================================================
   13 · SCAFFOLD PANEL (worked example / explanation)
   Support fades as a function of demonstrated rung. At rung 4+ this element is
   REMOVED FROM THE DOM — do not render it hidden, do not render it collapsed.
   A panel you can re-open is a panel you will re-open.
   ============================================================================ */
.scaffold-panel {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  background: var(--color-code-bg);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--leading-normal);
  color: var(--color-text-muted);
}
.scaffold-panel__subgoal { display: block; }
.scaffold-panel__blank { color: var(--color-action); }

/* ============================================================================
   14 · TRACE PLAYER
   The entire motion budget. Nothing else in RETRIVIUM animates.
   At rung 1 the learner predicts each next state before it is revealed, so the
   step control is the interaction — never autoplay into a learning surface.
   ============================================================================ */
.trace {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-2), var(--shadow-hairline);
  overflow: hidden;
}
.trace__head {
  display: flex; flex-wrap: wrap; gap: var(--space-3);
  justify-content: space-between; align-items: center;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface-sunk);
}
.trace__body { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.05fr); }
@media (max-width: 56rem) { .trace__body { grid-template-columns: minmax(0,1fr); } }
.trace__code {
  padding: var(--space-5);
  background: var(--color-code-bg);
  border-right: 1px solid var(--color-border);
}
@media (max-width: 56rem) {
  .trace__code { border-right: 0; border-bottom: 1px solid var(--color-border); }
}
.trace__stage { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }

.trace__sequence { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.trace__item {
  padding: 0.25rem 0.55rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunk);
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-text-muted);
  transition: background var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.trace__item--past { opacity: 0.52; }
.trace__item--now {
  background: var(--color-state);
  border-color: var(--color-state);
  color: var(--color-state-text);
  transform: translateY(-2px);
}

.trace__memo { display: flex; flex-direction: column; gap: var(--space-2); }
.trace__entry {
  display: grid; grid-template-columns: 1fr auto;
  align-items: center; gap: var(--space-3);
  padding: 0.42rem 0.7rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface-sunk);
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  transition: border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out);
}
.trace__entry--hit { border-color: var(--color-state); background: var(--color-state-wash); }
.trace__key   { color: var(--color-code-string); }
.trace__value { font-variant-numeric: tabular-nums; font-weight: var(--weight-semi); }

.trace__caption {
  padding-left: var(--space-3);
  border-left: 2px solid var(--color-state);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text-muted);
  min-height: 3.4rem;
}
.trace__caption strong { color: var(--color-text); font-weight: var(--weight-semi); }
.trace__caption .discard { color: var(--color-action); }

.trace__controls {
  display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
  padding: var(--space-3) var(--space-5) var(--space-5);
}
.trace__position {
  margin-inline-start: auto;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-subtle);
  font-variant-numeric: tabular-nums;
}
.trace__btn {
  padding: 0.42rem 0.9rem;
  min-height: 36px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  color: var(--color-text-muted);
  transition: border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.trace__btn:hover { border-color: var(--color-text-muted); color: var(--color-text); }
.trace__btn--primary {
  background: var(--color-state);
  border-color: var(--color-state);
  color: var(--color-state-text);
}

.fresh-start {
  margin: 0 0 var(--space-4);
  color: var(--color-action);
  font-size: var(--text-xl);
  font-weight: var(--weight-semi);
}

.consistency {
  padding: var(--space-6);
  border-block: 1px solid var(--color-border);
}

.consistency__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

.consistency__dots {
  display: grid;
  grid-template-columns: repeat(14, minmax(0, 1fr));
  gap: var(--space-2);
  margin-block: var(--space-4);
}

.consistency__dot {
  aspect-ratio: 1;
  border: 1px solid var(--color-border-strong);
  border-radius: 50%;
}

.consistency__dot--complete { background: var(--color-state); border-color: var(--color-state); }
.consistency__dot--open { background: transparent; }
.consistency__dot--rest { border-style: dashed; opacity: 0.4; }

@media (max-width: 44rem) {
  .consistency__header { display: block; }
}
