/* ===========================================================================
 * passage-item.css — canonical visual for PassageItem.
 * ===========================================================================
 * Single source of truth for .pi-* classes — .pi-eyebrow / .pi-stem /
 * .pi-choices / .pi-choice / .pi-letter / .pi-choice-main / .pi-choice-text
 * / .pi-elim / state classes.
 *
 * Replaces the per-surface scoped duplicates that previously lived in
 * subjects/reading/styles.css (.reading-screen .pi-*). The diagnostic-ui.css
 * .diag-passage-region .pi-* block stays as a surface-specific override
 * (the diagnostic genuinely uses a different visual treatment per the
 * passage-item-spec).
 *
 * Uses global tokens directly (--ink-*, --accent-*, --surface, --radius)
 * rather than the .reading-screen scoped --rd-* aliases — the canonical
 * applies anywhere PassageItem is mounted, not just under .reading-screen.
 * Loaded BEFORE surface stylesheets in index.html so per-surface overrides
 * (where they exist) win on specificity.
 * ========================================================================= */

.pi-item {
  font-family: var(--font-ui, var(--font-display));
  color: var(--ink);
}

/* --- Eyebrow chip above each question stem (q.type) ------------------- */
.pi-eyebrow {
  display: inline-block;
  padding: 4px 10px;
  background: var(--accent-coral-tint);
  color: var(--accent-coral);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  margin-bottom: 12px;
}

/* --- Question stem ----------------------------------------------------- *
 * A question inside a testlet is the SAME question served alone, so its stem
 * carries no typography of its own: the text blocks inside it are `.mc-stem`
 * (McItem's block renderer — see PassageItem.jsx) and inherit body type from
 * the item, exactly as a standalone McItem does. Setting display type here is
 * what turned a three-block vocab-in-context stem into three bold headings.
 * This rule keeps only the box: colour, spacing and wrapping. */
.pi-stem {
  color: var(--ink);
  margin-bottom: 14px;
  text-wrap: pretty;
}
/* stemBlocks stream: space between blocks (text or figure) */
.pi-stem--blocks > * + * { margin-top: 10px; }

/* --- Choice list + rows ------------------------------------------------ */
.pi-choices {
  display: grid;
  gap: 8px;
}

/* Row wrapper — positioning context for the eliminate ×, which is a SIBLING
 * of the choice button (a button may not nest inside a button) overlaid on the
 * slot the button reserves for it. Also carries the states that must cover the
 * whole row (the eliminated dim, the shake) so the × moves and fades with its
 * choice exactly as it did when it was nested inside it.
 * `--pi-elim-inset` = the button's right padding + border width; it tracks any
 * .pi-choice padding override through the same cascade. */
.pi-choice-row {
  position: relative;
  /* Single-item grid so the button still stretches to the full row box it got
     as a direct grid item of .pi-choices. */
  display: grid;
  --pi-elim-inset: 14px;
}
/* D5 — de-emphasis via the compliant ink pair .is-dimmed uses, never `opacity`
 * (0.5 measured 2.98:1 at 14px in the state the student works in). */
.pi-choice-row.is-eliminated .pi-choice {
  color: var(--ink-soft);
  border-color: var(--ink-5);
}
.pi-choice-row.is-eliminated .pi-letter { background: var(--ink-5); }

.pi-choice {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: start;
  gap: 12px;
  width: 100%;
  padding: 12px;
  background: var(--surface);
  border: 2px solid var(--ink-10);
  border-radius: var(--radius);
  cursor: pointer;
  /* Named + motion vars (study D5) — see mc-item.css. */
  transition: background var(--dur-quick, 120ms) ease, border-color var(--dur-quick, 120ms) ease,
    color var(--dur-quick, 120ms) ease, box-shadow var(--dur-quick, 120ms) ease;
  -webkit-tap-highlight-color: transparent;
  text-align: left;
  font: inherit;
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
}
/* Hover is keyed off the ROW, not the button: the eliminate × sits over the
 * button but is no longer inside it, so hovering the × must still light the
 * choice border the way it did when the × was a child. */
.pi-choice-row:hover .pi-choice:not(:disabled) { border-color: var(--ink-30); }
.pi-choice:disabled { cursor: default; }

.pi-choice.is-selected:not(.is-correct):not(.is-wrong) {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.pi-choice.is-correct {
  background: var(--accent-sage-tint);
  border-color: var(--accent-sage);
  color: var(--accent-sage-ink);
}
.pi-choice.is-wrong {
  background: var(--danger-bg);
  border-color: var(--danger);
  color: var(--danger);
}
/* The eliminated dim lives on .pi-choice-row (it must take the × with it). */
/* Struck, but still tappable — the tap puts the choice back (study B17). */
.pi-choice.is-eliminated {
  cursor: pointer;
}
.pi-choice.is-eliminated .pi-choice-text {
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  text-decoration-color: var(--ink-30);
}
/* De-emphasis WITHOUT opacity: fading text and background toward each
 * other landed the unselected choices at 3.77:1 at the exact moment the
 * student re-reads them (consultant-3). Mute via an explicit compliant
 * pair instead — ink-soft text (5.6:1), receded border, lightened chip. */
.pi-choice.is-dimmed { color: var(--ink-soft); border-color: var(--ink-5); }
.pi-choice.is-dimmed .pi-letter { background: var(--ink-5); }

/* --- Letter chip ------------------------------------------------------- */
.pi-letter {
  align-self: center;
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 8px;
  background: var(--ink-10);
  color: var(--ink-70);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono, var(--font-ui));
}
.pi-choice.is-selected:not(.is-correct):not(.is-wrong) .pi-letter {
  background: var(--accent);
  color: #fff;
}
.pi-choice.is-correct .pi-letter {
  background: var(--accent-sage);
  color: #fff;
}
.pi-choice.is-wrong .pi-letter {
  background: var(--danger);
  color: #fff;
}

/* --- Choice text container -------------------------------------------- */
.pi-choice-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  font-family: var(--font-body, var(--font-display));
  font-size: 14px;
  line-height: 1.4;
  color: inherit;
  text-wrap: pretty;
}
.pi-choice-text { display: block; }

/* --- Eliminate button --------------------------------------------------
 * A real <button> (out of the tab order — see PassageItem.jsx); the UA
 * appearance/font reset keeps the shipped look. It is a SIBLING of the choice
 * button, absolutely positioned over the .pi-elim-spacer slot the choice
 * reserves for it in its right-edge grid column. */
.pi-elim {
  appearance: none;
  -webkit-appearance: none;
  font-family: inherit;
  line-height: 1;
  align-self: center;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--ink-30);
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 700;
  transition: background var(--dur-quick, 120ms) ease, border-color var(--dur-quick, 120ms) ease,
    color var(--dur-quick, 120ms) ease;
  -webkit-tap-highlight-color: transparent;
}

/* Overlay the slot the choice button reserves for it, landing on the exact
   pixels the old nested grid cell occupied. Also the containing block for the
   ::after hit box below. */
.pi-choice-row > .pi-elim {
  position: absolute;
  right: var(--pi-elim-inset);
  top: 50%;
  transform: translateY(-50%);
}

/* 44px hit box for the eliminator: visual circle stays 28px, the touch
   area grows via an invisible overlay (hit-tests to the owner element). */
.pi-elim::after { content: ''; position: absolute; inset: -8px; }

/* --- Reveal adornment (✓ / ✗) ------------------------------------------
 * The graded glyph the host renders into the right-edge column via
 * renderRightAdornment (runner.jsx emits `mc-verdict-adorn pi-verdict-adorn`
 * so one span lands correctly in either renderer's stylesheet). Same footprint
 * as .pi-elim-spacer, so a row's height and text column are identical whether
 * it is holding the ×, the glyph, or nothing. `currentColor` inherits the
 * row's own semantic ink — sage on the key, danger on the student's wrong
 * pick — so the glyph can never disagree with the fill it sits on. */
.pi-verdict-adorn {
  width: 28px;
  height: 28px;
  align-self: center;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  color: currentColor;
}

/* The reserved slot itself — the ×'s exact footprint, so row height and the
   text column are unchanged by the un-nesting. */
.pi-elim-spacer {
  width: 28px;
  height: 28px;
  align-self: center;
  flex-shrink: 0;
}

.pi-elim:hover {
  border-color: var(--ink-soft);
  color: var(--ink);
}
/* D6 — the student's own working mark sits on the neutral ink ramp, never on
 * danger/danger-bg (the app's "you got this wrong" pair, 2.00:1 effective). */
.pi-elim.is-on {
  background: var(--ink-10);
  border-color: var(--ink-soft);
  color: var(--ink);
}

/* --- Inline why panel after reveal ------------------------------------ */
/* The reveal panel is McItem's `.mc-why-block` (study B1/A17) — one design,
   one verdict head, one reading treatment for every item kind. The `.pi-why*`
   rules that used to live here are gone with it. */

/* --- Line-numbered passage: centre the fixed measure -------------------- *
 * A line-numbered passage is hard-wrapped at a fixed measure (~420px). In a
 * pane wider than that (stacked layout: iPad portrait, narrow desktop windows)
 * the block hung against the left edge with a dead region beside it.
 *
 * The centring must not move what usePbFit measures (subjects/reading/ui.jsx):
 * it reads .pb-linefit's own box (clientWidth + a ResizeObserver) and each
 * row's span rect. So .pb-linefit stays full-pane-width — only its single grid
 * TRACK is content-sized, and minmax(0, min-content) clamps that track to the
 * pane. Wider pane → track = the measure, centred; narrower → track = the pane,
 * i.e. today's boxes exactly, so the gutter/flow verdict and the shrink
 * threshold are untouched. The observed box never changes width, so no
 * measure↔resize feedback is possible.
 * min-content rather than fit-content is what makes a NON-numbered sibling
 * block (an ACT front-matter line) wrap to the same measure instead of the
 * pane — the nowrap rows set the track, every block shares it.
 * The FLOW presentation is excluded: it has no nowrap rows, so a min-content
 * track would collapse it to one word per line, and flowing text fills the
 * pane anyway. */
.passage-pane .pb-linefit:not(.pb-linefit-flow) {
  display: grid;
  grid-template-columns: minmax(0, min-content);
  justify-content: center;
}
/* The track is sized from the same intrinsic text width the fit hook then
 * measures against, so the two can land on a rounding tie and read as an
 * overflow. 3px of slack inside the row's own box keeps rect > ink; it is
 * inside the box, so the constrained case (track = pane) keeps the shipped
 * threshold to the pixel. */
.passage-pane .pb-linefit:not(.pb-linefit-flow) .pb-fixed-line { padding-right: 3px; }
