/* Theme tokens.  The dark palette appears twice below — once under
   prefers-color-scheme (guarded so an explicit light choice wins) and once for
   an explicit data-theme="dark" — because CSS cannot share one declaration
   block between a media query and a selector: keep the two lists identical. */
:root {
  --bg: #f7f6f2; --panel: #ffffff; --ink: #1c1b18; --muted: #6f6a5e;
  --accent: #8a4b2d; --accent-soft: #f2e4da; --border: #e2ddd2;
  --mono-bg: #fbfaf7;                 /* the editable input */
  --out-bg: #f0ece3; --out-border: #d9d2c4;   /* the generated output pane: clearly not an input */
  --good: #2e6e4e; --error: #b03030;   /* error text: 6.3:1 on the panel */
  --pivot: #8a5800;   /* the rounding-error warning in the table: 5.6:1 on the page, 6.0:1 on the panel, 5.8:1 on a hovered row */
  /* C syntax colours (comments ≥ 4.5:1 on --out-bg: 4.9 light, 4.7 dark) */
  --hl-comment: #6a655a; --hl-preproc: #7a4d9c; --hl-string: #9a5b1e;
  --hl-number: #1f5f9f; --hl-keyword: #8a4b2d; --hl-type: #2e6e4e; --hl-fn: #2a4f8f;
  /* input polynomial colours */
  --in-num: #1f5f9f; --in-var: #8a4b2d;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #191817; --panel: #211f1d; --ink: #ece8e0; --muted: #9d968a;
    --accent: #d69a71; --accent-soft: #3a2c22; --border: #383430;
    --mono-bg: #171614;
    --out-bg: #2a2724; --out-border: #403b35;
    --good: #7fc9a2; --pivot: #dfa065; --error: #ef8a7a;   /* 6.7:1 on the dark panel */
    --hl-comment: #98917f; --hl-preproc: #c39bde; --hl-string: #e0a568;
    --hl-number: #8fb9ea; --hl-keyword: #d69a71; --hl-type: #7fc9a2; --hl-fn: #9db7e8;
    --in-num: #8fb9ea; --in-var: #d69a71;
  }
}
:root[data-theme="dark"] {
  --bg: #191817; --panel: #211f1d; --ink: #ece8e0; --muted: #9d968a;
  --accent: #d69a71; --accent-soft: #3a2c22; --border: #383430;
  --mono-bg: #171614;
  --out-bg: #2a2724; --out-border: #403b35;
  --good: #7fc9a2; --pivot: #dfa065; --error: #ef8a7a;   /* 6.7:1 on the dark panel */
  --hl-comment: #98917f; --hl-preproc: #c39bde; --hl-string: #e0a568;
  --hl-number: #8fb9ea; --hl-keyword: #d69a71; --hl-type: #7fc9a2; --hl-fn: #9db7e8;
  --in-num: #8fb9ea; --in-var: #d69a71;
}
* { box-sizing: border-box; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 16px/1.55 Charter, Georgia, 'Times New Roman', serif;
}
.wrap { max-width: 60rem; margin: 0 auto; padding: 2.5rem 1.25rem 4rem; }
/* visually hidden, read by assistive tech: the sub-headings, the table caption,
   the full column names on phones */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.nowrap { white-space: nowrap; }   /* inline formulas never line-break */
/* day / night: one button shows the theme it would switch TO — the moon while
   the page is light, the sun while it is dark (system preference or explicit) */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.1rem; height: 2.1rem; padding: 0; cursor: pointer;
  border: 1px solid var(--border); border-radius: 7px; background: var(--panel); color: var(--ink);
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.theme-toggle .sun { display: none; }
:root[data-theme="dark"] .theme-toggle .sun { display: inline; }
:root[data-theme="dark"] .theme-toggle .moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: inline; }
  :root:not([data-theme="light"]) .theme-toggle .moon { display: none; }
}

/* two-column header: title + intro left, "Read the paper" card right; stacks when narrow */
header {
  display: flex; flex-wrap: wrap; gap: 1.25rem 2.5rem; align-items: flex-start;
  justify-content: space-between; margin-bottom: 1.75rem;
}
header .head-main { flex: 1 1 24rem; min-width: 0; }
header h1 { font-size: 1.9rem; margin: 0 0 .35rem; letter-spacing: -.01em; }
header .sub { color: var(--muted); margin: 0; max-width: 44rem; }
header .sub a { color: var(--accent); }
/* the header's right column: paper card above, GitHub + the day / night toggle
   on one line below */
.header-links .row { display: flex; gap: .45rem; justify-content: flex-end; align-items: center; }
header .sub .ours { color: var(--ink); font-style: normal; font-weight: 700; }
.header-links {
  flex: 0 1 21rem; display: flex; flex-direction: column; gap: .55rem;
}
.paper-card {
  display: flex; gap: .7rem; align-items: flex-start;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  padding: .8rem .95rem; color: inherit; text-decoration: none;
  font-size: .85rem; line-height: 1.45;
}
.paper-card:hover { border-color: var(--accent); }
.paper-card .doc-icon { color: var(--accent); flex: none; margin-top: .1rem; }
.paper-card b { display: block; margin-bottom: .1rem; }
.paper-card .paper-txt > span { color: var(--muted); }
.github-link {
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--ink); text-decoration: none; font: 700 .82rem/1.2
    system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  padding: .38rem .58rem; border: 1px solid var(--border); border-radius: 7px;
  background: var(--panel);
}
.github-link:hover { border-color: var(--accent); color: var(--accent); }
.github-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.github-stars {
  min-width: 2.4rem; margin-left: .12rem; padding-left: .52rem;
  border-left: 1px solid var(--border); display: inline-flex; align-items: center;
  justify-content: center; gap: .28rem; color: var(--muted); text-align: center;
  font-variant-numeric: tabular-nums;
}

/* the single card: input → field / method rows → tabs + pane → stats line */
.card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 10px; padding: 1.25rem 1.4rem; margin-bottom: 1.25rem;
}

/* heading row: the label left, example chips + degree stepper right */
.head-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: .4rem 1rem; margin-bottom: .55rem;
}
label.head { display: block; font-weight: 700; }
.ex-row { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .4rem .9rem; margin-left: auto; }

/* example chips, regenerated at the chosen degree */
.examples { display: inline-flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.examples .chip {
  display: inline-flex; align-items: center;
  border: 1px solid var(--border); border-radius: 999px; background: var(--mono-bg);
  padding: .14rem .7rem; color: var(--accent); cursor: pointer; font: inherit; font-size: .88rem;
  line-height: inherit; user-select: none;
}
.examples .chip:hover { border-color: var(--accent); }
.examples .chip:focus-visible, .monic-toggle:focus-visible, .degree button:focus-visible,
.seg button:focus-visible, .views button:focus-visible, .subopts .gear:focus-visible,
button.copy:focus-visible, button.download:focus-visible, button.share:focus-visible,
button.cancel:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.seg button:focus-visible { outline-offset: -2px; }   /* inside the clipped pill group */
.examples .chip .katex { font-size: 1em; line-height: 1; }
.monic-toggle {
  border: 1px solid var(--border); border-radius: 999px; background: transparent;
  padding: .14rem .7rem; color: var(--muted); cursor: pointer; font: inherit;
  font-size: .82rem; line-height: inherit;
}
.monic-toggle:hover { border-color: var(--accent); color: var(--accent); }
.monic-toggle.on { border-color: var(--accent); background: var(--mono-bg); color: var(--accent); font-weight: 700; }

/* degree chooser (− N +) next to the chips */
.degree { display: inline-flex; align-items: center; gap: .1rem; }
.degree button {
  width: 1.55rem; height: 1.55rem; border: 1px solid var(--border); border-radius: 6px;
  background: transparent; color: var(--ink); cursor: pointer; font: inherit; line-height: 1;
}
.degree button:not([aria-disabled="true"]):hover { border-color: var(--accent); color: var(--accent); }
.degree button[aria-disabled="true"] { opacity: .45; cursor: default; }   /* at the end of the field's range */
.degree .deg-n { color: var(--muted); font-size: .88rem; padding: 0 .4rem; white-space: nowrap; }

/* The polynomial input: a transparent textarea stacked over a highlighted
   backdrop.  Both share font, padding, border width, wrapping and width, so
   the painted tokens sit exactly under the (invisible) typed text; the
   textarea keeps the caret, selection, focus ring and the resize handle. */
.poly-edit { position: relative; }
.poly-edit .poly-hl, textarea#poly-in {
  font: 15px/1.5 ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  letter-spacing: normal; tab-size: 4;
  padding: .7rem .8rem; border: 1px solid var(--border); border-radius: 8px;
  white-space: pre-wrap; overflow-wrap: break-word; word-break: normal; hyphens: none;
  margin: 0;
}
textarea#poly-in {
  display: block; position: relative; z-index: 1;
  width: 100%; min-height: 4.2rem; resize: vertical;
  color: transparent; caret-color: var(--ink); background: transparent;
}
textarea#poly-in:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }   /* ≥ 3:1 ring */
textarea#poly-in::selection { background: rgba(138, 75, 45, .28); }
.poly-edit .poly-hl {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  color: var(--ink); background: var(--mono-bg); border-color: transparent;
}
.poly-hl .in-num { color: var(--in-num); }
.poly-hl .in-var { color: var(--in-var); }

/* control rows: the button groups start at the card's left edge, aligned with
   each other and with the view tabs; the small-caps legend sits to their right */
.controls { display: flex; flex-wrap: wrap; gap: .6rem .8rem; align-items: center; margin-top: .9rem; }
.controls > .lbl, .subopts .lbl {
  font-size: .72rem; letter-spacing: .09em; text-transform: uppercase; color: var(--muted);
}
.controls > .lbl { margin-left: .15rem; }
.controls > .lbl.tight { display: none; }   /* no room on the pills' line (measured in ui.js) */
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.seg button {
  border: 0; background: transparent; color: var(--muted);
  padding: .45rem .9rem; font: inherit; cursor: pointer;
}
.seg button sup { font-size: .7em; }
.seg button.on { background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.seg button:disabled { opacity: .45; cursor: default; }

/* field chooser: one pill group per registry group (exact ℚ ℝ · Mersenne
   primes 2⁶¹−1 2⁸⁹−1 2¹²⁷−1 · binary fields GF(2³²) GF(2⁶⁴) GF(2¹²⁸)), each led
   by a muted group caption.  Labels are short and the pills tight so that all
   three groups plus the FIELD legend share one line at the card's 60rem width
   (measured headless in Chromium: groups 756px + legend 36px of the 873px available). */
.field-groups { display: inline-flex; flex-wrap: wrap; gap: .5rem .5rem; align-items: center; }
.field-groups .seg .grp {
  display: inline-flex; align-items: center; align-self: stretch;
  padding: 0 .45rem 0 .55rem; border-right: 1px solid var(--border);
  font-size: .66rem; letter-spacing: .07em; text-transform: uppercase; color: var(--muted);
  white-space: nowrap; cursor: default;
}
.field-groups .seg { flex-wrap: wrap; max-width: 100%; }   /* narrow screens: a group wraps inside its pill */
.field-groups .seg button { padding: .42rem .5rem; white-space: nowrap; }

#error { color: var(--error); margin-top: .8rem; white-space: pre-wrap; overflow-wrap: anywhere; }
#error:empty { margin: 0; }   /* the live region stays mounted; empty it takes no room */
/* under the input: the slow-degree warning */
.input-hint { margin-top: .45rem; color: var(--muted); font-size: .85rem; line-height: 1.4; }
/* the job status line (an always-mounted live region): a job running with no
   output to dim — spinner, "compiling…", Cancel — or the note after a Cancel */
#job-status { margin-top: .9rem; color: var(--muted); font-style: italic; }
#job-status:empty { margin: 0; }
.busy-row { display: flex; align-items: center; gap: .55rem; }
.busy-row .spinner { margin: 0; }
button.cancel {
  border: 1px solid var(--border); border-radius: 6px; background: var(--panel);
  color: var(--accent); cursor: pointer; font: inherit; font-size: .8rem; font-style: normal;
  padding: .12rem .6rem;
}
button.cancel:hover { border-color: var(--accent); }
/* in the pane corner Cancel appears only once a recompile has run for a moment
   (a quick one would flash it for ~30 ms) */
@keyframes appear { from { visibility: hidden; } to { visibility: visible; } }
.pane-actions button.cancel { animation: appear .01s linear .2s both; }

/* a numeric method (Knuth–Eve, Pan) still computing in its own worker: a
   small ring on its chip, its table row and — if selected — the pane */
.spinner {
  display: inline-block; width: .75em; height: .75em; margin-left: .4em; vertical-align: -.05em;
  border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation: none; border-top-color: var(--muted); } }
.seg.methods button.pending { color: var(--muted); }
table.cmp td.pending { color: var(--muted); font-style: italic; }
table.cmp td.pending .spinner { margin-left: 0; margin-right: .3em; }
.pending-pane { padding: 1.2rem 1.1rem; color: var(--muted); font-style: italic; }
.pending-pane .spinner { margin: 0 .5em 0 0; }

/* method chips */
.seg.methods { flex-wrap: wrap; display: inline-flex; }
.seg.methods button { display: inline-grid; }
.seg.methods button > span, .seg.methods button::after { grid-area: 1 / 1; }
.seg.methods button::after {
  content: attr(data-label); font-weight: 700; visibility: hidden; pointer-events: none;
}

/* Output section: the view tabs are drawn as attached tabs whose baseline IS
   the pane's top border (the active tab paints over it in the pane colour). */
.out { margin-top: 1.1rem; }
.viewbar {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 0 1rem; border-bottom: 1px solid var(--out-border); margin: 0;
}
.views { display: flex; gap: .25rem; }
.views button {
  border: 1px solid transparent; border-bottom: 0; border-radius: 8px 8px 0 0;
  background: none; cursor: pointer; margin-bottom: -1px;
  color: var(--muted); font: inherit; font-size: .82rem; letter-spacing: .06em;
  text-transform: uppercase; padding: .38rem .85rem .42rem;
}
.views button:hover { color: var(--ink); }
.views button.on {
  color: var(--ink); font-weight: 700;
  background: var(--out-bg); border-color: var(--out-border);
  border-bottom: 1px solid var(--out-bg);
}
/* the display menu: a gear at the right end of the view bar; its dropdown
   (one labelled radio group per sub-option: form, constants) hangs under it
   over the pane's top-right corner */
.subopts { position: relative; display: flex; align-items: center; font-size: .82rem; color: var(--muted); padding-bottom: .35rem; }
.subopts .gear {
  display: inline-flex; align-items: center; justify-content: center; width: 1.7rem; height: 1.7rem;
  cursor: pointer; border-radius: 999px; border: 1px solid transparent; color: var(--muted);
  background: none; font: inherit; line-height: 1;
}
.subopts .gear:hover, .subopts .gear[aria-expanded="true"] { color: var(--ink); }
.subopts .gear[aria-expanded="true"] { border-color: var(--border); background: var(--panel); }
.subopts .menu {
  position: absolute; top: calc(100% - .1rem); right: 0; z-index: 5; min-width: 11rem;
  display: flex; flex-direction: column; gap: .5rem; padding: .55rem .6rem;
  background: var(--panel); border: 1px solid var(--border); border-radius: .5rem;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .14);
}
.subopts .strip { display: flex; flex-direction: column; gap: .1rem; }
.subopts .lbl { font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; padding: 0 .35rem .15rem; }
.subopts .menu button {
  display: flex; align-items: center; gap: .5rem; text-align: left; width: 100%;
  cursor: pointer; padding: .22rem .45rem; border-radius: .35rem; border: 1px solid transparent;
  color: var(--ink); user-select: none; background: none; font: inherit; line-height: inherit;
}
.subopts .menu button::before {   /* the radio mark: a ring, filled for the chosen option */
  content: ""; width: .6rem; height: .6rem; border-radius: 999px; box-sizing: border-box;
  border: 1.5px solid var(--muted); flex: none;
}
.subopts .menu button.on { color: var(--accent); }
.subopts .menu button.on::before { border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 2px var(--panel); }
.subopts .menu button:disabled { opacity: .5; cursor: default; }
.subopts .menu button:not(:disabled):hover, .subopts .menu button:focus-visible { background: var(--accent-soft); outline: none; }

/* the pane wrapper anchors Copy + Download to the pane's top-right corner */
.pane-wrap { position: relative; }
.pane-actions {
  position: absolute; top: .55rem; right: .55rem;
  z-index: 2; display: flex; gap: .35rem;
}
button.copy, button.download {
  border: 1px solid var(--out-border); border-radius: 6px; background: var(--out-bg);
  color: var(--accent); cursor: pointer; font: inherit; font-size: .8rem;
  padding: .12rem .6rem;
}
button.copy:hover, button.download:hover { border-color: var(--accent); }
button.download:disabled { opacity: .55; cursor: wait; }

/* the generated output: pane colour distinct from the input, no top border
   (the tab row's line is the top edge), square top corners under the tabs */
.chain, .graph-pane {
  background: var(--out-bg); border: 1px solid var(--out-border); border-top: 0;
  border-radius: 0 0 8px 8px; margin: 0;
}
pre.chain {
  padding: 1rem 1.1rem; overflow-x: auto;
  font: 14px/1.65 ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}
pre.chain .op { color: var(--accent); }
pre.chain .cm { color: var(--muted); }
pre.chain .none { color: var(--muted); font-style: italic; }

/* Mathematical view: KaTeX cells in a real alignment table. The canonical
   plain-text chain remains behind Copy and the operation counter; this is only
   its typeset presentation. The action buttons float over the unused top-right
   corner rather than reserving a blank row above the equations. */
.math-chain {
  padding: 1rem 1.1rem 1.15rem; overflow-x: auto;
  color: var(--ink); -webkit-overflow-scrolling: touch;
}
.math-table {
  border-collapse: separate; border-spacing: 0 .24rem;
  /* Keep the three alignment columns at their intrinsic widths. `min-width:
     100%` makes HTML tables distribute spare pane width between the columns,
     so short chains acquire huge gaps around `=` while longer chains do not. */
  width: max-content; margin-inline: 0;
}
.math-table td, .math-table th { white-space: nowrap; vertical-align: baseline; }
.math-equation td { padding-block: .06rem; }
.math-lhs { min-width: 2.4rem; padding: 0 .25rem 0 .2rem; text-align: right; color: var(--accent); }
.math-rel { padding: 0 .55rem; text-align: center; color: var(--muted); }
.math-rhs { padding: 0 .4rem 0 .05rem; text-align: left; }
.math-chain .math-var { color: var(--in-var); }
.math-chain .math-const { color: var(--in-num); }
.math-chain .katex { font-size: 1.08em; }
.math-equation.result td { padding-top: .42rem; }
.math-equation.result .math-lhs { font-weight: 700; }
.math-annotation {
  margin-left: 1rem; color: var(--muted);
  font: italic .78rem/1.3 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.math-section th {
  padding: .62rem .25rem .12rem; text-align: left; color: var(--muted); font-weight: 400;
}
.math-section:first-child th { padding-top: 0; }
.math-section-rule {
  display: inline-block; width: 1.35rem; margin: 0 .55rem .18rem 0;
  border-top: 1px solid var(--out-border); vertical-align: middle;
}
.math-section-rule:last-child { margin: 0 0 .18rem .55rem; }
.math-note td {
  padding: .25rem; color: var(--muted);
  font: italic .82rem/1.45 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.math-gap td { height: .5rem; }
@media (max-width: 540px) {
  .math-chain { padding-inline: .75rem; }
  .math-chain .katex { font-size: .98em; }
  .math-rel { padding-inline: .35rem; }
}

/* C syntax highlighting (js/highlight.js) */
.hl-comment { color: var(--hl-comment); font-style: italic; }
.hl-preproc { color: var(--hl-preproc); }
.hl-string  { color: var(--hl-string); }
.hl-number  { color: var(--hl-number); }
.hl-keyword { color: var(--hl-keyword); font-weight: 700; }
.hl-type    { color: var(--hl-type); }
.hl-fn      { color: var(--hl-fn); }

/* graph view: the SVG is sized to content; a graph up to ~1.35× the pane shrinks
   to fit (ui.js GraphPane, class `fit`), a wider one scrolls sideways behind a
   right-edge fade (class `more` on the wrapper while more lies past the edge)
   and the legend says so */
.graph-pane-wrap { position: relative; }
.graph-pane { padding: .6rem; overflow-x: auto; overflow-y: hidden; }
.graph-pane svg { display: block; max-width: none; }
.graph-pane.fit svg { width: 100%; height: auto; }
.graph-pane-wrap.more::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 3.5rem; pointer-events: none;
  background: linear-gradient(to right, transparent, var(--out-bg) 85%); border-radius: 0 0 8px 0;
}
.graph-legend .lg-scroll { color: var(--accent); }
.graph-pane .none { color: var(--muted); font-style: italic; padding: .4rem .5rem; }
.graph-legend {
  display: flex; flex-wrap: wrap; gap: .3rem 1.2rem; margin-top: .5rem;
  color: var(--muted); font-size: .8rem;
}
.graph-legend i {
  display: inline-block; font-style: normal; text-align: center; vertical-align: middle;
  margin-right: .3rem; font: 700 12px/18px ui-monospace, Menlo, monospace;
}
.graph-legend .lg-mul { width: 18px; height: 18px; border-radius: 50%; background: var(--accent); color: var(--panel); }
.graph-legend .lg-add { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--ink); color: var(--ink); line-height: 15px; }
.graph-legend .lg-const { padding: 0 6px; border: 1px solid var(--border); border-radius: 5px; background: var(--out-bg); color: var(--ink); }
.graph-legend .lg-dash { width: 22px; height: 0; border-top: 2px dashed var(--muted); }
.graph-legend .lg-k { color: var(--ink); }

/* comparison table at the bottom of the card: one centered table; the
   selected method is indicated only with ordinary bold text */
.foot {
  display: flex; flex-wrap: wrap; gap: .6rem 1.5rem; align-items: flex-start;
  justify-content: space-between; margin: .85rem 0 0;
  color: var(--muted); font-size: .9rem;
}
.cmp-wrap { flex: 1 1 22rem; min-width: 0; overflow-x: auto; }
table.cmp { border-collapse: collapse; width: 100%; max-width: 40rem; margin-inline: auto; font-size: .88rem; color: var(--ink); }
table.cmp th, table.cmp td {
  padding: .26rem .65rem; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums;
}
table.cmp th {
  font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; font-weight: 400;
  color: var(--muted); padding-bottom: .2rem;
}
table.cmp th.m, table.cmp td.m { text-align: left; padding-left: .5rem; }
table.cmp tbody tr { cursor: pointer; }
table.cmp tbody tr:hover td, table.cmp tbody tr:focus-visible td { background: var(--mono-bg); }
table.cmp tbody tr:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
table.cmp td.warn { color: var(--pivot); }             /* measured rounding error above 1e-6 */
table.cmp .rel-err { color: var(--muted); font-size: .78rem; margin-left: .2rem; font-weight: 400; }
table.cmp td.warn .rel-err { color: inherit; font-weight: 600; }
table.cmp tbody tr.on td { font-weight: 700; }
table.cmp tbody tr.off { cursor: default; color: var(--muted); }
table.cmp tbody tr.off:hover td { background: none; }
table.cmp td.na { text-align: left; }
table.cmp .why { font-size: .78rem; white-space: normal; }
table.cmp a.ref { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--muted); }
table.cmp a.ref:hover { color: var(--accent); border-bottom-color: var(--accent); }
table.cmp .ref-no { color: var(--muted); font-size: .62rem; margin-left: .15rem; font-weight: 400; }
/* under the table: what the columns count, then each row's own note */
.cmp-caption, .cmp-notes {
  max-width: 40rem; margin: .6rem auto 0; color: var(--muted); font-size: .8rem; line-height: 1.45;
}
.cmp-caption { padding: 0 .5rem; }
.cmp-notes { padding-left: 1.4rem; }
.cmp-notes li { margin-bottom: .15rem; }
.cmp-notes b { color: var(--ink); font-weight: 600; }
/* the references behind the methods, numbered as in the method cells */
.refs {
  max-width: 40rem; margin: .7rem auto 0; padding-left: 1.4rem;
  color: var(--muted); font-size: .8rem; line-height: 1.4;
}
.refs li { padding-left: .15rem; margin-bottom: .12rem; }
.refs a { color: inherit; text-decoration: none; }
.refs a:hover { color: var(--accent); text-decoration: underline; }
table.cmp th .abbr { display: none; }
@media (max-width: 480px) {                 /* phones: compact headers + padding, the wrapper still scrolls if needed */
  table.cmp { font-size: .82rem; }
  table.cmp th, table.cmp td { padding: .24rem .35rem; }
  table.cmp td.m { white-space: normal; }   /* long method names (Rabin–Winograd) may wrap */
  table.cmp th .full {                        /* still read out in full; sighted users see "mult." */
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
  }
  table.cmp th .abbr { display: inline; }
}
button.share {
  display: inline-flex; align-items: center; gap: .4rem;
  border: 1px solid var(--border); border-radius: 8px; background: var(--panel);
  color: var(--accent); cursor: pointer; font: inherit; font-size: .85rem;
  padding: .28rem .75rem;
}
button.share:hover { border-color: var(--accent); }


/* stale-while-revalidate: while a new job runs (or a parse error stands, or
   the last job was cancelled) the previous output stays mounted and dims
   briefly (the delay hides the dim on fast compiles) — every view of it: the
   pane, the method chips / dropdown, the comparison table, the phone stats line */
#out, #methods, #method-picker, #footer-stats, #stats-line { transition: opacity 0.12s ease; }
#out.stale, #methods.stale, #method-picker.stale, #footer-stats.stale, #stats-line.stale {
  opacity: 0.55; transition: opacity 0.15s ease 0.12s;
}


/* ---- phones (≤ 640px; ui.js shares the breakpoint) --------------------------
   Header: the title, a short intro and Paper / GitHub ★ n links with the desktop
   icons (the desktop intro and paper card are hidden).  Input card: label +
   three example chips on one line, the auto-growing input, then Field and
   Method as two dropdowns.  Output card: underline tabs with the display-menu
   gear at the right (the form group in the math view — the constants group is
   presentedState's job on phones — and the ℚ C view's constants group; ui.js
   mounts no gear without a group) — then a static right-aligned
   Copy + Share row at the top of the pane — not floating: a floated corner
   covered the end of mid-width equation rows, which do not scroll — and the
   pane body (rows wider than the pane scroll sideways, as in the C and graph
   panes), then a stats line.  Secondary controls are padded to ≥ 32px tall.
   The comparison table folds into a collapsed "Compare methods" card. */
@media (max-width: 640px) {
  .wrap { padding: 1.3rem .85rem 3rem; }
  header { margin-bottom: 0; gap: 0; }
  header h1 { font-size: 1.85rem; line-height: 1.15; margin-bottom: .45rem; }
  header .sub, .header-links { display: none; }
  .intro-compact { margin-bottom: 1.1rem; }
  .intro-compact .sub { display: block; font-size: .98rem; line-height: 1.45; }
  .quick-links { display: flex; align-items: center; gap: 1.4rem; margin-top: .6rem; font-size: 1.05rem; }
  .quick-links a { display: inline-flex; align-items: center; gap: .4rem; color: var(--accent); text-decoration: none; font-weight: 600; }
  .quick-links .theme-toggle { margin-left: auto; width: 2.4rem; height: 2.4rem; }
  .quick-links .stars {
    display: inline-flex; align-items: center; gap: .25rem; margin-left: .2rem; padding-left: .5rem;
    border-left: 1px solid var(--border); color: var(--muted); font-weight: 400; font-size: .92rem;
    font-variant-numeric: tabular-nums;
  }
  .pane-actions button.share { background: var(--panel); padding: .3rem .65rem; font-size: .85rem; }

  .card { padding: .95rem .9rem 1rem; margin-bottom: .9rem; border-radius: 12px; }
  .head-row { margin-bottom: .75rem; gap: .4rem .4rem; flex-wrap: nowrap; }
  label.head { font-size: 1rem; white-space: nowrap; }
  .ex-row { margin-left: auto; gap: .35rem; flex-wrap: nowrap; }
  .examples { gap: .3rem; flex-wrap: nowrap; }
  .examples .chip { padding: .3rem .45rem; font-size: .82rem; white-space: nowrap; }
  /* ≥ 16px in form fields: iOS Safari stops auto-zooming the page on focus */
  .poly-edit .poly-hl, textarea#poly-in { font-size: 16px; padding: .65rem .75rem; }
  textarea#poly-in { min-height: 3.6rem; }

  .pickers { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin-top: 1rem; }
  .picker { display: flex; flex-direction: column; gap: .3rem; min-width: 0; color: var(--muted); font-size: .98rem; }
  .picker select {
    width: 100%; min-width: 0; font: inherit; font-size: 16px; color: var(--ink);
    background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
    padding: .55rem 2rem .55rem .75rem; appearance: none; -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%236f6a5e' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right .6rem center; background-size: 1rem;
    text-overflow: ellipsis;
  }
  .picker select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
  .controls > .lbl { flex-basis: 100%; order: -1; margin-left: 0; }   /* busy row etc. */

  /* output card: tabs + the display-menu gear on one line, the pane attached below */
  .out-card { padding: 0 0 .85rem; overflow: hidden; }
  .out-card .out { margin-top: 0; }
  .viewbar { padding: .1rem .8rem 0; border-bottom: 1px solid var(--out-border); gap: .1rem .5rem; flex-wrap: nowrap; }
  .views { gap: 0; flex-shrink: 0; }   /* the tabs never wrap or shrink ("C code" stays one line) */
  .views button {
    border: 0; border-bottom: 2px solid transparent; border-radius: 0; margin: 0 .8rem -1px 0;
    text-transform: none; letter-spacing: 0; font-size: .98rem; padding: .55rem .05rem .45rem;
    white-space: nowrap;
  }
  .views button.on { background: none; border-color: var(--accent); color: var(--accent); }
  .subopts { padding: 0 0 .4rem; font-size: .8rem; margin-left: auto; min-width: 0; }
  .subopts .gear { width: 2rem; height: 2rem; }      /* a finger-sized target beside the tabs */
  .subopts .menu button { padding: .35rem .5rem; }
  .pane-wrap { margin: 0; }
  .out-card .chain, .out-card .graph-pane { border-left: 0; border-right: 0; border-radius: 0; }
  /* Copy / Share / Cancel: a static right-aligned row inside the pane, above its body */
  .pane-actions {
    position: static; justify-content: flex-end; padding: .45rem .7rem 0; background: var(--out-bg);
  }
  .pane-actions:empty { display: none; }
  button.copy { background: var(--panel); padding: .3rem .65rem; font-size: .85rem; }
  .out-card .pane-actions button.cancel { background: var(--panel); padding: .3rem .65rem; font-size: .85rem; }
  pre.chain { padding: .3rem .9rem .9rem; }
  .math-chain { padding: .3rem .8rem .9rem; }
  .pending-pane { padding-top: .5rem; }
  .graph-pane { padding-top: .3rem; }
  .math-chain .katex { font-size: 1.12em; }
  .math-table { border-spacing: 0 .3rem; }
  .math-lhs { min-width: 2rem; padding-left: 0; }
  .math-annotation { display: block; margin: .1rem 0 0; }
  .graph-legend { padding: 0 .8rem; }
  .stats-line { padding: .75rem .9rem 0; color: var(--muted); font-size: .95rem; }

  /* comparison card: a native disclosure, collapsed by default */
  .cmp-card { padding: 0; }
  .cmp-card summary {
    display: flex; justify-content: space-between; align-items: center; cursor: pointer;
    padding: .85rem 1rem; font-weight: 700; font-size: 1.1rem; list-style: none;
  }
  .cmp-card summary::-webkit-details-marker { display: none; }
  .cmp-card summary::after {
    content: ''; width: .55rem; height: .55rem; margin: -.3rem .3rem 0 0;
    border: solid var(--muted); border-width: 0 2px 2px 0; transform: rotate(45deg);
    transition: transform .15s ease;
  }
  .cmp-card[open] summary { border-bottom: 1px solid var(--border); }
  .cmp-card[open] summary::after { transform: rotate(-135deg); margin-top: .25rem; }
  .cmp-card .foot { margin: 0; padding: .5rem .5rem .8rem; }
  .cmp-card .refs { padding-left: 1.2rem; font-size: .8rem; }
  .cmp-card .cmp-caption, .cmp-card .cmp-notes { font-size: .8rem; }
  .cmp-card table.cmp { max-width: none; }
}
