/* ==========================================================================
   mulptch — specialization reference
   Hand-written, no framework, no external requests, no webfonts, no build step.

   Implements website/DESIGN-RESEARCH.md. Three decisions govern the sheet:

   1. It is a reference table, not an essay. Facts are tabular, every numeric
      column is tabular-figure, and there is no justification on the page at
      all — the design rationale it used to collapse behind a disclosure is not
      published, so no `<details>` element exists to style.
   2. Light is the default polarity and dark is the media-query override
      (§1.1 — positive polarity read faster in every condition tested).
   3. Contrast is deliberately capped below the ceiling: body ink lands at
      APCA Lc ~90 light / ~-83 dark, not Lc 100+. Past the critical level more
      contrast buys nothing and costs halation (§1.2).
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tokens — light (the default)
   Colours derived from Radix `sand` (warm neutral) and Radix `blue`, pasted as
   literals: the constraint is no external request and no build step, and 24 hex
   values honour both. Two steps are hand-tuned off Radix to land the body pair
   at Lc ~90 instead of Radix's ~100. Measured values are in the comments.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  --bg:           #f7f6f1;  /* sand-1-ish, warmed  */
  --bg-raised:    #fdfcf9;  /* sand-0              */
  --bg-sunken:    #efeee8;  /* sand-3              */
  --bg-zebra:     #f2f1eb;  /* sand-2              */

  --ink:          #3d3b34;  /* on --bg: 10.36:1, APCA Lc 90.5 — body */
  --ink-muted:    #696861;  /* on --bg:  5.02:1, APCA Lc 71.7 — meta cells only */
  --ink-faint:    #82817a;  /* on --bg:  3.61:1, APCA Lc 61.1 — 12px/600 uppercase only */

  --rule:         #dcdad2;  /* decorative hairline */
  --rule-strong:  #bfbcb2;  /* borders that may need to argue 1.4.11 */

  --link:         #15599e;  /* on --bg: 6.57:1, APCA Lc 78.7 */
  --accent-solid: #2f6fb3;  /* rules and swatches only — never text */

  /* Used when a spec has no usable armorHue. */
  --accent-default: #2f6fb3;

  --measure:       62ch;
  --measure-lede:  46ch;
  --shell:         78rem;

  --fs-micro: 0.75rem;
  --fs-meta:  0.8125rem;
  --fs-ui:    0.9375rem;
  --fs-body:  1.0625rem;
  --fs-lede:  1.1875rem;
  --fs-h3:    1.25rem;
  --fs-h2:    1.5rem;
  --fs-h1:    clamp(1.875rem, 1.4rem + 1.9vw, 2.5rem);

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.875rem;
  --space-4: 1.375rem;
  --space-5: 2.25rem;
  --space-6: 3.5rem;
  --space-7: 5.5rem;

  --radius: 4px;

  --font-body: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
               "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;
}

/* --------------------------------------------------------------------------
   Tokens — dark override
   Note the muted and faint tokens go UP, not down: the old dark theme's faint
   token sat at Lc -31.7, barely above APCA's absolute floor, and was carrying
   column labels. "Reduce contrast" means compress the range from both ends.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root {
    --bg:           #1a1a18;  /* lifted off black */
    --bg-raised:    #232320;
    --bg-sunken:    #141412;
    --bg-zebra:     #201f1d;

    --ink:          #dcdad3;  /* on --bg: 12.46:1, APCA Lc -82.8 */
    --ink-muted:    #b7b5ad;  /* on --bg:  8.49:1, APCA Lc -60.9 */
    --ink-faint:    #918f87;  /* on --bg:  5.38:1, APCA Lc -40.7 */

    --rule:         #33322e;
    --rule-strong:  #58564f;

    --link:         #8cbcf0;  /* on --bg: 8.77:1, APCA Lc -62.7 */
    --accent-solid: #8cbcf0;

    --accent-default: #8cbcf0;
  }
}

/* --------------------------------------------------------------------------
   Reset-ish
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* Note: no `overflow-x: hidden` on <html>. It breaks `position: sticky` on the
   header in Chromium, and it is the wrong tool anyway — nothing here is allowed
   to be wider than its container in the first place. Tables get `.table-wrap`,
   text gets `overflow-wrap`, and inline code stops refusing to wrap on phones. */

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  /* Above SC 1.4.12's 1.5 so a user stylesheet forcing 1.5 does not reflow. */
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
  overflow-wrap: break-word;
}

h1, h2, h3, h4 { margin: 0; font-weight: 640; text-wrap: balance; }
h1 { font-size: var(--fs-h1); line-height: 1.15; letter-spacing: -0.011em; }
h2 { font-size: var(--fs-h2); line-height: 1.25; letter-spacing: -0.011em; }
h3 { font-size: var(--fs-h3); line-height: 1.3; }

p, ul, ol, blockquote, table, dl, figure { margin: 0; }

a { color: inherit; }

a:focus-visible,
:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 2px;
  border-radius: 2px;
}

code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  font-variant-numeric: slashed-zero tabular-nums;
  background: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.08em 0.34em;
  white-space: nowrap;
}

/* Every numeric surface gets tabular figures. A no-op on faces that lack the
   feature, free on every face this site actually renders in. */
table, .num, .chain-head {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Shell + skip link
   -------------------------------------------------------------------------- */
.shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2.5rem);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--bg-raised);
  border: 1px solid var(--rule-strong);
  z-index: 10;
}
.skip-link:focus { left: var(--space-3); top: var(--space-3); }

/* --------------------------------------------------------------------------
   Header / nav / footer
   -------------------------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--rule);
  background: var(--bg-raised);
  position: sticky;
  top: 0;
  z-index: 5;
}

.site-header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 3.25rem;
  flex-wrap: wrap;
}

.wordmark {
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  font-size: var(--fs-lede);
}

.site-nav ul {
  display: flex;
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-link {
  color: var(--ink-muted);
  text-decoration: none;
  font-size: var(--fs-ui);
  padding-block: var(--space-2);
  border-bottom: 2px solid transparent;
}
.nav-link:hover { color: var(--ink); }
.nav-link.is-current {
  color: var(--ink);
  border-bottom-color: var(--accent-solid);
}

.site-footer {
  margin-top: var(--space-7);
  border-top: 1px solid var(--rule);
  padding-block: var(--space-5);
  color: var(--ink-muted);
  font-size: var(--fs-ui);
}
.site-footer-tagline {
  color: var(--ink);
  margin-bottom: var(--space-2);
}
.site-footer-note { max-width: var(--measure); }

main { padding-top: var(--space-5); }

/* --------------------------------------------------------------------------
   Prose — kept for the collapsed rationale, which is the only long-form left
   -------------------------------------------------------------------------- */
.prose > * + * { margin-top: 1.25em; }

.prose p,
.prose ul,
.prose ol,
.prose blockquote {
  max-width: var(--measure);
}

.prose ul, .prose ol { padding-left: 1.35em; }
.prose li + li { margin-top: var(--space-2); }

.prose strong { font-weight: 660; color: var(--ink); }
/* Italic is kept for inline emphasis only — never for a multi-line block. */
.prose em { font-style: italic; }

.prose a {
  color: var(--link);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
.prose a:hover { text-decoration-thickness: 2px; }

.prose blockquote {
  border-left: 2px solid var(--rule-strong);
  padding-left: var(--space-4);
  color: var(--ink-muted);
}

/* --------------------------------------------------------------------------
   Tables — the primary element on every page
   -------------------------------------------------------------------------- */
.table-wrap {
  overflow-x: auto;
  max-width: 100%;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: var(--bg-raised);
}

.table-wrap table,
.data-table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--fs-ui);
  line-height: 1.4;
}

.table-wrap th,
.table-wrap td,
.data-table th,
.data-table td {
  text-align: left;
  vertical-align: top;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--rule);
}

.table-wrap thead th,
.data-table thead th {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
  background: var(--bg-sunken);
  white-space: nowrap;
  vertical-align: bottom;
}

.data-table tbody tr:nth-child(even) { background: var(--bg-zebra); }
.table-wrap tbody tr:last-child td { border-bottom: 0; }
.data-table tfoot td,
.data-table tfoot th {
  border-bottom: 0;
  border-top: 1px solid var(--rule-strong);
  background: var(--bg-sunken);
  color: var(--ink-muted);
  font-size: var(--fs-meta);
  font-weight: 600;
}

/* A caption is a table's own label, not a heading — it carries the unit note
   ("k is the falloff exponent") the columns cannot fit. */
.table-caption {
  margin-top: var(--space-2);
  font-size: var(--fs-meta);
  color: var(--ink-muted);
  max-width: var(--measure);
}

.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
th.num { text-align: right; }

/* A header that is a *symbol*, not a word. `k` is the falloff exponent the
   caption's `n^-k` names, and case is meaning in maths: the uppercase treatment
   every other header gets printed it as `K`, which is a different variable from
   the one in the formula directly below the table. Exempted, and set in the
   mono face so it reads as the symbol it is rather than a one-letter word. */
.data-table thead th.col-sym {
  text-transform: none;
  font-family: var(--font-mono);
  letter-spacing: 0;
}
.cell-nil { color: var(--rule-strong); }

/* --------------------------------------------------------------------------
   Micro-type: eyebrows, column labels, tags. Uppercase 12px/600 only — the
   faint token clears APCA's large-text band and nothing smaller.
   -------------------------------------------------------------------------- */
.eyebrow,
.tag,
.toptags-key {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.eyebrow { color: var(--ink-faint); margin-bottom: var(--space-2); }
.eyebrow a { color: var(--ink-muted); text-decoration: none; }
.eyebrow a:hover { color: var(--link); text-decoration: underline; }
.eyebrow-sep { padding-inline: 0.35em; color: var(--rule-strong); }

.tags { display: flex; flex-wrap: wrap; gap: var(--space-1); list-style: none; margin: 0; padding: 0; }
.tag {
  color: var(--ink-muted);
  letter-spacing: 0.04em;
  text-transform: none;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 400;
  white-space: nowrap;
}
.tag + .tag::before { content: "· "; color: var(--rule-strong); }

/* The one aggregate the header still carries. A line, not a boxed cell — with
   Family gone and Chain moved into its own section there is nothing left to
   put in a strip beside it. */
.spec-toptags {
  margin-top: var(--space-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: baseline;
}
.toptags-key { color: var(--ink-faint); white-space: nowrap; }
.toptags-value {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  color: var(--ink-muted);
}

/* --------------------------------------------------------------------------
   Page head
   -------------------------------------------------------------------------- */
.page-head { margin-bottom: var(--space-5); }
.page-lede {
  margin-top: var(--space-3);
  max-width: var(--measure);
  color: var(--ink);
  font-size: var(--fs-lede);
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Accent handling
   --------------------------------------------------------------------------
   `--accent` is set inline from the spec's armorHue and may be anything at all,
   including #ffffff (the archetype value meaning "no tint") and near-black. It
   is therefore never used for text, for a fill, or for a hover state — only for
   a 4px rule beside the <h1> and a 12px swatch in the index. `--accent-line`
   mixes it toward `--rule-strong` so a white hue still draws a visible rule.
   -------------------------------------------------------------------------- */
.spec,
.hue {
  --accent-resolved: var(--accent, var(--accent-default));
  --accent-line: color-mix(in oklab, var(--accent-resolved) 70%, var(--rule-strong));
}

@supports not (color: color-mix(in oklab, red, blue)) {
  .spec, .hue { --accent-line: var(--rule-strong); }
}

/* --------------------------------------------------------------------------
   /classes — the roster table
   -------------------------------------------------------------------------- */
.roster-table td:first-child,
.roster-table th:first-child { width: 2rem; padding-right: 0; }

.hue {
  display: block;
  width: 12px;
  height: 12px;
  margin-top: 0.35em;
  border-radius: 2px;
  background: var(--accent-line);
}

/* The row header cell — every table on the site names its rows in column 1. */
.cell-name { font-weight: 600; white-space: nowrap; }
.cell-name a { color: var(--link); text-decoration: none; }
.cell-name a:hover { text-decoration: underline; }

.roster-table td { color: var(--ink); }
.roster-table .roster-tagline,
.roster-table .roster-resource { color: var(--ink-muted); }
.roster-table .roster-tagline { min-width: 22rem; }

/* --------------------------------------------------------------------------
   /classes/<slug> — spec page
   -------------------------------------------------------------------------- */
.spec-head { margin-bottom: var(--space-5); }

.spec-name {
  /* The armour hue's first of two appearances on the whole site. The rule
     hangs in the shell's gutter so the name still aligns with everything
     below it — an indented h1 reads as a quote, not as a title. */
  border-left: 4px solid var(--accent-line);
  padding-left: var(--space-4);
  margin-left: calc(-1 * var(--space-4) - 4px);
}

.tagline {
  margin-top: var(--space-3);
  max-width: var(--measure-lede);
  font-size: var(--fs-lede);
  line-height: 1.5;
  color: var(--ink);
}

/* --- Parse warnings: loud on purpose. Silent data loss is the failure mode
       that matters, so a document error is a visible notice, not a log line. */
.notice {
  margin-block: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--rule-strong);
  border-left: 4px solid var(--accent-solid);
  border-radius: var(--radius);
  background: var(--bg-sunken);
  font-size: var(--fs-ui);
}
.notice-title { font-weight: 660; margin-bottom: var(--space-2); }
.notice ul { margin: 0; padding-left: 1.35em; color: var(--ink-muted); }

/* --- Sections ------------------------------------------------------------- */
.spec-section { margin-top: var(--space-6); }

.section-heading {
  font-size: var(--fs-h2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--rule-strong);
  margin-bottom: var(--space-3);
  scroll-margin-top: 4.5rem;
}

/* --- Chain ----------------------------------------------------------------
   The heading is the answer to the first two questions — is there a chain, and
   what is it — so the resource's name is set at heading weight and the label
   beside it is not. The cap floats right on a wide viewport and wraps under on
   a phone, because it is the third question, not the first. */
.chain-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}
.chain-label {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.chain-sep { color: var(--rule-strong); font-weight: 400; }
.chain-name { color: var(--ink); }
.chain-cap {
  margin-left: auto;
  font-size: var(--fs-ui);
  font-weight: 400;
  color: var(--ink-muted);
  letter-spacing: 0;
}

/* The five specs that run no resource. A sentence, because "no" is an answer
   to a question the reader is asking, and an omitted section is not. */
.chain-none {
  color: var(--ink-muted);
  font-size: var(--fs-ui);
  max-width: var(--measure);
}

/* --- The spell table -------------------------------------------------------
   One table per spec, two rows per spell: the numbers, then the rules text
   spanning all five columns beneath them. The numeric columns stay pinned
   narrow and `Consumes` takes the slack, so `k` and `Floor` cannot drift
   apart down the page. */
.spell-table .num { width: 4rem; }
.spell-table .spell-data td:nth-child(3) { width: 100%; color: var(--ink); }

/* A `<tbody>` per spell, so the rules separate *spells* and never rows. This
   is the whole reason the group exists: with two rows each and a rule between
   every one of them, no reader could tell which paragraph belonged to which
   name. Inside a group there are no borders at all; between groups there is
   one, and it is the strong token.
   Every selector below descends with `>` on purpose. A spell's rules text may
   itself contain a table — `Misfire` publishes a wheel of six payloads — and a
   loose `.spell-table tbody` would reach inside it and strip the borders off
   somebody else's rows. */
.spell-table > tbody > tr > th,
.spell-table > tbody > tr > td { border-bottom: 0; }
.spell-table > tbody + tbody > tr > th,
.spell-table > tbody + tbody > tr > td { border-top: 1px solid var(--rule-strong); }

/* Zebra by spell, not by row — the default striping would have banded every
   spell's rules text and none of its numbers. */
.spell-table > tbody > tr:nth-child(even) { background: transparent; }
.spell-table > tbody:nth-of-type(even) { background: var(--bg-zebra); }

/* The chain tables still link here, so the landing target is the whole group
   and it says so when you arrive. */
.spell-table > tbody.spell { scroll-margin-top: 4.5rem; }
.spell-table > tbody.spell:target { background: var(--bg-sunken); box-shadow: inset 3px 0 0 var(--accent, var(--link)); }

/* The two rows read as one block: the numbers sit tight above their text. */
.spell-table > tbody > .spell-data > th,
.spell-table > tbody > .spell-data > td { padding-bottom: var(--space-1); }
.spell-table > tbody > .spell-data > .cell-name { color: var(--ink); font-weight: 600; }
.spell-table > tbody > .spell-text > td { padding-top: 0; padding-bottom: var(--space-3); }
.spell-table > tbody > .spell-text > td > .spell-rules,
.spell-table > tbody > .spell-text > td > .spell-effect { margin-top: 0; }

/* The falloff denominator — a gloss on the `k` and `Floor` columns, so it is
   set below the rules text and quieter than it. */
.falloff-note {
  margin-top: var(--space-2);
  font-size: var(--fs-meta);
  color: var(--ink-faint);
  max-width: var(--measure-lede);
}

/* The chain's two sides are two tables sharing one frame, because the amount
   column carries a different fact on each — `Generates` above, `Consumes`
   below — and one column cannot honestly be headed twice. `table-layout: fixed`
   puts the split in the same place on both so the pair still reads as one
   block, and the second table's header band is the divider between them. */
.econ-tables table { table-layout: fixed; }
.econ-tables thead th:first-child { width: 45%; }
.econ-tables table + table thead th { border-top: 1px solid var(--rule-strong); }

/* The `.spell` block, `.spell-name`, `.spell-anchor` and `.kv-inline` rules
   that used to live here are gone with the Spell detail section they styled.
   A spell is a `<tbody>` in the table above now, and its name is plain text —
   there is nowhere left to jump to, so there is no anchor to style. */

/* Authored rules text — the Magic-the-Gathering register. It is a *rule*, not
   an explanation, so it is set apart from the prose around it: a rule down the
   left edge, a slightly tighter measure, and reminder text (the italics the
   author writes) demoted to the muted token so the operative sentence reads
   first. Where no rules text is authored, `.spell-effect` above renders the
   design doc's paragraph exactly as it always has. */
.spell-rules {
  margin-top: var(--space-3);
  padding: var(--space-2) 0 var(--space-2) var(--space-3);
  border-left: 2px solid var(--rule-strong);
  max-width: var(--measure-lede);
  line-height: 1.5;
}
.spell-rules p + p { margin-top: var(--space-2); }
.spell-rules em { color: var(--ink-muted); }
.spell-rules strong { font-weight: 660; }

/* A data table the source document states in markdown — the `Reference table`
   section. There is one on the whole site (Naturalist's reagent products) and
   it is the only intro block that survives, because it is data rather than
   argument. */
.intro-table { margin-bottom: var(--space-3); }

/* The disclosure rules that used to live here are gone with the design
   rationale they wrapped. There is no `<details>` element anywhere on the
   site: with the argument removed nothing is left that is worth hiding. */

/* --- Pager ---------------------------------------------------------------- */
.pager {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--rule);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-size: var(--fs-meta);
}

.pager-link {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  max-width: 45%;
}
.pager-link.is-empty { max-width: 0; }
.pager-next { text-align: right; align-items: flex-end; }

.pager-dir {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}
.pager-prev .pager-dir::before { content: "\2190\00a0"; }
.pager-next .pager-dir::after  { content: "\00a0\2192"; }

.pager-name { color: var(--link); font-size: var(--fs-ui); font-weight: 600; }
.pager-link:hover .pager-name { text-decoration: underline; }

.pager-all { color: var(--ink-muted); text-underline-offset: 0.2em; }
.pager-all:hover { color: var(--ink); }

/* --------------------------------------------------------------------------
   Small screens — the first table column stays pinned while the rest scrolls.
   The table is never collapsed into stacked cards: that destroys the
   comparison the table exists for.
   -------------------------------------------------------------------------- */
@media (max-width: 40rem) {
  :root {
    --fs-body: 1rem;   /* the floor — never below 16px */
    --space-6: 2.75rem;
    --space-7: 4rem;
  }

  /* A long multi-word spell name in `code` must not be able to widen the page. */
  code { white-space: normal; }

  .table-wrap th:first-child,
  .table-wrap td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--bg-raised);
    box-shadow: 1px 0 0 var(--rule);
  }
  .table-wrap .data-table tbody tr:nth-child(even) > :first-child { background: var(--bg-zebra); }
  .table-wrap thead th:first-child { background: var(--bg-sunken); z-index: 2; }

  .roster-table .roster-tagline { min-width: 18rem; }

  /* --- The spell table, one-handed ----------------------------------------
     This is the page's main surface now, so the phone case is the case.

     Two things had to be fixed for the merged shape. First, the rules text
     lives in a `colspan` cell that is also a `td:first-child`, so the sticky
     rule above would have pinned a full-width paragraph to the left edge and
     let it slide under the numbers — it is opted out. Second, that cell is as
     wide as the *table*, which on a phone is wider than the screen: without a
     cap, reading thirty words would mean panning sideways through them. The
     cap is the viewport minus the shell's gutters, so the whole paragraph is
     legible with the table scrolled hard left, which is where it starts. */
  .spell-table > tbody > .spell-text > td {
    position: static;
    box-shadow: none;
    background: transparent;
  }
  .spell-table > tbody > .spell-text > td > * {
    max-width: calc(100vw - 2 * var(--space-4));
  }

  /* The numbers still scroll horizontally, with the spell's name pinned —
     that is the comparison the table exists for and it is kept. Zebra follows
     the group, so the pinned name cell has to match its own group's band. */
  .spell-table > tbody:nth-of-type(even) > .spell-data > :first-child { background: var(--bg-zebra); }
  .spell-table > tbody:nth-of-type(odd) > .spell-data > :first-child { background: var(--bg-raised); }

  /* A payload table nested inside the rules text — `Misfire` publishes six —
     keeps its own scroll container rather than widening its parent cell. */
  .spell-table > tbody > .spell-text .table-wrap { max-width: 100%; }

  /* The shell's gutter is too narrow here for the rule to hang in it. */
  .spec-name { margin-left: 0; padding-left: var(--space-3); border-left-width: 3px; }

  .pager { flex-direction: column; align-items: flex-start; }
  .pager-link, .pager-next { max-width: 100%; text-align: left; align-items: flex-start; }
}

/* --------------------------------------------------------------------------
   Print / reduced motion
   -------------------------------------------------------------------------- */
@media print {
  /* Nothing on the page is collapsed any more, so there is no disclosure to
     force open here — a printed page and a screen page carry the same words. */
  .site-header, .pager, .skip-link { display: none; }
  .table-wrap { overflow: visible; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}
