/*
 * Math flow contract — SSOT for how KaTeX behaves inside question markup.
 * Rendered by shared code on both pages:
 *   - lib/quiz-pure.js                        (exam tab + admin learner preview)
 *   - features/quiz/quiz-topic-modal.js       (quiz modal)
 *   - features/gym/stat-modal-templates.js    (history/stat review modals)
 * Must load eagerly on every page that renders question markup (index.html, admin.html).
 * Do NOT fold into the lazy gym CSS bundle (core/route-css.js Tier 1) — quiz and
 * history modals render without that bundle, and admin.html never loads it.
 *
 * A KaTeX box is inline-block, so a formula wider than the card cannot wrap and
 * keeps growing sideways. The quiz and exam shells are `overflow: hidden`
 * (.quiz-modal-content), so anything that escapes is not merely ugly — it is
 * cut off with no way to read the rest. Every block that can hold a formula
 * therefore scrolls its own overflow instead of leaking it to an ancestor.
 *
 * The three surfaces are listed together rather than in their own feature files
 * so the behaviour cannot drift apart; the rule matches whether or not the gym
 * bundle that styles .exam-* / .pwcr-* has loaded.
 *
 * overflow-y must be `hidden`, not `visible`: with overflow-x: auto the spec
 * computes a visible overflow-y to auto, which would add a stray vertical
 * scrollbar. Same pairing the KaTeX fallback uses for .katex-display.
 */
.quiz-q-text,
.quiz-bubble-body,
.exam-q-text,
.exam-explanation p,
.pwcr-q,
.pwcr-explain-body {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  /* A formula scrolled to its end must not hand the gesture to the modal
     behind it and start a page swipe. */
  overscroll-behavior-x: contain;
}

/*
 * Explanation blocks — the output of lib/explain-pure.js, rendered identically
 * by every surface that shows an `explain` field.
 *
 * Spacing is margin-based rather than flex `gap` on purpose: `.ex-math` scrolls
 * its own overflow, and a column flex parent shrinks children before it agrees
 * to scroll (the defect scripts/css-flex-shrink-guard.js exists to catch).
 * Colour and font are inherited from whichever card is hosting the block, so
 * this file never states a second palette for the same text.
 */
.ex-p,
.ex-h,
.ex-list,
.ex-math,
.ex-rule { margin: 0 0 6px; }
.ex-body > .ex-step + .ex-step { margin-top: 10px; }
.ex-step > :last-child { margin-bottom: 0; }
.ex-h { font-weight: 800; }
.ex-list { padding-inline-start: 1.35em; }
.ex-list > li + li { margin-top: 4px; }
.ex-rule { border: 0; border-top: 1px solid currentColor; opacity: 0.22; }
.ex-img { max-width: 100%; border-radius: 8px; display: block; }

/* A lifted derivation owns its line. It still scrolls rather than overflowing
   (same pairing as the blocks above), and sets flush left instead of centred:
   a step reads as a continuation of the sentence above it, not as a plate. */
.ex-math {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.ex-math .katex-display { margin: 0.35em 0; text-align: left; }
.ex-math .katex-display > .katex { text-align: left; }

/* Choice rows are flex containers; a flex item defaults to min-width: auto and
   so refuses to shrink below its content. Without this a single long formula
   widens the whole row and pushes the label glyph off the card. */
.quiz-choice-text,
.exam-choice > div:last-child {
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
