/* Design tokens: the only place colours are written as hex (DESIGN.md "Type And Color"). One type scale, a 4px spacing
   grid, a neutral page with one accent, review status in the Nature BPG palette (ggsci NPG "nrc"). */
:root {
  color-scheme:light;
  /* Type: one family (the system stack), sizes 12-32px with their line heights, weights 400/500/600. */
  --font:-apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  --font-mono:ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --fs-12:12px; --lh-12:16px;   /* units, axis ticks, captions' data line, counts in filter options, record key */
  --fs-13:13px; --lh-13:18px;   /* table cells, chips, record labels, figure captions, filter options */
  --fs-14:14px; --lh-14:20px;   /* UI text, record values, record section headings, tabs */
  --fs-16:16px; --lh-16:24px;   /* Guide body, record values-table numbers */
  --fs-18:18px; --lh-18:24px;   /* Stats section headings */
  --fs-20:20px; --lh-20:24px;   /* counts band numbers, record title, Stats headline line 2 */
  --fs-24:24px; --lh-24:28px;   /* Stats page title */
  --fs-28:28px; --lh-28:32px;   /* Stats headline key numbers on phones */
  --fs-32:32px; --lh-32:36px;   /* Stats lead figure; headline key numbers' top on tablets */
  --fs-40:40px; --lh-40:44px;   /* Stats headline key numbers */
  /* Spacing: a 4px grid. Radius 4px for controls, 0 for bars. */
  --sp-1:4px;
  --sp-2:8px;
  --sp-3:12px;
  --sp-4:16px;
  --sp-5:24px;
  --sp-6:32px;
  --sp-7:48px;
  --radius:4px;
  /* Layout: header 56px, counts band 64px, sidebar and record columns (DESIGN.md "Layout"). */
  --header-h:56px;
  --band-h:64px;
  --gutter:24px;
  --sidebar-w:288px;
  --rail-w:48px;
  --panel-w:480px;
  /* Neutrals (WCAG 2.x on white: text 16.5:1, text-2 9.5:1, muted 5.8:1). */
  --text:#172120;
  --text-2:#3d4845;
  --muted:#5c6865;
  --line:#d3dcd7;
  --line-soft:#e7ece9;
  --line-strong:#aebdb7;      /* control outlines */
  --bg:#ffffff;
  --surface-2:#f6f8f7;
  --surface-3:#fafbfa;        /* every other table row */
  --hover:#f1f6f4;
  /* What a visitor picks or acts on (links, buttons, the focus ring, selection) is ink, a neutral that carries no data
     meaning (round 14: the teal accent, Human-checked's green and Read from the paper's dark cyan read as one teal family,
     so green now means agreement alone). Links are told from text by a quiet underline, never by a hue. */
  --accent:#172120;           /* 16.5:1; white on it 16.5:1 */
  --accent-hover:#3d4845;
  --accent-tint:#eef1f0;      /* text on tint 15.0:1 */
  --accent-line:#aebdb7;      /* underlines and control outlines */
  /* The Nature BPG palette (ggsci npg "nrc"), each colour written once, with the darker shade of the same hue that its
     text, tick or ring takes where the colour itself is too light on white (WCAG 2.x: text 4.5:1, marks and rings 3:1).
     Marks (dots, squares, the "!" disc) are opaque; figures fill at 60% (#RRGGBB99) with a 1px opaque outline. One
     meaning per colour, the same everywhere (DESIGN.md "Type And Color", the colour table). */
  --bpg-navy:#3C5488;         /* 7.5:1  Accepted */
  --bpg-salmon:#F39B7F;       /* 2.1:1  Not confirmed (ring 3.9:1) */
  --bpg-slate:#8491B4;        /* 3.1:1  Not checked (tick 4.6:1) */
  --bpg-deep-red:#DC0000;     /* 5.2:1  Disputed */
  --bpg-cyan:#4DBBD5;         /* 2.2:1  CatLog's reading of the paper (ring 3.0:1, text 5.5:1) */
  --bpg-green:#00A087;        /* 3.3:1  agreement: Same number, human-checked (text 5.6:1) */
  --bpg-mint:#91D1C2;         /* 1.7:1  the same number in another form (ring 3.0:1) */
  --bpg-brown:#7E6148;        /* 5.7:1  Different number */
  --bpg-red:#E64B35;          /* 3.9:1  a correction: Corrects a value, unit or magnitude */
  --bpg-tan:#B09C85;          /* 2.6:1  caution (ring 4.1:1, text 5.5:1) */
  /* Review result: the colour itself on figures and Stats' marks (Not checked is one colour for both its kinds,
     Unverified and Not reviewed: the record names which; salmon's marks get a darker 1px ring). On Browse, the record,
     the chips, the sidebar and the Guide the result is a word in its colour's text shade (round 17, "words, not
     shapes": no dot); the light salmon and slate words take a darker shade of the same hue, the slate one greyed so it
     stays apart from Accepted's navy (CIEDE2000 11.2). Contrast on white / the hovered row / the selected row. */
  --st-accepted:var(--bpg-navy);
  --st-pending:var(--bpg-salmon);
  --st-pending-ring:#c4664a;  /* 3.9:1 */
  --st-unverified:var(--bpg-slate);
  --st-not-reviewed:var(--bpg-slate);
  --st-not-reviewed-ring:var(--bpg-slate);
  --st-disputed:var(--bpg-deep-red);
  --st-accepted-ink:var(--bpg-navy);  /* 7.5 / 6.8 / 6.6:1 */
  --st-pending-ink:#975B4C;   /* 5.4 / 4.9 / 4.7:1, salmon's darker, quieter shade (terracotta; CIEDE2000 16.9 from Disputed) */
  --st-unverified-ink:#60687F;  /* 5.5 / 5.1 / 4.9:1, slate's darker, greyer shade */
  --st-disputed-ink:var(--bpg-deep-red);  /* 5.2 / 4.8 / 4.6:1 */
  /* Filter ticks: the status colour, or a darker form where it is light (3:1 or more on white). */
  /* Agreement with a second source (BPG green): human-checked's tick and word in the darker green (a human reviewer
     approved the values), a database result's Same number at the colour itself. */
  --checked:#007664;          /* 5.6:1; on its 12% tint 4.7:1, on the selected row 4.9:1 */
  /* Cautions (BPG tan): the "!" disc in tan with its 1px ring and an ink "!" (6.2:1 on tan), the caution's words and
     lines in the darker tan, its notes on a tan tint with ink-brown text. */
  --caution:#79654F;          /* 5.5:1 */
  --caution-mark:var(--bpg-tan);
  --caution-ring:#8c7a64;     /* 4.1:1 */
  --caution-tint:#f8f6f4;
  --caution-line:#dbd2c8;
  --caution-ink:#4a3b2a;      /* 9.7:1 on the tint */
  /* Database comparison and kinds of change (the record's Against the databases, Stats part 7, the corrections on
     records not yet re-read): agreement green, the same number in another form (another label; more digits or
     rounding) mint, a different number brown, a correction (Corrects a value; unit or magnitude) red, and a value no
     database has (Not in the databases; added where the source had none) cyan, CatLog's reading of the paper. */
  --cmp-same:var(--bpg-green);
  --cmp-other:var(--bpg-mint);
  --cmp-other-ring:#45A48E;   /* 3.0:1 */
  --cmp-differs:var(--bpg-brown);
  --cmp-new:var(--bpg-cyan);
  --cmp-new-ring:#2DA1BD;     /* 3.0:1 */
  --chg-magnitude:var(--bpg-red);
  --chg-precision:var(--bpg-mint);
  --bar-neutral:#7d8885;      /* single-series bars 3.7:1: a count with no meaning colour */
  /* Enzyme classes EC 1-7: a categorical set, used only in the Stats figures that draw the classes apart (Values by
     enzyme class, kcat against Km), where no other meaning colour appears, and always beside the class's number. Mint,
     tan and deep red are left out (too light for a line, or Disputed's alarm). */
  --ec-1:var(--bpg-red);
  --ec-2:var(--bpg-cyan);
  --ec-3:var(--bpg-green);
  --ec-4:var(--bpg-navy);
  --ec-5:var(--bpg-salmon);
  --ec-6:var(--bpg-slate);
  --ec-7:var(--bpg-brown);
  /* The databases: a categorical set for a figure whose only series are the databases (none yet; every view that lists
     them now colours its marks by review result or database result, so there the names tell them apart). */
  --db-brenda:var(--bpg-navy);
  --db-sabio:var(--bpg-red);
  --db-oed:var(--bpg-green);
  --db-uniprot:var(--bpg-slate);
  --db-skid:var(--bpg-tan);
  --db-strenda:var(--bpg-brown);
  /* Where a record's values come from: CatLog's reading of the paper (Read from the paper, its counts, its chip, its
     marks on Stats, the AI agents on Team) is BPG cyan, its words and numbers in the darker cyan; Not yet re-read has
     no colour of its own. */
  --src-paper:var(--bpg-cyan);
  --src-paper-ring:#2DA1BD;   /* 3.0:1 */
  --src-paper-ink:#207286;    /* 5.5:1; on its 12% tint 5.0:1 */
  --src-paper-tint:#eaf7fa;   /* 12% */
  /* A line of CatLog's values (CatLog and BRENDA by publication year): the cyan between its ring and its ink (55:45),
     so the line keeps 3:1 on the grey band too, where the ring's 3.0:1 would fall to 2.6:1. */
  --src-paper-line:#278CA4;   /* 3.9:1 on white; 3.4:1 on --plot-band */
  /* A plain grey band behind the years a figure sets apart (CatLog and BRENDA by publication year); no data meaning. */
  --plot-band:#eef1f0;
  /* Filter chips and the dot beside a sidebar group (tone-* below). A chip whose option has a meaning colour wears it;
     the other filters (search, enzyme, EC number, organism, substrate, measurement, wild type or variant, temperature,
     pH, Not yet re-read, a source database) are choices with no meaning colour, so they wear the accent, the colour of
     what a visitor picks (links, buttons, the selected row). */
  --fg-source:var(--accent);
  --fg-identity:var(--accent);
  --fg-measurement:var(--accent);
  --fg-dot-ring:rgba(23,33,32,0.24);  /* a 1px ring round the sidebar's group dots */
  /* No glow, halo, wash or gradient anywhere: a crisp, short shadow only where something floats above the page (menus,
     dialogs, the phone sheet, the record drawer, Stats' tooltip line). */
  --tip-shadow:0 2px 8px rgba(20,34,31,0.18);
  --overlay:rgba(20,34,31,0.24);
  --scroll-edge:rgba(23,33,32,0.5);
  --shadow:0 2px 8px rgba(20,34,31,0.10);
  --shadow-panel:0 0 0 1px var(--line), 0 4px 16px rgba(20,34,31,0.12);
}
* { box-sizing:border-box }
html, body { background:var(--bg) }
body { margin:0; color:var(--text); font-family:var(--font); font-size:var(--fs-14); font-variant-numeric:tabular-nums lining-nums; line-height:var(--lh-14); letter-spacing:0 }
button, input, select { font:inherit }
strong, b { font-weight:600 }
sub, sup { font-size:max(var(--fs-12),0.75em); line-height:0 }
/* A link is ink with a quiet underline that darkens under the pointer; controls that are plainly controls (tabs, menu
   items, buttons, contents lists, the counts band's numbers) keep none. */
a { color:var(--accent); text-decoration:underline; text-decoration-color:var(--accent-line); text-decoration-thickness:1px; text-underline-offset:2px }
a:hover { text-decoration-color:currentColor }
:is(.nav-tab, .nav-external, .brand-lockup, .skip-link, .button, .download-options a, .stats-contents a, .guide-contents a, .snapshot-paper, .snapshot-checked, .stats-total-value) { text-decoration:none }
:where(a,button,input,select,summary):focus-visible { outline:2px solid var(--accent); outline-offset:2px }
[hidden], .hidden { display:none !important }
.muted { color:var(--muted) }
/* A number and its unit, or a range with its power of ten ("1–3 × 10⁷ s⁻¹"), kept on one line. */
.nowrap { white-space:nowrap }
/* Read by screen readers only. Its box is 1px inside the nearest positioned ancestor; every scrolling view below is
   positioned, so hidden text deep in a long page never sits at the foot of the document and makes it scroll. */
.visually-hidden { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; border:0; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }

/* Skip link: shown only when focused. */
.skip-link { position:absolute; top:8px; left:8px; z-index:200; border-radius:var(--radius); background:var(--bg); box-shadow:var(--shadow); padding:8px 12px; color:var(--accent); font-size:var(--fs-14); font-weight:600; transform:translateY(-200%) }
.skip-link:focus { transform:none }
/* On the GitHub Pages copy (and offline copies): one line saying where the main site is; hidden on the main site. */
.main-site-note { flex-shrink:0; margin:0; border-bottom:1px solid var(--line-soft); background:var(--surface-2); color:var(--text-2); padding:6px var(--gutter); font-size:var(--fs-13); line-height:var(--lh-13) }
.main-site-note a { color:var(--text); font-weight:600 }
/* A short window wider than a phone keeps the table's 340px and does not scroll as a whole: up to 700px tall the note
   gives way, like the line over the counts card (which goes at 640px). */
@media (min-width: 641px) and (max-height: 700px) { .main-site-note { display:none } }
body:is(.stats-open,.guide-open,.team-open) .skip-link { display:none }
.static-app { display:flex; flex-direction:column; height:100vh; height:100dvh; min-height:0; background:var(--bg) }
.app-header, .catalog-load-progress, .snapshot-band { flex-shrink:0 }
#catalogView { display:flex; flex-direction:column; flex:1; min-height:0 }

/* Header (56px): brand, the catalog's tabs (Browse · Stats · Guide · Team), the links out, search (at most 560px), Download. */
.app-header { display:grid; grid-template-columns:max-content max-content max-content minmax(200px,1fr) max-content; grid-template-areas:"brand nav links search actions"; min-height:var(--header-h); align-items:center; column-gap:var(--sp-5); border-bottom:1px solid var(--line); background:var(--bg); padding:0 var(--gutter) }
.brand-lockup { display:flex; min-width:max-content; align-items:baseline; gap:var(--sp-2); border:0; background:transparent; cursor:pointer; padding:0; text-align:left }
.brand-lockup strong { color:var(--text); font-size:var(--fs-20); font-weight:600; line-height:var(--lh-20) }
.brand-lockup span { color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.brand-lockup:hover strong { color:var(--accent) }
.top-nav { display:flex; align-self:stretch; align-items:stretch; gap:var(--sp-1) }
.nav-tab { display:inline-flex; align-items:center; justify-content:center; min-width:56px; border:0; border-bottom:2px solid transparent; background:transparent; color:var(--text-2); cursor:pointer; padding:2px var(--sp-2) 0; font-size:var(--fs-14); font-weight:500; line-height:var(--lh-14); text-decoration:none }
.nav-tab:hover { color:var(--text); text-decoration:none }
.nav-tab.active { border-bottom-color:var(--accent); color:var(--text); font-weight:600 }
/* The Stats tab's soft glow (the user, 2026-10-21: "the glow in the numbers isn't needed, only the Stats button"): the
   one glow on the site, so visitors notice the Stats page. A quiet BPG-cyan halo behind the word, no animation, the same
   when the tab is active (its underline unchanged); the word keeps the tabs' colours. Nothing else glows. */
#statsButton { text-shadow:0 0 10px color-mix(in srgb, var(--bpg-cyan) 75%, transparent), 0 0 3px color-mix(in srgb, var(--bpg-cyan) 40%, transparent) }
/* The CatRange paper and the lab's site: links out, after the catalog's own tabs and set apart by a rule. */
.external-nav { display:flex; align-items:center; gap:var(--sp-4); border-left:1px solid var(--line); padding-left:var(--sp-5); white-space:nowrap }
.nav-external { color:var(--text-2); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13); text-decoration:none }
.nav-external:hover { color:var(--accent); text-decoration:underline }
.nav-external > span[aria-hidden] { color:var(--muted) }
.nav-external-short { display:none }
.global-search { display:grid; grid-template-columns:minmax(0,1fr) auto; justify-self:end; width:min(560px,100%); align-items:center; border:1px solid var(--line-strong); border-radius:var(--radius); background:var(--bg); padding:0 var(--sp-2) 0 var(--sp-3) }
.global-search:focus-within { border-color:var(--accent); outline:2px solid var(--accent); outline-offset:2px }
/* Laptops: closer header areas leave the search box room for its placeholder. */
@media (min-width: 1024px) and (max-width: 1439px) {
  .app-header { column-gap:var(--sp-4) }
  .external-nav { gap:var(--sp-3); padding-left:var(--sp-4) }
}
/* 1024-1439px: still one 56px line, the brand without its tagline and the short links out ("Paper ↗ Lab ↗"), so the
   search box keeps room for its placeholder (at 1280px the long links left it 225px in Linux's wider DejaVu font). */
@media (min-width: 1024px) and (max-width: 1439px) {
  .app-header { grid-template-columns:max-content max-content max-content minmax(160px,1fr) max-content }
  .brand-lockup span:not(.visually-hidden), .nav-external-long { display:none }
  .nav-external-short { display:inline }
}
.global-search input { width:100%; min-height:36px; border:0; outline:0; background:transparent; color:var(--text); font-size:var(--fs-14) }
.global-search input::placeholder { color:var(--muted) }
.global-search kbd { min-width:20px; border:1px solid var(--line); border-radius:4px; background:var(--surface-2); color:var(--muted); text-align:center; font:var(--fs-12)/18px var(--font-mono) }
/* Touch screens (pointer: coarse): the "/" shortcut badge means nothing without a keyboard, so the box shows none. */
@media (pointer: coarse) {
  .global-search kbd { display:none }
}
.header-actions { display:flex; min-width:max-content; align-items:center; gap:12px }
.download-menu { position:relative }
.download-menu summary { gap:8px; border-color:var(--accent-line); color:var(--accent); list-style:none; user-select:none }
.download-menu summary::-webkit-details-marker { display:none }
.download-menu[open] summary { background:var(--accent-tint) }
.download-options { position:absolute; z-index:90; top:calc(100% + 8px); right:0; display:grid; width:330px; border:1px solid var(--line); border-radius:var(--radius); background:var(--bg); box-shadow:var(--shadow); padding:6px }
.download-options a { display:grid; gap:2px; border-radius:4px; color:var(--text); padding:8px 10px; text-decoration:none }
.download-options a:hover, .download-options a:focus-visible { background:var(--accent-tint); outline:0; text-decoration:none }
.download-options a:focus-visible, .download-options button:focus-visible { outline:2px solid var(--accent); outline-offset:-2px }
.download-options strong { font-size:var(--fs-13) }
.download-options span { color:var(--muted); font-size:var(--fs-12); line-height:1.4; white-space:pre-line }
/* Where a filtered set is saved (Export results gives CSV), under the files, set off by a hairline. */
.download-note { margin:4px 0 0; border-top:1px solid var(--line-soft); padding:8px 10px 2px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.download-options .corpus-request-link { margin-top:4px; border-top:1px solid var(--line); border-radius:0 0 4px 4px; padding-top:12px }
/* Export results: three choices under the button (opening to the right, so a phone keeps it on screen). */
.export-menu .download-options { right:auto; left:0; width:min(320px,calc(100vw - 32px)) }
.download-options button { display:grid; gap:2px; width:100%; border:0; border-radius:4px; background:transparent; color:var(--text); cursor:pointer; padding:8px 10px; text-align:left }
.download-options button:hover:not(:disabled) { background:var(--accent-tint); outline:0 }
.download-options button:focus-visible { background:var(--accent-tint) }
/* An empty search box offers one line of examples: "Try: hexokinase · 1.1.1.1 · ..." (it wraps in a narrow box). */
.search-suggestions { position:fixed; z-index:85; display:flex; flex-wrap:wrap; align-items:center; gap:2px 0; max-height:min(320px,calc(100vh - 80px)); overflow:auto; border:1px solid var(--line); border-radius:var(--radius); background:var(--bg); box-shadow:var(--shadow); padding:6px 8px }
.suggestion-title { color:var(--muted); padding:4px 4px 4px 2px; font-size:var(--fs-13) }
.suggestion-sep { color:var(--muted); font-size:var(--fs-13) }
.search-suggestions button { min-height:30px; border:0; border-radius:4px; background:transparent; color:var(--accent); cursor:pointer; padding:4px 6px; text-align:left; font-size:var(--fs-13); white-space:nowrap }
.search-suggestions button:hover, .search-suggestions button:focus, .search-suggestions button[aria-selected="true"] { background:var(--hover); outline:0 }

/* Buttons */
.button, .text-button, .icon-button { border-radius:var(--radius); cursor:pointer }
.button { display:inline-flex; min-height:32px; align-items:center; justify-content:center; gap:8px; border:1px solid var(--line-strong); background:var(--bg); color:var(--text); padding:6px 12px; font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13); text-decoration:none }
.button.secondary:hover:not(:disabled) { border-color:var(--accent-line); background:var(--accent-tint); text-decoration:none }
.text-button, .icon-button { border:0; background:transparent; font-size:var(--fs-13) }
.text-button { color:var(--accent); padding:0; font-weight:500; text-decoration:underline; text-decoration-color:var(--accent-line); text-decoration-thickness:1px; text-underline-offset:2px }
.text-button:hover:not(:disabled) { text-decoration-color:currentColor }
.icon-button { display:inline-grid; width:32px; height:32px; place-items:center; color:var(--text-2); font-size:var(--fs-20) }
.icon-button:hover:not(:disabled) { background:var(--accent-tint) }
button:disabled { cursor:not-allowed; opacity:0.5 }

/* Loading bar (Browse only). */
.catalog-load-progress { --load-progress:0; height:4px; overflow:hidden; background:var(--line-soft); opacity:1; transition:opacity 180ms ease }
.catalog-load-progress > span { display:block; width:100%; height:100%; transform:scaleX(var(--load-progress)); transform-origin:left center; background:var(--accent); transition:transform 160ms ease }
.catalog-load-progress.complete { opacity:0 }
.catalog-load-progress.stalled > span { transform:scaleX(1); background:var(--caution); opacity:0.6 }
body:is(.stats-open,.guide-open,.team-open) .catalog-load-progress { display:none }

/* Counts band, the first thing a visitor sees (round 13, the user: "the numbers and overall progress ... so small and
   colour same so it doesn't capture any attention"; round 14: "a bit AI-ish, with the glow"; round 15: "the screenshot
   segment could still be improved"): a plain white card with a 1px hairline, no glow, wash or shadow, holding one even
   row: the four key numbers, each label over its number and one short line of context under it, then, behind one thin
   rule, the parameters (each name over its count, one line under them). Type set in columns, not tiles: no rule
   between the key numbers. They lead by size, weight and tabular figures, each in the colour its meaning has across
   the site (Records the page's ink, Accepted its status navy, Read from the paper the darker BPG cyan, Human-checked
   the darker BPG green with the tick; round 17: no dot or square on the labels). The line above says what CatLog is and ends with the
   snapshot date. One layout from 1024px up (nothing wraps or moves as the window widens or the filters change), two
   rows on tablets, a 2 x 2 grid on phones. */
.snapshot-band { position:relative; min-width:0; border-bottom:1px solid var(--line); background:var(--bg); padding:6px var(--gutter) }
/* One plain line on what CatLog is, over the counts, for a first-time visitor; the snapshot date at its right end (a
   float after the words: on a phone it takes the end of the last line, or a line of its own when that has no room; the
   line holds its float, so the card under it keeps its width). */
.snapshot-lead { display:flow-root; margin:0 0 4px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.snapshot-lead a { white-space:nowrap }
.snapshot-date { color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); white-space:nowrap }
.snapshot-lead .snapshot-date { float:right; margin-left:var(--sp-4); line-height:var(--lh-13) }
/* A short window wider than a phone (800 x 600) keeps the table's 340px: the line gives way, the Guide tab stays, and the
   snapshot date moves into the card (the end of the parameters' line, below). */
@media (min-width: 641px) and (max-height: 640px) { .snapshot-lead { display:none } }
/* The row: a grid of three lines (labels, numbers, context) that every cell shares (a subgrid), so the labels, the
   numbers' baselines and the lines of context each line up across the band; columns as wide as each other, never
   narrower than their words. */
.snapshot-overview { --band-num:var(--fs-28); --band-num-lh:var(--lh-24); --cell-pad:20px; position:relative; display:grid; min-width:0; grid-template-rows:auto auto auto; grid-auto-flow:column; grid-auto-columns:minmax(max-content,1fr); column-gap:var(--cell-pad); border:1px solid var(--line); border-radius:var(--radius); background:var(--bg); padding:6px var(--cell-pad) 6px var(--sp-4) }
/* Records and Accepted sit in the band's row like the other key numbers. */
.summary-grid { display:contents }
.summary-card, .snapshot-paper, .snapshot-checked, .snapshot-meta { grid-row:1 / span 3; display:grid; grid-template-rows:subgrid; justify-self:start; min-width:0 }
.summary-card, .snapshot-paper, .snapshot-checked { --key:var(--text); position:relative; color:var(--text); white-space:nowrap }
/* One thin rule, before the parameters (as round 14 had); none between the key numbers. */
.snapshot-meta { border-left:1px solid var(--line-soft); padding-left:var(--cell-pad) }
.summary-card > span, .snapshot-paper > span, .snapshot-checked > span { display:inline-flex; align-items:center; color:var(--muted); font-size:var(--fs-13); line-height:16px }
.summary-card > strong, .snapshot-paper > strong, .snapshot-checked > strong { align-self:baseline; color:var(--key); font-size:var(--band-num); font-weight:600; line-height:var(--band-num-lh) }
/* Records' "?" (round 17: what a record and its values are, where a visitor first meets the word): the sidebar's "?" at
   the label's size (16px, a 24px target), and the two sentences it opens in a hairline note over the band, under the
   label, never moving the numbers. */
.band-about { position:relative; display:inline-grid; width:16px; height:16px; margin-left:var(--sp-1); place-items:center; border:1px solid var(--line-strong); border-radius:50%; background:var(--bg); color:var(--muted); cursor:pointer; padding:0; font:inherit; font-size:var(--fs-12); font-weight:600; line-height:1 }
.band-about::after { content:""; position:absolute; inset:-4px }
.band-about:hover { border-color:var(--accent); color:var(--accent) }
.band-about[aria-expanded="true"] { border-color:var(--accent-line); background:var(--accent-tint); color:var(--accent) }
.band-about-text { position:absolute; z-index:30; top:20px; left:-9px; display:block; width:min(340px,calc(100vw - 32px)); border:1px solid var(--line-strong); border-radius:var(--radius); background:var(--bg); padding:var(--sp-2) 10px; color:var(--text-2); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12); white-space:normal }
.band-about-text[hidden] { display:none }
/* Each count keeps the room of a seven-character number ("185,804"), so a filter that changes its digits never moves
   the columns. */
@media (min-width: 641px) {
  .summary-card > strong, .snapshot-paper > strong, .snapshot-checked > strong, .snapshot-line > strong { min-width:7ch }
}
/* A line of context under each number (and under the parameters): muted, 12px, one line. Where the cells are narrow
   (below 1280px) Read from the paper's share leaves its "of records" to screen readers ("40.4% · 4,324 papers"). */
.snapshot-note { display:block; min-height:var(--lh-12); color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12); white-space:nowrap }
@media (max-width: 1279px) {
  .snapshot-note-base { position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
}
/* The meaning colours: the same as everywhere else on the site (DESIGN.md "Type And Color", one meaning per colour). */
.summary-card.summary-accepted { --key:var(--st-accepted-ink) }
.snapshot-paper { --key:var(--src-paper-ink) }
.snapshot-checked { --key:var(--checked) }
/* Every label is muted; the colour is on the number, at 0 too (no link then), and on Human-checked's green check, the
   site's one mark for it (round 17: no dot before Accepted, no square before Read from the paper). */
.snapshot-checked .check-icon { margin-right:3px; color:var(--checked) }
/* A linked count tints in its own colour around its words under the pointer (::before), so nothing moves. */
.snapshot-paper[href], .snapshot-checked[href] { isolation:isolate }
.snapshot-paper[href]::before, .snapshot-checked[href]::before { content:""; position:absolute; inset:-4px -8px; z-index:-1; border-radius:var(--radius); background:transparent; pointer-events:none }
.snapshot-paper[href]:hover::before, .snapshot-checked[href]:hover::before { background:color-mix(in srgb, var(--key) 9%, var(--bg)) }
@media (prefers-reduced-motion: no-preference) {
  .snapshot-paper[href]::before, .snapshot-checked[href]::before { transition:background-color 200ms ease }
}
.snapshot-paper:hover, .snapshot-checked:hover { text-decoration:none }
.snapshot-paper[href]:hover > span, .snapshot-checked[href]:hover > span { text-decoration:underline }
/* The parameters: kcat, Km and kcat/Km, each name (a label like the others) over its count (16px, 500, the second ink:
   so the key numbers lead; a 20px line, so on the key numbers' baseline it keeps their 28px line), "records with each
   parameter" under them; in a short window the snapshot date ends that line (the card's copy of it). */
.snapshot-meta { grid-template-columns:repeat(3,max-content); column-gap:var(--sp-4) }
.snapshot-title { display:none; color:var(--muted); font-size:var(--fs-12); line-height:16px }
.snapshot-line { display:contents }
.snapshot-line > span { grid-row:1; color:var(--muted); font-size:var(--fs-13); line-height:16px; white-space:nowrap }
.snapshot-line > strong { grid-row:2; align-self:baseline; color:var(--text-2); font-size:var(--fs-16); font-weight:500; line-height:20px; white-space:nowrap }
.snapshot-meta > .snapshot-note { grid-row:3; grid-column:1 / -1 }
.snapshot-card-date { display:none }
@media (min-width: 1024px) and (max-height: 640px) { .snapshot-card-date { display:inline } }
/* (below 1100px the line has room for the date alone, as on tablets: in a wide font such as DejaVu Sans the whole line
   needs a 1048px window) */
@media (min-width: 1024px) and (max-width: 1099px) and (max-height: 640px) { .snapshot-meta .snapshot-note-text { display:none } }
.snapshot-more { display:none }
.snapshot-paper-short { display:none }
/* Tablets: the key numbers 24px, their lines of context under them, on the first row; the parameters on one line under
   them ("With kcat 104,525 Km ...") and the snapshot date at that line's end (the card's copy, the line's last item:
   the line above has no room for it beside its words at 641px), no rule. */
@media (min-width: 641px) and (max-width: 1023px) {
  .snapshot-overview { --band-num:var(--fs-24); --band-num-lh:var(--lh-20); --cell-pad:var(--sp-5); grid-template-columns:repeat(4,minmax(max-content,1fr)); grid-template-rows:auto auto auto auto; row-gap:0; padding:6px var(--sp-4) }
  .snapshot-meta { grid-row:4; grid-column:1 / -1; justify-self:stretch; display:flex; align-items:baseline; gap:var(--sp-3); margin-top:var(--sp-2); border-left:0; padding-left:0 }
  .snapshot-title { display:inline }
  .snapshot-line { display:inline-flex; align-items:baseline; gap:6px }
  .snapshot-line > span { color:var(--text-2); font-size:var(--fs-12) }
  .snapshot-line > strong { font-size:var(--fs-12); line-height:16px }
  .snapshot-meta > .snapshot-note { margin-left:auto; padding-left:var(--sp-3) }
  .snapshot-meta .snapshot-note-text, .snapshot-lead .snapshot-date { display:none }
  .snapshot-card-date { display:inline }
}
/* Phones: Records and Accepted, then Read from the paper and Human-checked, labels over 20px numbers, with More at the
   right of the first row; More shows the lines of context under the numbers and the parameters under a thin rule:
   rows that exist only while shown, so a closed More leaves no empty row's gap. */
@media (max-width: 640px) {
  .snapshot-band { padding:var(--sp-2) var(--gutter) }
  .snapshot-overview { --band-num:var(--fs-20); --band-num-lh:var(--lh-20); --cell-pad:0px; grid-template-columns:max-content max-content minmax(0,1fr); grid-template-rows:none; grid-auto-flow:row; grid-template-areas:"records accepted more" "paper checked checked"; gap:var(--sp-2) var(--sp-4); padding:var(--sp-2) var(--sp-3) }
  .summary-card, .snapshot-paper, .snapshot-checked { grid-template-rows:none; display:inline-flex; flex-direction:column; align-items:flex-start; min-width:auto; border-left:0; padding-left:0 }
  .summary-card > strong, .snapshot-paper > strong, .snapshot-checked > strong { align-self:auto }
  .summary-records { grid-area:records }
  .summary-accepted { grid-area:accepted }
  .snapshot-paper { grid-area:paper }
  .snapshot-checked { grid-area:checked }
  .snapshot-more { grid-area:more; position:relative; z-index:1; display:inline-flex; justify-self:end; align-self:start; align-items:center; gap:4px; min-height:28px; margin:-4px -4px 0 0 }
  .snapshot-meta { grid-row:auto; grid-column:1 / -1; justify-self:stretch; grid-template-rows:none; row-gap:2px; border-top:1px solid var(--line-soft); border-left:0; padding:var(--sp-2) 0 0 }
  .snapshot-line > strong { grid-row:2; font-size:var(--fs-14); line-height:var(--lh-14) }
  .snapshot-band:not(.expanded) :is(.snapshot-meta,.snapshot-note) { display:none }
  /* Open, the columns give the lines of context the room there is, and one wraps rather than leave the card (a 320px
     phone in a wide font); Less keeps its own room at the first row's end. */
  .snapshot-band.expanded .snapshot-overview { grid-template-columns:auto auto minmax(44px,1fr) }
  .snapshot-note { white-space:normal }
}
/* Read from the paper takes its short tag, From paper, only where a phone is narrower than 360px (a screen reader
   still reads Read from the paper). */
@media (max-width: 359px) {
  .snapshot-paper-long { position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
  .snapshot-paper-short { display:inline }
  /* There the line above has no room for the date after its words (it would take a third line): the date ends the
     parameters' line under More, as round 14 had it. */
  .snapshot-lead .snapshot-date { display:none }
  .snapshot-card-date { display:block }
  .snapshot-card-date .snapshot-note-text { display:none }
  /* Open, Less takes More's place at the first row's end instead of a column of its own (beside "Matching records ?"
     in a wide font that column would push it out of the card), and Accepted's line of context wraps under its number
     rather than reach under Less (More and Less sit over the cards, so a tap on them never lands on Accepted). */
  .snapshot-band.expanded .snapshot-overview { grid-template-columns:auto min-content minmax(0,1fr) }
}

/* Workbench: one grid, [filter sidebar | table | open record]. The sidebar is a column from 641px (open, or a 48px rail
   when collapsed), never over the table; the record is a column from 1024px; phones get a filter sheet and a record
   dialog. Sidebar and record scroll on their own; the table keeps its own scroll and page controls. */
.workbench { --filter-col:var(--rail-w); display:grid; grid-template-columns:minmax(0,1fr); grid-template-rows:minmax(0,1fr); align-items:stretch; flex:1; min-height:340px }
.filter-rail, .table-panel, .detail-panel { background:var(--bg) }
.filter-column { display:contents }
.filter-rail-button { display:none }
@media (min-width: 641px) {
  .workbench { grid-template-columns:var(--filter-col) minmax(0,1fr) }
  body.filters-open .workbench { --filter-col:var(--sidebar-w) }
  .filter-column { display:flex; grid-column:1; grid-row:1; min-width:0; min-height:0; border-right:1px solid var(--line); background:var(--bg) }
  .table-panel { grid-column:2; grid-row:1 }
  /* Collapsed: the rail, one tall button with "Filters" set vertically and the active-filter count. */
  body:not(.filters-open) .filter-rail-button { display:flex; flex-direction:column; align-items:center; gap:var(--sp-2); width:100%; border:0; background:transparent; color:var(--text-2); cursor:pointer; padding:var(--sp-3) 0; font-size:var(--fs-13); font-weight:600; line-height:var(--lh-13) }
  .filter-rail-button:hover { background:var(--accent-tint); color:var(--text) }
  .filter-rail-button:focus-visible { outline-offset:-2px }
  .filter-rail-label { writing-mode:vertical-rl; transform:rotate(180deg) }
  body:not(.filters-open) .filter-rail { display:none }
  body.filters-open .filter-rail { display:flex }
  .filter-backdrop, .close-filters { display:none }
}
.double-chevron { flex:0 0 16px; width:16px; height:16px; color:var(--muted) }
/* The sidebar (and, on phones, the sheet): a sticky heading, then the filter groups. */
/* A control reached with Tab or Shift+Tab scrolls clear of the sticky 48px heading, with room for its focus ring. */
/* A thin scrollbar (11px where scrollbars take room, as in Chrome on Linux and Windows) leaves the options 4px more. */
/* position:relative: the rail is the containing block of what it holds, so a visually hidden label inside it is
   clipped by its scroll box instead of lengthening the page. */
.filter-rail { position:relative; display:flex; flex-direction:column; width:100%; min-width:0; min-height:0; overflow-y:auto; overscroll-behavior:contain; scroll-padding-top:56px; scrollbar-width:thin }
.filter-rail:focus { outline:none }
.rail-heading { position:sticky; top:0; z-index:2; display:flex; flex-shrink:0; min-height:48px; align-items:center; gap:var(--sp-2); border-bottom:1px solid var(--line-soft); background:var(--bg); padding:0 var(--sp-2) 0 var(--sp-4) }
.rail-title { margin:0; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.rail-heading #clearButton { margin-left:auto; font-size:var(--fs-13) }
/* Without a filter on, Clear all is hidden and the « (or ×) keeps the heading's right end. */
.rail-heading #clearButton[hidden] ~ .icon-button { margin-left:auto }
/* Undo in the heading is for the phone sheet, which covers the chips (wider, the chips' Undo is in view beside the
   sidebar). */
.rail-heading #undoFiltersButton { display:none; font-size:var(--fs-13) }
.rail-heading .icon-button { flex:0 0 32px }
.filter-toggle { width:max-content }
.filter-count { display:inline-grid; min-width:18px; height:18px; place-items:center; border-radius:9px; background:var(--accent-tint); color:var(--accent); padding:0 5px; font-size:var(--fs-12); font-weight:600; line-height:1 }
/* Groups: native disclosures, 13px/600 summaries, a soft rule between them. */
.filter-section { position:relative; border-bottom:1px solid var(--line-soft) }
/* A title keeps its chevron (and its "?") level with its first line: 13px above and below an 18px line make the 44px row,
   so a one-line title is centred and a title a wide font wraps keeps both on its first line. */
.filter-section-title { display:flex; min-height:44px; align-items:flex-start; justify-content:space-between; gap:var(--sp-2); color:var(--text); cursor:pointer; padding:13px var(--sp-4); font-size:var(--fs-13); font-weight:600; line-height:var(--lh-13); list-style:none; user-select:none }
.filter-section-title::-webkit-details-marker { display:none }
.filter-section-title:hover { background:var(--surface-2) }
.filter-section-title:focus-visible { outline-offset:-2px }
.filter-section > :not(summary) { margin:0 var(--sp-4) var(--sp-3) }
/* A group's "?" (beside its chevron) shows its explanations in a quiet box under the title: the options keep one short
   line each. Its 24px circle is centred on the title's first line (top 10px + 12px = 13px + 9px), as the chevron is,
   46px from the group's right edge (right 30px + the 16px margin every part of a group has), its 44px touch area 7px
   clear of the chevron; the title stops 4px before it (30px more than the chevron's 36px), so a long title in a wide
   font wraps instead of running under it. */
.filter-section.has-about > .filter-section-title > span { margin-right:30px }
/* Inside More filters a group's "?" sits further in, so its title stops sooner (it wraps, in a wide font, rather than run under it). */
.filter-more .filter-section.has-about > .filter-section-title > span { margin-right:58px }
.section-about { display:inline-grid; width:24px; height:24px; margin:0; place-items:center; border:1px solid var(--line-strong); border-radius:50%; background:var(--bg); color:var(--muted); cursor:pointer; padding:0; font-size:var(--fs-12); font-weight:600; line-height:1 }
.section-about:hover { border-color:var(--accent); color:var(--accent) }
.section-about[aria-expanded="true"] { border-color:var(--accent-line); background:var(--accent-tint); color:var(--accent) }
.filter-section > .section-about { position:absolute; top:10px; right:30px }
.filter-about { display:grid; gap:6px; border-radius:var(--radius); background:var(--surface-2); padding:var(--sp-2) 10px; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12) }
.filter-about p { margin:0 }
.filter-about strong { color:var(--text); font-weight:600 }
/* Each option's name on its line, its words under it (a term list, as the Guide's; no "Name — words"). */
.filter-about .about-terms { display:grid; gap:6px; margin:0 }
.filter-about .about-terms > div { display:grid; gap:1px }
.filter-about .about-terms dt { color:var(--text); font-weight:600 }
.filter-about .about-terms dd { margin:0 }
.filter-about .about-under { color:var(--text-2); font-weight:400 }

/* 12px chevrons; they turn over when their group opens or closes. */
.chevron { flex:0 0 12px; width:12px; height:12px; transition:transform 160ms ease }
.filter-section-title .chevron { margin-top:3px; color:var(--muted) }
.filter-section:not([open]) .chevron, .download-menu[open] .chevron, .snapshot-band.expanded .chevron { transform:rotate(180deg) }
.filter-section input:is([type="search"],[type="text"]), .records-tools select, .pagination select { width:100%; min-width:0; min-height:32px; border:1px solid var(--line-strong); border-radius:var(--radius); background:var(--bg); color:var(--text); padding:4px var(--sp-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.filter-section input:is([type="search"],[type="text"]):focus-visible, .records-tools select:focus-visible, .pagination select:focus-visible { border-color:var(--accent) }
.filter-section input[aria-invalid="true"] { border-color:var(--st-disputed) }
/* Names and EC number: a label beside each field (the column is as wide as the longest label, so none wraps). */
.field-grid { display:grid; grid-template-columns:max-content minmax(0,1fr); align-items:center; gap:var(--sp-2) var(--sp-3) }
.field-grid label { color:var(--text-2); font-size:var(--fs-13); white-space:nowrap }
/* Assay conditions: a label and its count, then from and to. */
.range-stack { display:grid; gap:var(--sp-3) }
.range-row { display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr); align-items:center; gap:var(--sp-1) 6px }
/* The label has the whole first line (its count at the right end), so a wide font does not wrap it. */
.range-label { grid-column:1 / -1; grid-row:1; padding-right:64px; color:var(--text); font-size:var(--fs-13) }
.range-row > strong { grid-column:3; grid-row:1; justify-self:end; color:var(--muted); font-size:var(--fs-12); font-weight:400 }
.range-dash { color:var(--muted); font-size:var(--fs-13) }
.filter-note { margin:0; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
/* Options: 28px rows, a 14px box, the 13px label and its 12px count at the right. A label that wraps (a wide system
   font) takes a second line: the box and the count stay on its first line and nothing runs into the next row. */
.check-stack { display:grid; gap:0 }
.check-row { display:grid; grid-template-columns:14px minmax(0,1fr) auto; min-height:28px; align-items:start; gap:var(--sp-2); padding:5px 0; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13) }
.check-row input { width:14px; height:14px; margin:2px 0 0; accent-color:var(--accent) }
.check-row > strong { padding-top:1px; white-space:nowrap }
/* Every box is neutral (the accent). A review result and Read from the paper are their words in their colour's text
   shade, as in the table (round 17: no dot or square); human-checked its green check and word. A caution shows its "!"
   and a database result its square between the box and its words: each mark takes the square's 10px slot, 6px after the
   box and 4px before the words, so the words of those groups start at one edge; an option without one (No cautions,
   Corrected earlier) keeps the slot. */
.option-mark { display:inline-block; flex:none; width:10px; height:10px; margin:0 4px 0 -2px; vertical-align:-1px }
.state-word { color:var(--status-ink,var(--text)) }
:is(.state-word,.chip-state).accepted { --status-ink:var(--st-accepted-ink) }
:is(.state-word,.chip-state).review { --status-ink:var(--st-pending-ink) }
:is(.state-word,.chip-state).unresolved { --status-ink:var(--st-unverified-ink) }
:is(.state-word,.chip-state).disputed { --status-ink:var(--st-disputed-ink) }
.source-word { color:var(--src-paper-ink) }
/* the "!" disc at its legible 12px, centred where the dots and squares are */
.caution-option-mark { display:inline-grid; width:12px; height:12px; margin:0 3px 0 -3px; place-items:center; border-radius:50%; background:var(--caution-mark); box-shadow:inset 0 0 0 1px var(--caution-ring); color:var(--text); font-size:var(--fs-12); font-weight:600; line-height:1; vertical-align:-2px }
.caution-option-mark::before { content:"!" }
.check-row.nested { margin-left:22px }
/* "✓ human-checked" keeps one line beside its count; in the 256px sidebar a wider font breaks it after the hyphen rather
   than run it into the count. */
.human-checked-word { color:var(--checked); font-weight:500 }
.human-checked-word .check-icon { margin-right:2px }
.check-row strong { color:var(--muted); font-size:var(--fs-12); font-weight:400 }
/* Counts being worked out after a change fade only if that takes a moment. */
#catalogFilters [data-count] { transition:opacity 120ms ease }
#catalogFilters[data-counts="pending"] [data-count] { opacity:0.5; transition-delay:250ms }
/* An option no current result has: grey, still clickable. */
.check-row.is-zero > span, .range-row.is-zero > .range-label { color:var(--muted) }
.check-row.is-zero :is(.human-checked-word,.state-word,.source-word) { color:inherit }

/* Source: three choices, one line each (the help is behind the group's "?"), the first group under More filters; the
   databases of Not yet re-read are their own group there, Source database.
   Read from the paper keeps one line beside a six-figure count in the 256px sidebar, also in a wide font (DejaVu Sans):
   a count may come 4px closer to its label than elsewhere. */
.source-modes { display:grid; gap:0 }
.check-row.radio-row input { accent-color:var(--accent) }
.radio-row > strong { margin-left:-4px }

/* More filters: one disclosure after the three groups in view, holding the specialist groups (Source, Wild type or
   variant and Assay conditions open inside it; Against the databases, Cautions and Source database closed). Its title is a group
   title in the accent colour with the count of its filters set (the Filters badge's look, 6px after the words); it
   opens by itself when one of them is set. Inside, the groups keep their look; a soft rule closes the last one. */
.filter-more { border-bottom:1px solid var(--line-soft) }
.filter-more-title { color:var(--accent) }
.filter-more-title .chevron { color:var(--accent) }
.filter-more-title .filter-count { margin-left:6px; vertical-align:1px }
/* What is inside, while closed (round 14: Source moved in here, and a newcomer could not see it): one muted line of the
   groups' short names, Source first. */
.filter-more-groups { display:block; margin-top:2px; color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12) }
.filter-more[open] .filter-more-groups { display:none }
.filter-more:not([open]) > .filter-more-title .chevron { transform:rotate(180deg) }
.filter-more[open] > .filter-more-title { border-bottom:1px solid var(--line-soft) }
.filter-more > .filter-section:last-child { border-bottom:0 }

/* Against the databases: a 10px square in each result's colour before its name (the record and Stats use the same
   colours; Corrected earlier has none), "every value" nested under Not in the databases, and a rule before Corrected
   earlier, which is about records not yet re-read. With its square, "Not in the databases" (135px in DejaVu Sans) keeps
   one line beside a five-digit count in the 256px sidebar, also beside an 11px scrollbar (Chrome on Linux and
   Windows): the square sits 6px after the box and 4px before the name, the count comes 6px closer (2px from the
   names' column; the counts stay in line with the other groups'), and the names are set 1px tighter between words
   and 0.01em between letters. In the phone sheet the rows are 44px targets. */
.db-mark { display:inline-block; width:10px; height:10px; background:var(--db-mark, var(--bar-neutral)); box-shadow:inset 0 0 0 1px var(--db-mark-ring, var(--db-mark, var(--bar-neutral))); vertical-align:-1px }
#databaseChecklist .db-mark { margin:0 4px 0 -2px }
.db-mark.db-mark-none { visibility:hidden }
#databaseChecklist .check-row > span { letter-spacing:-0.01em; word-spacing:-1px }
#databaseChecklist .check-row > strong { margin-left:-6px }
.db-mark-corrects { --db-mark:var(--chg-magnitude) }
.db-mark-differs { --db-mark:var(--cmp-differs) }
.db-mark-other-label { --db-mark:var(--cmp-other); --db-mark-ring:var(--cmp-other-ring) }
.db-mark-not-listed { --db-mark:var(--cmp-new); --db-mark-ring:var(--cmp-new-ring) }
.db-mark-same { --db-mark:var(--cmp-same) }
.check-row.after-divider { margin-top:var(--sp-1); border-top:1px solid var(--line-soft); padding-top:9px }
@media (max-width: 640px) {
  #databaseChecklist .check-row { min-height:44px; padding-block:12px }
}

/* Phones: the filters are a full-screen sheet that slides up, "Filters · Undo · Clear all · ×" at the top (Undo and
   Clear all when they have something to do) and "Show N records" at the bottom. */
.filter-footer { display:none }
@media (max-width: 640px) {
  /* ...and clear of the sticky 69px "Show N records" footer. */
  .filter-rail { position:fixed; inset:0; z-index:80; height:100vh; height:100dvh; box-shadow:var(--shadow-panel); transform:translateY(calc(100% + 24px)); visibility:hidden; pointer-events:none; transition:transform 200ms ease, visibility 200ms ease; scroll-padding-bottom:80px }
  body.filters-open .filter-rail { transform:translateY(0); visibility:visible; pointer-events:auto }
  .filter-backdrop { position:fixed; inset:0; z-index:75; border:0; background:var(--overlay); cursor:default; opacity:0; visibility:hidden; pointer-events:none; transition:opacity 160ms ease, visibility 160ms ease }
  body.filters-open .filter-backdrop { opacity:1; visibility:visible; pointer-events:auto }
  .collapse-filters { display:none }
  .filter-footer { display:block; position:sticky; bottom:0; z-index:2; margin-top:auto; border-top:1px solid var(--line); background:var(--bg); padding:var(--sp-3) var(--sp-4) }
  .filter-footer .button { width:100%; min-height:44px; border-color:var(--accent); background:var(--accent); color:var(--bg); font-size:var(--fs-14) }
  .filter-footer .button:hover { border-color:var(--accent-hover); background:var(--accent-hover) }
  /* "Filters · Clear all · Undo · ×": the sheet covers the chips, so their Undo is here too. It always shows (dimmed with
     nothing to undo) right before ×, so Clear all coming and going never moves it under the finger, and Clear all keeps
     8px more room before it. */
  .rail-heading #undoFiltersButton { display:block }
  .rail-heading #clearButton { margin-right:var(--sp-2) }
  .rail-heading #clearButton[hidden] + #undoFiltersButton { margin-left:auto }
  .rail-heading #clearButton[hidden] ~ .icon-button { margin-left:0 }
}

/* Records: a 48px toolbar (Filters on phones, the active filters as chips and Clear all; Columns and Export at the
   right, and Sort on phones), the table, page controls. With its 1px rule it is 48px like the sidebar's heading, so the two rules line up
   (7px above and below a 32px control). */
.table-panel { display:flex; flex-direction:column; min-width:0; min-height:0; overflow:hidden }
/* The toolbar and the chips start at the row's top, the chips' first line 2px down so it centres on the 32px toolbar:
   a chip that wraps the bar onto a second line then leaves the first line (and Undo, which keeps its place) where it was
   (centred, a two-line bar had moved it up 2.5px, so a second click at the same point missed Undo's middle). */
.records-header { display:grid; grid-template-columns:minmax(0,1fr) auto; min-height:48px; flex-shrink:0; align-items:start; gap:var(--sp-3); border-bottom:1px solid var(--line); background:var(--bg); padding:7px var(--sp-4) }
.records-title { display:flex; flex-wrap:wrap; align-items:center; gap:var(--sp-2) var(--sp-3); min-width:0; min-height:30px; padding-top:2px }
.records-title > span { color:var(--text-2); font-size:var(--fs-13) }
/* The tools (Columns, Export) keep the toolbar's last column, so Export ends the row at every width, with or without
   a chip beside it (round 17 fix pass: with the title row empty from 1024px the tools fell into the first column and
   Export sat at the left at 1280-1700px but at the right beside a filter or a record). */
.records-tools { display:flex; grid-column:-2; align-items:center; gap:var(--sp-2); color:var(--text-2); font-size:var(--fs-13) }
@media (min-width: 1024px) {
  .records-tools > .export-menu { margin-left:auto }
}
/* Sorting is by the column headers; phones, whose cards have none, get a compact control instead (Sort ↑ reverses the
   order, the menu picks the column). */
.sort-control { display:none; min-width:0; align-items:center; gap:var(--sp-2) }
.sort-direction { display:inline-flex; min-height:32px; align-items:center; gap:2px; color:var(--muted); font-size:var(--fs-12); font-weight:400; text-decoration:none; white-space:nowrap }
.sort-direction .sort-icon { visibility:visible; margin-top:0; color:var(--accent) }
.sort-direction[data-direction="ascending"] .sort-icon { transform:rotate(180deg) }
.sort-direction:hover:not(:disabled) { color:var(--text) }
.sort-direction:disabled { cursor:default }
.sort-direction:disabled .sort-icon { color:var(--muted) }
.records-tools .button { white-space:nowrap }
#openFiltersButton { display:none }
.table-wrap { width:100%; flex:1; min-height:0; overflow:auto; background:var(--bg) }
/* Active filters: Undo first (dimmed with nothing to undo: it keeps its place however many chips there are, so pressing
   it again never lands on a chip or Clear all), then one removable chip each and Clear all. A chip is plain (round 14:
   a tint, a tinted line and a 3px coloured stripe showed one colour three times, a template look): a 1px hairline on
   white, its words ("Source: Read from the paper") and, where its option has one, the option's own words or mark in its
   meaning colour (a review result's word and Read from the paper's words in their text shades, human-checked's tick, a
   database result's square, a caution's "!"). The tone-* classes below colour the sidebar's group dots only. */
.active-filters { display:flex; flex-wrap:wrap; min-width:0; align-items:center; gap:6px var(--sp-2) }
/* A group's colour (--group), for the dot beside its title in the sidebar. */
.tone-source { --group:var(--fg-source) }
/* Read from the paper: BPG cyan, as on the counts band and Stats (its chip's tone; the chip says it in words). */
.tone-paper { --group:var(--src-paper) }
.tone-identity { --group:var(--fg-identity) }
.tone-measurement { --group:var(--fg-measurement) }
.tone-caution { --group:var(--caution-mark); --group-tint:var(--caution-tint); --group-line:var(--caution-line) }
.tone-checked { --group:var(--checked) }
.tone-st-accepted { --group:var(--st-accepted) }
.tone-st-pending { --group:var(--st-pending); --group-line:var(--st-pending-ring) }
.tone-st-unverified { --group:var(--st-unverified) }
.tone-st-disputed { --group:var(--st-disputed) }
.tone-cmp-corrects { --group:var(--chg-magnitude) }
.tone-cmp-differs { --group:var(--cmp-differs) }
.tone-cmp-new { --group:var(--cmp-new) }
.tone-cmp-other { --group:var(--cmp-other); --group-line:var(--cmp-other-ring) }
.tone-cmp-same { --group:var(--cmp-same) }
/* Corrected earlier (no square) and a Review result chip naming several results (each result's dot is in its words). */
.tone-neutral { --group:var(--bar-neutral) }
.filter-chip { display:inline-flex; min-width:0; max-width:100%; min-height:28px; align-items:center; gap:var(--sp-1); border:1px solid var(--line-strong); border-radius:var(--radius); background:var(--bg); color:var(--text); cursor:pointer; padding:2px 6px; font-size:var(--fs-12); line-height:var(--lh-12) }
.filter-chip > span { min-width:0; max-width:280px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.filter-chip .chip-x { flex:0 0 12px; width:12px; height:12px; color:var(--muted) }
/* The Review result chip names each result in its colour's text shade, as the table's status cells do, and the Source
   chip Read from the paper in its dark cyan (round 17: words, no dot or square). */
.chip-state { color:var(--status-ink,var(--text)) }
/* The marks a chip's option has on the page, before its name, so a chip's group is told by more than its colour (two
   colours can look alike to a colour-blind reader): human-checked's green tick, a caution's tan "!" (the table's, at
   12px) and a database result's square (the sidebar's, at 8px). */
.chip-check { color:var(--checked) }
.chip-check .check-icon { width:12px; height:12px; margin-right:2px; vertical-align:-2px }
.chip-flag { display:inline-grid; width:12px; height:12px; margin:0 4px 1px 0; place-items:center; border-radius:50%; background:var(--caution-mark); box-shadow:inset 0 0 0 1px var(--caution-ring); color:var(--text); font-size:var(--fs-12); font-weight:600; line-height:1; vertical-align:middle }
.chip-flag::before { content:"!"; content:"!" / "" }
.filter-chip .db-mark { width:8px; height:8px; margin:0 4px 1px 0; vertical-align:middle }
.filter-chip:hover { border-color:var(--accent) }
.filter-chip:hover .chip-x { color:var(--accent) }
/* Undo and Clear all stand 4px further from the chips than the chips from each other. Clear all's room is the last
   chip's right margin, so a Clear all that wraps starts its line where the chips do, never 4px in. */
.filter-chips-undo { margin-right:var(--sp-1); font-size:var(--fs-12) }
.filter-chips-clear { font-size:var(--fs-12) }
.filter-chip:has(+ .filter-chips-clear) { margin-right:var(--sp-1) }
/* Undo and Clear all (beside the chips and in the sidebar's heading) and Clear search and filters: targets at least 24px
   tall. */
:is(.filter-chips-undo, .filter-chips-clear, #undoFiltersButton, #clearButton, #clearResultsButton) { min-height:24px }
.active-filters.results-empty .filter-chips-clear { display:none }
/* A mark beside a sidebar group's title: none shows. The groups with no meaning colour (the enzyme fields, the
   measurement, Source database) have none (an ink dot there was decoration); Review result, Against the databases and
   Cautions say it on their options; Source's cyan square while Read from the paper was chosen went in round 17 (the
   option's words are its dark cyan). A dot would hang in the 16px gutter (4px from the edge, 4px before the words). */
.group-dot { display:inline-block; width:8px; height:8px; margin:0 4px 1px -12px; border-radius:50%; background:var(--group); box-shadow:inset 0 0 0 1px var(--fg-dot-ring); vertical-align:middle }
.group-dot:is(.tone-identity, .tone-measurement, .tone-source) { display:none }
/* Columns: shown when the table is wider than its room (the script hides it otherwise). */
.table-scroll-controls { display:flex; gap:2px; border:1px solid var(--line); border-radius:var(--radius); background:var(--bg); padding:1px }
.table-scroll-controls > span { align-self:center; padding:0 var(--sp-1) 0 6px; color:var(--muted); font-size:var(--fs-12); white-space:nowrap }
.table-scroll-controls .icon-button { width:28px; height:28px; font-size:var(--fs-18) }
/* A table wider than its room scrolls sideways: Enzyme stays in view and the scrolled edges are marked. The marks are a
   12px shadow over the rows inside the visible area (the script places them): beside the sticky Enzyme column at the
   left, before the vertical scrollbar at the right. */
.table-wrap { overscroll-behavior-x:contain }
.table-panel { position:relative }
.table-panel::before, .table-panel::after { content:""; position:absolute; z-index:4; top:var(--cue-top,0); bottom:var(--cue-bottom,0); width:12px; pointer-events:none; visibility:hidden }
.table-panel::before { left:var(--cue-left,0); box-shadow:inset 12px 0 10px -12px var(--scroll-edge) }
.table-panel::after { right:var(--cue-right,0); box-shadow:inset -12px 0 10px -12px var(--scroll-edge) }
.table-panel.cue-left::before, .table-panel.cue-right::after { visibility:visible }
.table-wrap:is(.can-scroll-left,.can-scroll-right) .c-enzyme { position:sticky; left:0; z-index:2; background:var(--bg); box-shadow:1px 0 0 var(--line) }
.table-wrap:is(.can-scroll-left,.can-scroll-right) th.c-enzyme { z-index:3; background:var(--surface-2) }
.table-wrap:is(.can-scroll-left,.can-scroll-right) tbody tr:nth-child(even) td.c-enzyme { background:var(--surface-3) }
.table-wrap:is(.can-scroll-left,.can-scroll-right) tbody tr:is(:hover,:focus-visible) td.c-enzyme { background:var(--hover) }
.table-wrap:is(.can-scroll-left,.can-scroll-right) tbody tr.selected td.c-enzyme { background:var(--accent-tint); box-shadow:inset 3px 0 0 var(--accent), 1px 0 0 var(--line) }

/* Fixed layout. These widths are a starting point: the script sizes each column to the page and gives the rest to the name columns. */
table { --cell-x:10px; width:100%; border-collapse:collapse; table-layout:fixed }
.col-ec { width:88px }
.col-organism { width:clamp(140px,12vw,200px) }
.col-substrate { width:clamp(150px,13vw,220px) }
.col-kcat, .col-km { width:88px }
.col-efficiency { width:104px }
.col-state { width:188px }
.col-open { width:28px }
th, td { border-bottom:1px solid var(--line-soft); padding:4px var(--cell-x); text-align:left; vertical-align:middle; font-size:var(--fs-13); line-height:17px; overflow-wrap:break-word }
th { position:sticky; top:0; z-index:1; height:48px; background:var(--surface-2); color:var(--text-2); font-size:var(--fs-12); font-weight:600; line-height:1.25; white-space:nowrap }
.header-unit { display:block; margin-top:4px; color:var(--muted); font-size:var(--fs-12); font-weight:400; white-space:nowrap }
/* Every header sorts (round 17): a click sorts the column its natural way (names A to Z, EC 1 to 7, values high to low,
   Review result accepted first), a second click the other way. The headings keep their type; the sorted column's
   heading is ink with a quiet arrow (up: ascending, A to Z or low to high; down: descending), and hovering another
   heading shows a faint arrow for the way a click would sort it. The whole cell is the target (the script forwards a
   click on its padding to the button). Value headings put the arrow before their words (they are right-aligned), the
   others after. */
th.sortable { cursor:pointer }
th.sortable:has(.sort-button:disabled) { cursor:default }
.sort-button { display:inline-flex; align-items:flex-start; gap:2px; border:0; background:none; padding:0; color:inherit; font:inherit; text-align:right; cursor:pointer }
th:not(.num) > .sort-button { align-items:center; gap:4px; text-align:left }
.sort-button:disabled { cursor:default }
.sort-icon { flex:0 0 12px; height:12px; margin-top:1px; color:var(--accent); visibility:hidden }
th:not(.num) > .sort-button .sort-icon { margin-top:0 }
th[aria-sort] { color:var(--text) }
th[aria-sort] .sort-icon, .sort-button:enabled:is(:hover,:focus-visible) .sort-icon { visibility:visible }
th:not([aria-sort]) .sort-icon { color:var(--muted) }
th[aria-sort="ascending"] .sort-icon, th[data-sort-natural="ascending"]:not([aria-sort]) .sort-icon { transform:rotate(180deg) }
th.sortable:hover:not([aria-sort]) .sort-button:enabled .sort-icon { visibility:visible }

.c-substrate, .c-eff { border-right:1px solid var(--line) }
/* A condition note under the substrate: the name takes one line, the note the second (the row keeps its height). */
.c-substrate.has-note .clamp-2 { max-height:17px; -webkit-line-clamp:1 }
.condition-note { display:block; overflow:hidden; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); text-overflow:ellipsis; white-space:nowrap }
/* A temperature caution (the table has no temperature column): the tan "!" with its short words, T questionable, opens
   the line under the substrate, before any other note; in a Substrate column at its narrowest the words end in "…". */
.condition-note .value-flag { display:inline-flex; max-width:100%; align-items:center; gap:3px; width:auto; height:auto; background:none; box-shadow:none; color:var(--caution); vertical-align:top }
.condition-note .value-flag::before { display:grid; flex:0 0 14px; place-items:center; width:14px; height:14px; border-radius:50%; background:var(--caution-mark); box-shadow:inset 0 0 0 1px var(--caution-ring); color:var(--text) }
.condition-note .value-flag .visually-hidden { position:static; width:auto; min-width:0; height:auto; margin:0; clip:auto; clip-path:none; text-overflow:ellipsis }
.num { text-align:right; white-space:nowrap }
.c-ec { white-space:nowrap }

/* Names wrap to two lines between words; the full name is in the tooltip. Only a name with a word longer than its
   column is hyphenated (.hyphenate, set by the script that fits the columns), because hyphens:auto would also split
   words that fit on the next line; a break inside a word is the last resort. SMILES and sequences may break anywhere. */
.clamp-2 { display:-webkit-box; max-height:34px; overflow:hidden; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow-wrap:break-word; white-space:normal }
/* A hyphenated word keeps at least 3 letters on each side and 7 in all (round 17 fix pass: no "…n-" / "e"); a locant
   that begins a word keeps to it ("4-Aminoacetophenone", .locant, set by the script). */
.clamp-2.hyphenate { -webkit-hyphens:auto; hyphens:auto; hyphenate-limit-chars:7 3 3; -webkit-hyphenate-limit-before:3; -webkit-hyphenate-limit-after:3 }
.locant { white-space:nowrap }
/* While the script measures each cell's natural width (one layout,never painted). */
table.measuring .sort-button { width:max-content }
table.measuring .clamp-2 { display:inline-block; max-width:none; white-space:nowrap }
table.measuring .primary-cell .enzyme-form { max-width:none }
table.measuring .metric-with-note { flex-wrap:nowrap; max-width:none }
table.measuring .state-badge { display:inline-grid; max-width:none }
table.measuring .state-tags { max-width:none; overflow:visible }
th.c-open, td.c-open { padding-left:0; padding-right:12px; text-align:right }
tbody tr { height:44px; cursor:pointer; transition:background-color 120ms ease }
tbody tr:nth-child(even) { background:var(--surface-3) }
tbody tr:hover, tbody tr:focus-visible { background:var(--hover) }
tbody tr:focus-visible { position:relative; z-index:1; outline:2px solid var(--accent); outline-offset:-2px }

/* The open record's row (painted on the cells,so the sticky column carries it). */
tbody tr.selected td { background:var(--accent-tint) }
tbody tr.selected td:first-child { box-shadow:inset 3px 0 0 var(--accent) }
tbody tr.selected .row-arrow { color:var(--accent) }
.primary-cell { min-width:0 }
.primary-cell strong { color:var(--accent); font-weight:500 }
/* A variant's line under the name, never clipped by it; the name then keeps one line, so every row keeps one height.
   Phones show it on its own line under the name (td.c-form, hidden in the table). Round 17 (the user: the boxed code
   was hard to understand): plain words, no box, "variant" muted and the mutation in the darker grey of secondary text
   with tabular figures, 12/16px (the old tag's 16px box), a long list cut with "…" (the title and the record give it
   whole, with the substitutions in words). */
.enzyme-form { display:inline-block; max-width:100%; overflow:hidden; color:var(--text-2); font-size:var(--fs-12); font-weight:400; font-variant-numeric:tabular-nums lining-nums; line-height:var(--lh-12); text-overflow:ellipsis; white-space:nowrap; vertical-align:top }
/* "variant" muted, and "variant, not specified" muted whole (it names no mutation). */
.enzyme-form .form-word { color:var(--muted) }
.primary-cell .enzyme-form { display:block; width:max-content; margin-top:2px }
.clamp-2.has-form { max-height:17px; -webkit-line-clamp:1 }
td.c-form { display:none }
/* A value's label for phone cards; the table's headings name its columns. */
.card-label { display:none }
.row-arrow { color:var(--muted); font-size:var(--fs-20) }

/* A value and its markers (no unit,calc.,a caution) share one line. */
.metric-with-note { display:inline-flex; flex-wrap:wrap; justify-content:flex-end; align-items:baseline; gap:0 4px; max-width:100%; vertical-align:middle; white-space:nowrap }
.metric-origin, .metric-inline-unit, .metric-unit-missing, .source-efficiency-value small { display:inline; color:var(--muted); font-size:var(--fs-12); font-style:normal; font-weight:400; line-height:1.2; white-space:nowrap }
.metric-unit-missing { color:var(--caution); font-weight:500 }
:is(.metric-origin,.metric-inline-unit,.metric-unit-missing)[title] { cursor:help }

.scientific-number { display:inline-block; white-space:nowrap }
.scientific-number sup { position:relative; top:-0.1em; margin-left:1px }

/* A caution: a tan "!" disc beside the value (BPG tan with its 1px darker ring, the "!" in ink); the words are in its
   tooltip. */
.value-flag { position:relative; display:inline-grid; flex:0 0 14px; place-items:center; align-self:center; width:14px; height:14px; border-radius:50%; background:var(--caution-mark); box-shadow:inset 0 0 0 1px var(--caution-ring); color:var(--text); cursor:help }
.value-flag::before { content:"!"; content:"!" / ""; font-size:var(--fs-12); font-weight:600; line-height:1 }

/* Placeholder rows while the first records load. */
.skeleton-row, .skeleton-row:hover { cursor:default; background:var(--bg) }
.skeleton-row span { display:block; width:68%; max-width:180px; height:10px; border-radius:4px; background:var(--line-soft) }
.skeleton-row:nth-child(even) span { width:52% }
.skeleton-row td.num span { width:44%; margin-left:auto }
.skeleton-row td.c-open span { display:none }

.loading-row, .loading-row:hover, .empty-row, .empty-row:hover { height:auto; cursor:default; background:var(--bg) }
.loading-row td, .empty-row td { border-right:0; padding:28px 16px }
/* One column that may be narrower than its longest button, so a long "Remove ..." button wraps inside a 320px table
   instead of running past it. */
.load-notice { display:grid; grid-template-columns:minmax(0,1fr); gap:6px; max-width:520px; margin:0 auto; border-left:3px solid var(--caution); background:var(--caution-tint); padding:14px 16px; color:var(--caution-ink); font-size:var(--fs-13); line-height:1.5; text-align:left }
.load-notice strong { color:var(--caution-ink) }
.load-notice .button { width:max-content; margin-top:4px; border-color:var(--caution-line) }
.load-notice.empty-notice { border-left-color:var(--line-strong); background:var(--surface-2); color:var(--text-2) }
.load-notice.empty-notice strong { color:var(--text) }
.load-notice.empty-notice .button { border-color:var(--line-strong) }
.empty-actions { display:flex; flex-wrap:wrap; gap:8px }
.empty-actions .button { max-width:100%; white-space:normal; text-align:left }
.catalog-load-failed .records-title { display:flex; flex-wrap:wrap }
.catalog-load-failed .records-title > strong, .catalog-load-failed .records-title > span { flex-basis:100% }
.catalog-load-failed .table-wrap table { min-width:0 !important }
.catalog-load-failed .table-wrap colgroup, .catalog-load-failed .table-wrap thead { display:none }

/* Review result (round 17, "words, not shapes"; the user: the dots and squares looked AI-made): the result is a word in
   its colour's text shade (Accepted navy, Not confirmed terracotta, Not checked slate grey, Disputed deep red), with
   human-checked's 12px green check right after it ("Accepted ✓", read out "human-checked"); under it, in 12px, where the
   record comes from: "from paper" in Read from the paper's dark cyan, or "not re-read" and its source in muted grey,
   then "corrected" or "no paper linked". No dot, square or pill: the words carry the colour and say what it means, so
   the column also reads in greyscale. A fixed height keeps rows even. */
td.c-status { text-align:left }
.state-badge { display:grid; grid-template-rows:18px auto; align-content:center; justify-items:start; height:34px; min-width:0; max-width:100%; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13); white-space:nowrap }
.state-label { display:inline-flex; align-items:center; gap:3px; color:var(--status-ink,var(--text)); font-weight:500 }
.state-badge.accepted { --status-ink:var(--st-accepted-ink) }
.state-badge.review { --status-ink:var(--st-pending-ink) }
.state-badge.unresolved { --status-ink:var(--st-unverified-ink) }
.state-badge.disputed { --status-ink:var(--st-disputed-ink) }
.state-tags { max-width:100%; overflow:hidden; text-overflow:ellipsis; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
/* No spaces in the separator, so each tag stays one box; it stays grey beside a coloured tag. */
.state-tag + .state-tag::before { content:"\00b7"; content:"\00b7" / ""; margin:0 3px; color:var(--muted); font-weight:400 }
/* Read from the paper's words in its dark cyan (the counts band's number, the record's status line, its chip, the
   sidebar's option, the Guide): the source is said in words, never by a square. */
.state-tag.source-paper { color:var(--src-paper-ink) }
.check-icon { display:inline-block; width:1em; height:1em; vertical-align:-0.14em }
/* human-checked as a tag (the Guide's legend): a small check and the word in green. */
.state-tag.human-checked { color:var(--checked); font-weight:500 }
.state-tag.human-checked .check-icon { margin-right:2px }
/* The check after the review result, in every table, card and width (the table measures it with the word). */
.state-check { display:inline-flex; flex:0 0 auto; color:var(--checked) }
.state-check .check-icon { width:12px; height:12px; vertical-align:0 }

.pagination { display:flex; min-height:48px; flex-shrink:0; align-items:center; justify-content:flex-end; gap:12px; border-top:1px solid var(--line); background:var(--surface-3); padding:6px 12px; color:var(--text-2); font-size:var(--fs-13) }
.pagination select { width:64px }
#pageLabel { margin-left:auto; min-width:116px; text-align:center }
/* The license and how to cite, said once for every record (round 17; the record panel no longer repeats them): one quiet
   line centred between Records per page and the page range. Phones and a table beside an open record on a laptop have
   no room for it in the bar: there it is not shown (the Guide and the downloads say it). */
.table-licence { flex:1 1 auto; min-width:0; margin:0; overflow:hidden; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); text-align:center; text-overflow:ellipsis; white-space:nowrap }
.table-licence + #pageLabel { margin-left:0 }
.table-licence a { color:inherit; text-decoration:underline; text-decoration-color:var(--line-strong); text-decoration-thickness:1px; text-underline-offset:2px }
.table-licence a:hover { color:var(--text); text-decoration-color:currentColor }

/* The open record (DESIGN.md "Record Details"): a column on desktop, a dialog on smaller screens. A sticky header (A),
   then sections B-H, each after a soft rule with a 14px heading and a definition list (112px terms in 12px muted,
   14px values); the source's own fields last. */
.detail-panel { display:none; position:relative; grid-column:3; grid-row:1; min-height:0; max-height:100%; border-left:1px solid var(--line); overflow:auto; overscroll-behavior:contain }
body.detail-open .detail-panel { display:block }
@media (min-width: 1024px) {
  body.detail-open .workbench { grid-template-columns:var(--filter-col) minmax(0,1fr) var(--panel-w) }
}
#detailContent { padding:0 0 8px }
.detail-load-status { margin:0; padding:16px 20px }
/* While a record loads: its header at once; the status line and a quiet outline of the values only after a moment, so a
   quick load does not flash. */
.detail-loading { animation:detail-loading-in 160ms ease-out 240ms both }
.detail-loading .detail-load-status { padding-bottom:4px }
.detail-skeleton { display:grid; gap:12px; padding:12px 20px 16px }
.detail-skeleton span { display:block; height:12px; border-radius:2px; background:var(--line-soft) }
.detail-skeleton span:nth-child(1) { width:28% }
.detail-skeleton span:nth-child(2) { width:86% }
.detail-skeleton span:nth-child(3) { width:72% }
.detail-skeleton span:nth-child(4) { width:80% }
@keyframes detail-loading-in { from { opacity:0 } to { opacity:1 } }
@media (prefers-reduced-motion: reduce) { .detail-loading { animation:none } }
.detail-top { position:sticky; top:0; z-index:2; display:grid; gap:4px; border-bottom:1px solid var(--line); background:var(--bg); padding:16px 56px 12px 20px }
.detail-top h2 { margin:0 0 2px; color:var(--text); font-size:var(--fs-20); font-weight:600; line-height:var(--lh-20); min-width:0; overflow-wrap:break-word }
.detail-top h2.long-name { font-size:var(--fs-16); line-height:var(--lh-16) }
/* The name wraps between its parts only, a short locant kept with the part after it (detailNameHtml). */
.detail-top h2 .name-part { display:inline-block; max-width:100% }
.detail-top h2:focus { outline:none }
.detail-top h2:focus-visible { outline:2px solid var(--accent); outline-offset:2px }
/* Focused after a click or by a link that opens the record (for screen readers), the heading shows no ring. */
.detail-top h2.quiet-focus:focus-visible { outline:none }
.detail-top p { margin:0; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13); overflow-wrap:break-word }
.detail-form { display:inline-block; max-width:100% }
/* The variant as the table sets it (round 17): the mutation plain in --text-2 with tabular figures, its substitutions in
   words muted and in brackets ("Variant E124Q (Glu124 → Gln)"); the list wraps after a "/" (<wbr>) or between words. */
.detail-subtitle .mutation { color:var(--text-2); font-variant-numeric:tabular-nums lining-nums; overflow-wrap:anywhere }
.detail-subtitle .mutation-words { color:var(--muted) }
.detail-top p.detail-substrate { display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow:hidden; color:var(--text) }
.detail-substrate > span:first-child { color:var(--muted) }
.detail-top p.detail-condition-note { margin-top:-2px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.detail-top p.detail-key { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 6px; margin-top:2px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.detail-key code { font-family:var(--font-mono); overflow-wrap:anywhere }
.detail-key .copy-link { padding:0; font-size:var(--fs-12); font-weight:500 }
/* Copy link, Show and Copy are at least 24px tall to touch (WCAG 2.5.8); a negative margin keeps their lines as they were. */
.detail-key .copy-link { min-height:24px; margin-block:-4px }
/* The title's buttons at its top right: ‹ and › open the record before or after this one in the results, × closes it.
   The title keeps their width clear (the header's 56px and 56px more), so a long name wraps before them. */
.detail-title { padding-right:56px }
.detail-title-buttons { position:absolute; top:12px; right:12px; display:flex; align-items:center }
.record-step { width:28px }
.detail-section { border-top:1px solid var(--line-soft); padding:16px 20px }
.detail-top + .detail-section { border-top:0 }
.detail-section h3 { margin:0 0 12px; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.detail-kv { display:grid; gap:6px; margin:0 }
.kv-line { display:grid; grid-template-columns:112px minmax(0,1fr); column-gap:12px; align-items:baseline }
.kv-line > dt { color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.kv-line > dd { min-width:0; margin:0; color:var(--text); font-size:var(--fs-14); line-height:var(--lh-14); overflow-wrap:break-word }
.reference-list { display:grid; grid-template-columns:minmax(0,1fr); justify-items:start; gap:2px }
/* A record that names several papers: each paper's ID, then how many records of it CatLog has; the link moves to the
   next line whole when it does not fit beside the ID. */
.paper-records-item { max-width:100%; overflow-wrap:anywhere }
.paper-records-item .paper-records-link { display:inline-block; max-width:100%; white-space:normal }
.paper-records-sep, .paper-records-only { color:var(--muted) }
/* A long DOI breaks inside the panel instead of widening it. */
.reference-link { max-width:100%; overflow-wrap:anywhere; text-decoration-line:underline; text-decoration-color:var(--accent-line); text-underline-offset:2px }
.reference-link::after { content:"\2197"; content:"\2197" / ""; display:inline-block; margin-left:4px; color:var(--muted); font-size:var(--fs-12); text-decoration:none }
.identity-how { color:var(--text-2) }
/* The Guide link after the Method sentence moves to the next line whole when it does not fit, and wraps only when a line
   is narrower than the link (a phone of 361-389px held it on one line past the panel's edge). */
.method-link { display:inline-block; max-width:100%; white-space:normal }
.condition-list { display:grid; gap:4px; min-width:0; margin:0; padding:0 0 0 14px; color:var(--text); overflow-wrap:break-word }
.condition-list li::marker { color:var(--muted) }
/* An item may be narrower than its longest word ("phosphoenolpyruvate/pyruvate"), which then breaks, so a 320px phone
   does not scroll the record sideways. */
.condition-list > li { min-width:0 }
/* A listed range breaks only after its dash or before its unit (each end is one unbroken number), so it fits at 320px. */
.source-efficiency-value { display:grid; gap:2px }
.source-efficiency-value .listed-end { white-space:nowrap }
.measurement-listed { margin-top:12px }

/* Status line, in the table's words and colours (round 17: no dot or square): the review result (13px/600) in its
   colour's text shade (--status-ink, set on the line), "✓ human-checked" 6px after it, then the tags: "from paper" in
   Read from the paper's dark cyan or "not re-read", "BRENDA" in grey, "corrected", "no paper linked". Each tag's "·"
   (muted, so the line's three hues stay quiet) sits in the 12px gap before it; a tag that wraps starts its line, where its "·" falls left of the line and is
   clipped, so no line starts or ends with a "·" (the line has no side padding of its own: on phones its margins keep
   it off the panel's edges). */
.detail-status { display:flex; flex-wrap:wrap; align-items:center; gap:2px 12px; margin-top:2px; overflow-x:clip }
.detail-status > span { position:relative; white-space:nowrap }
.detail-status > span + span::before { content:"\00b7"; content:"\00b7" / ""; position:absolute; top:0; right:100%; width:12px; color:var(--muted); font-weight:400; text-align:center }
.detail-status-word { color:var(--status-ink,var(--text)); font-weight:600 }
.detail-status > .detail-status-checked { margin-left:-6px; color:var(--checked); font-weight:500 }
.detail-status > .detail-status-checked::before { content:none }
.detail-status-checked .check-icon { margin-right:3px }
.detail-status-source { color:var(--src-paper-ink) }
.human-review-line > dd .check-icon { margin-right:4px; color:var(--checked) }

/* B. Values: one table (Parameter | Value | Unit | As printed | Where), numbers right-aligned in 16px/600. */
.values-table { width:100%; min-width:0; border-collapse:collapse; table-layout:auto; font-variant-numeric:tabular-nums lining-nums }
.values-table tr:nth-child(n) { height:auto; background:none; cursor:auto }
.values-table :is(th,td) { position:static; height:auto; border-bottom:1px solid var(--line-soft); background:none; padding:6px 8px; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13); text-align:left; vertical-align:baseline; white-space:normal }
.values-table :is(th,td):first-child { padding-left:0 }
.values-table :is(th,td):last-child { padding-right:0 }
.values-table thead th { border-bottom-color:var(--line); padding-top:0; color:var(--text-2); font-size:var(--fs-12); font-weight:600; line-height:var(--lh-12); vertical-align:bottom }
.values-table tbody th { font-weight:400; white-space:nowrap }
/* Parameter, Value and Unit take what they need; As printed (or a comparison's result) takes the rest. */
.values-table :is(thead th:first-child, tbody th, .vt-value, .vt-unit) { width:1% }
.values-table .vt-value { text-align:right; white-space:nowrap }
.values-table td.vt-value .vt-number { font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.values-table td.vt-value .metric-origin { margin-left:4px }
.values-table td.vt-value .value-flag { margin-left:6px; vertical-align:-1px }
/* A value a human reviewer approved: a small green check after the number (its meaning is the first note under the table). */
.value-approved, .value-approved-key { color:var(--checked) }
.values-table td.vt-value .value-approved { margin-left:4px; font-size:var(--fs-12); font-weight:400 }
.value-approved .check-icon { width:12px; height:12px; vertical-align:-1px }
.value-approved-key .check-icon { margin-right:4px; vertical-align:-0.12em }
/* A row without calc. or "!" keeps their space unseen, so every number in the column ends at the same place. */
.values-table .vt-ghost { visibility:hidden }
/* The Value heading ends where the numbers end: unseen copies of the check, calc. and "!" spaces its rows keep, taking
   width but no height (the heading row keeps its height). */
.values-table th.vt-value .vt-head { white-space:nowrap }
.values-table th.vt-value .vt-ghost { display:inline-block; height:0; overflow:hidden; vertical-align:baseline }
.values-table th.vt-value .value-approved { margin-left:4px }
.values-table th.vt-value .metric-origin { margin-left:4px }
.values-table th.vt-value .metric-origin::before { content:"calc." }
.values-table th.vt-value .value-flag { margin-left:6px }
.values-table .vt-unit { color:var(--muted); font-size:var(--fs-12); white-space:nowrap }
.values-table .vt-unit small { font-size:var(--fs-12) }
/* Without As printed (an older record), Unit takes the rest of the width. */
.values-table.vt-no-printed .vt-unit { width:auto }
.values-table caption { padding:0 0 8px; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12); text-align:left; overflow-wrap:anywhere }
.values-table .vt-where { max-width:9em; color:var(--text-2); font-size:var(--fs-12); overflow-wrap:anywhere }
.values-table .vt-where.vt-short { white-space:nowrap }
/* the narrowest phones (fonts differ by system): units may wrap, cells come closer, As printed breaks anywhere */
@media (max-width: 360px) {
  /* fixed columns: the table can never be wider than its section, whatever the system font */
  .values-table { table-layout:fixed }
  .values-table :is(thead th:first-child, tbody th) { width:24% }
  .values-table :is(thead th:nth-child(2), .vt-value) { width:34% }
  .values-table :is(thead th:nth-child(3), .vt-unit) { width:17% }
  .values-table :is(th,td) { overflow-wrap:anywhere }
  .values-table tbody th { white-space:normal }
  .values-table .vt-value { white-space:normal }
  /* A number in 14px keeps its check beside it: one too long for the cell (1.28 × 10⁻⁴ in a wide font) wraps before
     "× 10", never between the number and its check and never into Unit. The check hangs in a 16px margin of its own,
     so every line of every number ends at the same place. */
  .values-table td.vt-value .vt-number { font-size:var(--fs-14); line-height:var(--lh-14); white-space:nowrap }
  .values-table td.vt-value .scientific-number { display:inline; white-space:normal }
  .values-table.vt-checks td.vt-value .vt-number { padding-right:16px }
  .values-table.vt-checks td.vt-value .vt-number > .value-approved { margin-right:-16px }
  .values-table.vt-checks td.vt-value .vt-number > .value-approved.vt-ghost { display:none }
  .values-table thead th { overflow-wrap:normal; hyphens:auto }
  .values-table td.vt-value :is(.metric-origin, .value-flag) { display:block; margin-left:0 }
  .values-table .vt-unit { white-space:normal }
  .values-table td:last-child { overflow-wrap:anywhere }
}
.values-table small { display:block; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.values-table :is(.vt-value,.vt-unit) small { display:inline }
.values-table small.vt-where-inline { display:none }
.values-table .vt-printed { overflow-wrap:break-word }
/* An exponent (min⁻¹, 10⁶) stays on the line of its unit or number. */
.values-table sup { white-space:nowrap }
.values-empty { margin:0; color:var(--text-2); font-size:var(--fs-13) }
.value-notes { display:grid; gap:4px; margin:12px 0 0; padding:0; list-style:none; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.value-notes .metric-origin { margin-right:4px; font-size:var(--fs-12) }
/* "see Human review below": a link-like button that shows that row of Review and audit (outlined a moment, as a note) */
.value-notes .review-row-link { font-size:inherit; line-height:inherit; vertical-align:baseline }
.human-review-line { scroll-margin-block:12px; border-radius:2px }
.human-review-line:is(:focus-visible,.is-target) { outline:2px solid var(--accent); outline-offset:2px }
button.value-flag { border:0; padding:0; cursor:pointer }
.flag-notes { display:grid; gap:6px; margin:12px 0 0; padding:0; list-style:none }
.flag-notes li { display:flex; gap:8px; border:1px solid var(--caution-line); border-radius:var(--radius); background:var(--caution-tint); padding:8px 10px; color:var(--caution-ink); font-size:var(--fs-13); line-height:var(--lh-13) }
.flag-notes .value-flag { align-self:start; margin-top:2px }
.flag-notes li:is(:focus-visible,.is-target) { outline:2px solid var(--caution); outline-offset:1px }
.printed-lines { display:grid; gap:8px; margin-top:12px }
.printed-line-disclosure > summary { width:max-content; max-width:100%; cursor:pointer; color:var(--accent); font-size:var(--fs-12); font-weight:500; list-style:none }
.printed-line-disclosure > summary::-webkit-details-marker { display:none }
.printed-line-disclosure > summary::before { content:"+"; content:"+" / ""; display:inline-block; width:12px; color:var(--muted) }
.printed-line-disclosure[open] > summary::before { content:"\2212"; content:"\2212" / "" }
.printed-line-disclosure > :not(summary) { margin-top:6px }
.printed-line-note { margin:4px 0 0; color:var(--muted); font-size:var(--fs-12) }
.evidence-note-list { display:grid; gap:12px }
.evidence-note-item, .evidence-note-plain { border-left:2px solid var(--line); padding-left:10px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13); min-width:0; overflow-wrap:break-word }
.evidence-note-plain { margin:0 }
.evidence-note-item .kv-line > dd { color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }

/* E. A sequence or SMILES: its length, then Show and Copy; Show opens it under the row. */
.reveal-line { display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 12px }
/* A long run with no spaces (28 substitutions joined by "/") wraps inside the record instead of widening it. */
.reveal-summary { min-width:0; overflow-wrap:anywhere }
.row-actions { display:inline-flex; gap:12px }
.row-actions .text-button, .copy-button { border:0; background:transparent; color:var(--accent); cursor:pointer; padding:0; font-size:var(--fs-13); font-weight:500 }
.row-actions .text-button { min-height:24px; margin-block:-2px }
.row-actions .text-button:hover, .copy-button:hover { text-decoration:underline }
.reveal-note { display:block; margin-top:2px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.copy-field { display:block; min-width:0; margin-top:6px }
.copy-field code { display:block; max-height:96px; overflow:auto; border:1px solid var(--line-soft); border-radius:var(--radius); background:var(--surface-2); color:var(--text); padding:8px 10px; font:var(--fs-12)/var(--lh-12) var(--font-mono); overflow-wrap:anywhere; white-space:pre-wrap }

/* Notes a source or the earlier review left: folded under their section. */
.detail-notes { margin-top:12px; border-top:1px solid var(--line-soft); padding-top:10px }
.detail-notes > summary { display:flex; align-items:center; cursor:pointer; color:var(--text); font-size:var(--fs-13); font-weight:500; list-style:none }
.detail-notes > summary::-webkit-details-marker { display:none }
.detail-notes > summary::before { content:"+"; content:"+" / ""; width:12px; margin-right:8px; color:var(--muted) }
.detail-notes[open] > summary::before { content:"\2212"; content:"\2212" / "" }
.detail-notes > :not(summary) { margin-top:8px }

/* G. Against the databases (round 9 brief, section 4): the paper's note in a box (--surface-2, 1px --line, 13px), the
   values a database lists with the same number in 13px lines, then one folding note per other value (13px summary:
   the parameter, which databases list what, the result; a body of 13px lines and a definition list with 112px labels,
   96px on phones), a 12px caution line under them on a record with a Different number and links to records like this
   one; the compared databases are named once, in the heading's "?" box. A 10px square in the result colour beside each
   result word (colour never alone: corrects --chg-magnitude, differs --cmp-differs, same other label --bar-neutral,
   not in the databases --cmp-new, same --cmp-same). Everything wraps at any width. An earlier record's corrections: one
   list like the record's others, the field beside before -> after and the kind of change, then the Before line. */
.cmp-paper-note { margin:0 0 12px; border:1px solid var(--line); border-radius:var(--radius); background:var(--surface-2); padding:8px 12px; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13); overflow-wrap:break-word }
.cmp-paper-note p { margin:0 }
.cmp-paper-note strong { font-weight:600 }
.cmp-paper-note .cmp-paper-links { margin-top:6px }
.cmp-same-line { display:flex; align-items:baseline; gap:8px; margin:0 0 6px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13); overflow-wrap:break-word }
.cmp-same-line > span:last-child { min-width:0 }
.cmp-notes { border-top:1px solid var(--line-soft) }
.cmp-same-line + .cmp-notes { margin-top:8px }
.cmp-calc-line { margin:8px 0 0; color:var(--muted); font-size:var(--fs-13); line-height:var(--lh-13); overflow-wrap:break-word }
.cmp-same-line + .cmp-calc-line { margin-top:0 }
.cmp-note { margin:0; border-bottom:1px solid var(--line-soft); padding:8px 0; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13); overflow-wrap:break-word }
.cmp-note > summary { position:relative; display:block; cursor:pointer; padding-left:16px; list-style:none }
.cmp-note > summary::-webkit-details-marker { display:none }
.cmp-note > summary::before { content:"+"; content:"+" / ""; position:absolute; left:0; color:var(--muted) }
.cmp-note[open] > summary::before { content:"\2212"; content:"\2212" / "" }
p.cmp-note { padding-left:16px }
.cmp-note:is(:focus-visible,.is-target), .cmp-note > summary:focus-visible { outline:2px solid var(--accent); outline-offset:2px }
.cmp-sep { color:var(--muted) }
/* The result keeps its square beside its first word and wraps inside the note: "Different number (exact factor, not yet
   checked)" is wider than a 320px phone's note in any font, and a 375px one's in DejaVu. */
.cmp-note .cmp-result { white-space:normal; max-width:100% }
.cmp-note-body { margin:6px 0 0 16px }
.cmp-note-body .cmp-line { margin:0; color:var(--text-2) }
.cmp-note-body .cmp-facts { margin-top:6px }
.cmp-facts .kv-line > dd { color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
/* The checker's own notes on a value, folded and muted under its line: "What the AI check found" (12px, a + or − before it). */
.cmp-how { margin-top:6px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.cmp-how > summary { display:inline-block; cursor:pointer; list-style:none; color:var(--muted) }
.cmp-how > summary::-webkit-details-marker { display:none }
.cmp-how > summary::before { content:"+"; content:"+" / ""; display:inline-block; width:12px; color:var(--muted) }
.cmp-how[open] > summary::before { content:"\2212"; content:"\2212" / "" }
.cmp-how > summary:focus-visible { outline:2px solid var(--accent); outline-offset:2px }
.cmp-how > p { margin:4px 0 0; overflow-wrap:anywhere }
.cmp-pointer { margin:8px 0 0; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); overflow-wrap:break-word }
.cmp-pointer + .cmp-pointer { margin-top:2px }
.cmp-pointer .cmp-pointer-link { font-size:inherit; line-height:inherit; vertical-align:baseline }
/* The record's "?" (Against the databases) sits 8px after its heading's words, centred on its 20px line (the 24px circle
   overhangs it by 2px each way); its box opens under the heading. A record with a Different number says the caution
   in one 12px line under its notes. */
.detail-section.has-about > h3 { display:inline-block; margin-right:var(--sp-2); vertical-align:top }
.detail-section.has-about > .section-about { margin:-2px 0; vertical-align:top }
.detail-about { margin:0 0 12px; overflow-wrap:break-word }
.cmp-caution-line { margin-top:8px }
.cmp-intro.section-text { margin-bottom:12px; font-size:var(--fs-13); line-height:var(--lh-13) }
.cmp-where-once { margin:8px 0 0; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); overflow-wrap:break-word }
.cmp-list { gap:0 }
.cmp-list > .cmp-item { border-bottom:1px solid var(--line-soft); padding:8px 0 }
.cmp-list > .cmp-item:first-child { padding-top:2px }
.cmp-item > dt { color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-14) }
.cmp-item > dd { display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 12px }
.cmp-value { font-variant-numeric:tabular-nums lining-nums; overflow-wrap:anywhere }
.cmp-value small { color:var(--muted); font-size:var(--fs-12) }
.cmp-value strong { font-weight:600 }
.cmp-arrow { color:var(--muted) }
.cmp-item > dd > :is(.cmp-line, small) { flex-basis:100%; min-width:0 }
.cmp-item .cmp-line { margin-top:0; font-size:var(--fs-13); line-height:var(--lh-13) }
.cmp-item > dd > small { display:block; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); overflow-wrap:break-word }
.cmp-explore { margin:8px 0 0; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.cmp-result { display:inline-flex; align-items:baseline; gap:6px; min-width:0 }
.cmp-result strong { font-weight:600 }
.cmp-factor { white-space:nowrap }
.cmp-mark { flex:0 0 10px; width:10px; height:10px; border:1px solid var(--line-strong); background:var(--bg) }
.cmp-mark.cmp-same { border-color:var(--cmp-same); background:var(--cmp-same) }
.cmp-mark.cmp-differs { border-color:var(--cmp-differs); background:var(--cmp-differs) }
.cmp-mark.cmp-new { border-color:var(--cmp-new-ring); background:var(--cmp-new) }
.cmp-mark.cmp-magnitude { border-color:var(--chg-magnitude); background:var(--chg-magnitude) }
.cmp-mark.cmp-precision { border-color:var(--cmp-other-ring); background:var(--chg-precision) }
.cmp-mark.cmp-other { border-color:var(--cmp-other-ring); background:var(--cmp-other) }
.cmp-mark.cmp-neutral { border-color:var(--bar-neutral); background:var(--bar-neutral) }
.cmp-line { display:block; margin-top:2px; color:var(--text-2) }
.section-text { margin:0; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.section-note { margin:8px 0 0; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }

/* The record's footer: the actions side by side (Download record is the primary button), then one muted footnote with
   the license and the snapshot (date and data ID), each on its own line. */
.detail-footer { border-top:1px solid var(--line-soft); padding:16px 20px 20px }
.detail-actions { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px }
.detail-actions .button { min-height:36px }
.detail-footnote { display:grid; gap:2px; margin:12px 0 0; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); overflow-wrap:break-word }
/* A section's one Guide link (Checks: "How CatLog reads a value →"), under its rows. */
.section-link { margin:10px 0 0; font-size:var(--fs-13); line-height:var(--lh-13) }
.button.primary { border-color:var(--accent); background:var(--accent); color:var(--bg) }
.button.primary:hover:not(:disabled) { border-color:var(--accent-hover); background:var(--accent-hover); text-decoration:none }
.detail-load-error { display:grid; gap:6px; margin:16px 20px; border-left:3px solid var(--caution); background:var(--caution-tint); padding:12px 14px; color:var(--caution-ink); font-size:var(--fs-13) }
.detail-load-error strong { color:var(--caution-ink) }
.detail-load-error .button { width:max-content; margin-top:6px; border-color:var(--caution-line) }

/* Stats, Team and Guide pages. */
/* Each view scrolls inside itself (the header stays put); positioned, so nothing absolutely placed in it (screen-reader
   text, chart marks) can reach past it and make the whole document scroll. */
.guide-view, .stats-view, .team-view { position:relative; flex:1; min-height:0; overflow:auto; border-bottom:1px solid var(--line); background:var(--bg) }
/* Stats (design spec section 6): one centred column, a 12-column grid, numbered figures and tables. */
.stats-shell { max-width:1200px; margin:0 auto; padding:var(--sp-6) var(--sp-5); font-variant-numeric:tabular-nums lining-nums }
.stats-heading { display:flex; align-items:baseline; justify-content:space-between; flex-wrap:wrap; gap:var(--sp-2) var(--sp-5) }
.stats-heading h1 { margin:0; font-size:var(--fs-24); font-weight:600; line-height:var(--lh-24) }
.stats-heading .snapshot-date { color:var(--muted); font-size:var(--fs-14); line-height:var(--lh-14) }
.stats-heading p { margin:var(--sp-1) 0 0; color:var(--muted); font-size:var(--fs-13); line-height:var(--lh-13) }
/* On this page: the parts in one line under the title, each a link to its part (#stats-<key>), wrapping between parts
   only (a part keeps its number and name together), so on a phone, where Stats runs 17 screens, a part is one tap away. */
/* On this page: the Guide's contents (one component, round 15 polish: Stats' had been one inline line whose "·" separators
   ended each wrapped line on a phone): a 13px --muted label on its own line, then the parts as a wrapped row of 14px/500
   links 20px apart, 28px targets, no separators; Stats' links keep their parts' numbers, muted. */
.stats-contents { display:block; margin:var(--sp-3) 0 0 }
.stats-contents-title { display:block; margin:0 0 6px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.stats-contents ul { display:flex; flex-wrap:wrap; gap:4px 20px; margin:0; padding:0; list-style:none }
.stats-contents li { display:flex; padding:0; white-space:nowrap }
.stats-contents a { display:inline-flex; min-height:28px; align-items:center; color:var(--accent); font-size:var(--fs-14); font-weight:500; line-height:var(--lh-14); text-decoration:none }
.stats-contents a:hover, .stats-contents a:focus-visible { text-decoration:underline; text-underline-offset:3px }
.stats-contents-number { margin-right:0.3em; color:var(--muted); font-weight:400; font-variant-numeric:tabular-nums }
/* 1. At a glance: the headline band, the page's focal point. Round 14 (the user's colleague: "a bit AI-ish, with the
   glow"): a plain white card with a 1px hairline, no glow, halo, wash, gradient rule or entrance motion. The four key
   numbers (line 1, 40px, 600, tabular figures) lead by size, weight and the whitespace round them, each in its meaning
   colour; a linked number opens Browse and its whole item takes a flat tint under the pointer. */
.stats-totals { margin:var(--sp-5) 0 var(--sp-7) }
.stats-band { position:relative; overflow:hidden; border:1px solid var(--line); border-radius:var(--radius); background:var(--bg); padding:var(--sp-4) var(--sp-4) var(--sp-2) }
.stats-band > .stats-part-title { margin:0 0 var(--sp-1) var(--sp-2); border:0; padding:0 }
.stats-totals dl { display:grid; grid-template-columns:repeat(var(--stats-columns,4),minmax(0,1fr)); margin:0; padding:var(--sp-2) 0 }
.stats-totals dl + dl { border-top:1px solid var(--line-soft) }
.stats-band-words { margin:0; border-top:1px solid var(--line-soft); padding:var(--sp-2) var(--sp-3) var(--sp-1); color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-band-words b { color:var(--text-2); font-weight:600 }
.stats-total { position:relative; min-width:0; border-radius:var(--radius); padding:var(--sp-2) var(--sp-3) }
.stats-total + .stats-total::before { content:""; position:absolute; left:0; top:10px; bottom:10px; border-left:1px solid var(--line-soft) }
.stats-totals dt { color:var(--muted); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-totals dd { margin:4px 0 0; font-size:var(--fs-32); font-weight:600; line-height:var(--lh-32) }
.stats-totals dd small { display:block; margin-top:2px; color:var(--muted); font-size:var(--fs-13); font-weight:400; line-height:var(--lh-13) }
.stats-totals .stats-totals-main dd { font-size:var(--fs-40); line-height:var(--lh-40) }
.stats-totals .stats-totals-scope dd { font-size:var(--fs-20); line-height:var(--lh-20) }
.stats-total-value { color:var(--text) }
/* The key numbers in the colours Browse's counts band gives them (one meaning per colour): Records ink, Accepted
   Accepted's navy, Read from the paper the darker BPG cyan, Human review the human-checked green. */
.stats-totals-main .stats-total { --key:var(--text) }
.stats-totals-main .stats-total[data-total="accepted"] { --key:var(--st-accepted) }
.stats-totals-main .stats-total[data-total="catlog"] { --key:var(--src-paper-ink) }
.stats-totals-main .stats-total[data-total="review"] { --key:var(--checked) }
.stats-totals-main .stats-total-value { display:inline-block; color:var(--key) }
/* The key numbers line up across a row whatever wraps above them (fix pass after round 16b: at 375px in a wide font
   "Read from the paper" took two lines and its 75,000 stood 18px below 99.9%): each item's label and number are two rows
   of the band (a subgrid), so a row's labels end together and its numbers start together. */
.stats-totals .stats-totals-main > .stats-total { display:grid; grid-row:span 2; grid-template-rows:subgrid; row-gap:0; align-content:start }
/* As on Browse's counts band: the labels muted and the meaning colour on the number (round 17, "words, not shapes": no
   dot before Accepted, no square before Read from the paper). */
/* A linked number: the whole item is its target. */
a.stats-total-value { text-decoration:none }
a.stats-total-value::after { content:""; position:absolute; inset:0; border-radius:var(--radius) }
a.stats-total-value:focus-visible { outline:0 }
.stats-total:has(> dd > a.stats-total-value:focus-visible) { outline:2px solid var(--accent); outline-offset:-2px }
.stats-total:has(> dd > a.stats-total-value:hover) { background:var(--accent-tint); background:color-mix(in srgb, var(--key, var(--accent)) 9%, var(--bg)) }
/* Under the pointer the tint darkens the item's ground: its label and note step up to --text-2, so they keep AA
   contrast (muted there drops just under 4.5:1). */
.stats-total:has(> dd > a.stats-total-value:hover) :is(dt, dd small) { color:var(--text-2) }
@media (prefers-reduced-motion: no-preference) {
  .stats-total { transition:background-color 200ms ease }
}
/* The numbered parts after the band: one plain heading each, figures on a 12-column grid (two to a row from 1280px). */
.stats-charts { display:block }
.stats-part + .stats-part, .stats-part + .stats-method { margin-top:var(--sp-7) }
.stats-part-title { display:flex; align-items:center; gap:var(--sp-3); margin:0 0 var(--sp-5); border-bottom:1px solid var(--line); padding-bottom:var(--sp-3); font-size:var(--fs-20); font-weight:600; line-height:var(--lh-20) }
/* A part's number: plain muted figures before its title (no disc). */
.stats-part-number { flex:0 0 auto; min-width:1ch; color:var(--muted); font-weight:400; font-variant-numeric:tabular-nums lining-nums }
.stats-part-grid { display:grid; grid-template-columns:repeat(12,minmax(0,1fr)); gap:48px 32px; align-items:start }
.stats-part-grid > * { grid-column:span 6; min-width:0 }
.stats-part-grid > .stats-wide { grid-column:1 / -1 }
.stats-section { min-width:0 }
.stats-fig-title { margin:0 0 12px; font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.stats-narrow > .stats-fig { max-width:760px }
.stats-stack { display:grid; gap:48px; align-content:start; min-width:0 }
.stats-link, .stats-guide-link, .stats-ref-link { color:var(--accent); text-decoration:underline; text-decoration-color:var(--accent-line); text-underline-offset:3px }
.stats-link:hover, .stats-guide-link:hover, .stats-ref-link:hover { text-decoration-color:currentColor }
.stats-muted { color:var(--muted) }
.stats-num { text-align:right; white-space:nowrap }
.stats-note { margin:12px 0 0; max-width:80ch; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
/* Supplementary figures and tables (round 14; round 17: one click opens them all): one disclosure whose summary is the
   part's heading line (its number S, its title, then a muted + and "Show all 22 figures" at the line's end, "Hide" with
   a − when open); inside, groups named as the main parts, each a grid of open items as the main parts lay theirs out, an
   item's heading its number (a muted link to its own address) and its title over its figure. */
.stats-supp-all > summary { display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:4px 16px; margin:0; border-bottom:1px solid var(--line); padding-bottom:var(--sp-3); cursor:pointer; list-style:none }
/* (closed, the line ends the part: no space under its hairline but the gap to How these numbers are counted) */
.stats-supp-all[open] > summary { margin-bottom:var(--sp-5) }
.stats-supp-all > summary::-webkit-details-marker { display:none }
.stats-supp-all > summary > .stats-part-title { margin:0; border:0; padding:0 }
.stats-supp-all > summary:focus-visible { outline:2px solid var(--accent); outline-offset:4px; border-radius:2px }
.stats-supp-toggle { display:inline-flex; align-items:baseline; min-height:28px; padding-block:4px; color:var(--accent); font-size:var(--fs-14); line-height:var(--lh-14); white-space:nowrap }
.stats-supp-toggle::before { content:"+"; content:"+" / ""; display:inline-block; width:16px; color:var(--muted); font-weight:600 }
.stats-supp-all[open] > summary .stats-supp-toggle::before { content:"\2212"; content:"\2212" / "" }
.stats-supp-all > summary:hover .stats-supp-toggle > span { text-decoration:underline; text-underline-offset:3px }
.stats-supp-all[open] .stats-supp-show, .stats-supp-all:not([open]) .stats-supp-hide { display:none }
.stats-supp-group + .stats-supp-group { margin-top:var(--sp-7) }
.stats-supp-group-title { margin:0 0 var(--sp-4); border-bottom:1px solid var(--line-soft); padding-bottom:var(--sp-2); color:var(--text-2); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-supp-group > .stats-part-lead { margin:0 0 var(--sp-4) }
.stats-supp-title { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 8px; margin:0 0 12px; font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.stats-supp-number { flex:0 0 auto; color:var(--muted); font-size:var(--fs-14); font-weight:400; line-height:var(--lh-14); text-decoration:none; white-space:nowrap }
.stats-supp-number:hover, .stats-supp-number:focus-visible { color:var(--text-2); text-decoration:underline; text-underline-offset:3px }
.stats-supp-name { min-width:0 }
/* (no indent: Values by enzyme class keeps the x of Value ranges' shared log axis, so 10⁰ stands at one x in both) */
/* The supplement's former tables as figures (round 17). A list chart's name may stand indented under the row before it
   (a sub row) and every count above 0 shows at least 2px wide, a mark rather than a stray line (single-segment bars only,
   so a stacked bar's segments keep their places). */
.stats-chart-label > .stats-list-name { display:block }
.stats-chart-label > .stats-list-name.is-sub { padding-left:14px; color:var(--text-2) }
.stats-chart-label > .stats-list-name.is-sub + small { padding-left:14px }
.stats-supp .stats-track .stats-seg.is-start.is-end { min-width:2px }
/* Small multiples: panels side by side where each gets 300px, else one under another. */
.stats-panels { display:grid; grid-template-columns:repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap:32px 40px; align-items:start }
.stats-panel { min-width:0 }
/* a panel's chart keeps its names to 40% of the panel (a wide figure's 240px would leave a 360px panel no bar) */
.stats-panels .stats-panel .stats-chart:not(.stats-chart-percent) { --label-w:minmax(64px,40%) }
.stats-panel-title { display:flex; flex-wrap:wrap; align-items:baseline; gap:0 8px; margin:0 0 12px; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-panel-count { color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12) }
.stats-subs-top-title { margin-top:var(--sp-4) }
/* Short names (units, substitutions) keep their bars long: the name column is as wide as the chart's longest name (at most
   40% of the chart). It is one column for every row, the axis and the value headings (a subgrid of the chart's grid), so
   every bar of a chart starts at one x and ends at its axis's 100% (a max-content column per row had set each bar
   apart). Phones put each name above its bar, as every chart does there. */
@media (min-width: 641px) {
  .stats-supp .stats-chart:is([data-chart^="units-"], [data-chart="substitutions-top"]):not(.stats-chart-percent) { display:grid; grid-template-columns:fit-content(40%) minmax(0,1fr) var(--value-w,96px); column-gap:12px }
  .stats-supp .stats-chart:is([data-chart^="units-"], [data-chart="substitutions-top"]):not(.stats-chart-percent) > * { grid-column:1 / -1 }
  .stats-supp .stats-chart:is([data-chart^="units-"], [data-chart="substitutions-top"]):not(.stats-chart-percent) :is(.stats-chart-rows, .stats-chart-row, .stats-chart-axis, .stats-chart-head) { grid-column:1 / -1; grid-template-columns:subgrid; column-gap:12px }
}
/* Paired values by database: a dot plot, a red dot where CatLog's number corrects and a brown square where it differs,
   both opaque marks (a correction is opaque red), each with a 1px white keyline so two that meet stay apart; the All row
   stands under a hairline. */
.stats-dot, .stats-dot-key { display:block; width:10px; height:10px; border-radius:50%; background:var(--part); box-shadow:0 0 0 1px var(--bg) }
.stats-dot { position:absolute; top:3px; z-index:1; margin-left:-5px }
.stats-dot-key { display:inline-block; flex:0 0 10px; margin-top:3px }
:is(.stats-dot, .stats-dot-key).stats-part-differs { border-radius:1px; transform:scale(0.9) }
.stats-dot[data-tip]:hover { box-shadow:0 0 0 1px var(--bg), 0 0 0 3px var(--part) }
.stats-chart[data-chart="db-paired"] { --label-w:minmax(120px,40%) }
.stats-chart[data-chart="db-paired"] .stats-chart-row[data-row="db_all"] { border-top:1px solid var(--line-soft); padding-top:8px }
/* Corrections by cause and database: a heat map, each database x cause cell grey by its count (from 8% to 60% of the
   map's ink, ink numbers on it at 5:1 or more), the totals plain at the row's end and in the All row. */
.stats-table.stats-heat-table { width:auto; border-collapse:separate; border-spacing:2px }
.stats-table.stats-heat-table :is(th, td) { border:0; padding:7px 8px }
.stats-table.stats-heat-table thead th { white-space:normal }
.stats-table.stats-heat-table thead th.stats-num { min-width:56px; max-width:84px }
.stats-table.stats-heat-table tbody tr:nth-child(n) > td.stats-heat-cell { min-width:56px; border-radius:2px; background:color-mix(in srgb, color-mix(in srgb, var(--bar-neutral) 55%, var(--text)) var(--heat, 0%), var(--bg)) }
.stats-heat-cell .stats-link { color:var(--text) }
.stats-table.stats-heat-table .stats-heat-total { font-weight:600 }
.stats-table.stats-heat-table tfoot :is(th, td) { border-top:1px solid var(--line); font-weight:600 }
/* The typical wild-type enzyme: the average enzyme of Bar-Even et al. as an open ink diamond on the kcat/Km line, above
   the range and the median (no data colour: a published reference, not a count), named in the legend with the range. */
.stats-ridge-diamond { position:absolute; top:50%; z-index:3; width:9px; height:9px; margin:-4.5px 0 0 -4.5px; box-sizing:border-box; border:1.5px solid var(--text); background:var(--bg); transform:rotate(45deg) }
.stats-typical-key-diamond { display:inline-block; flex:0 0 9px; width:9px; height:9px; margin:3px 2px 0; box-sizing:border-box; border:1.5px solid var(--text); background:var(--bg); transform:rotate(45deg) }
.stats-typical-key-range { position:relative; display:inline-block; flex:0 0 22px; width:22px; height:9px; margin-top:3px }
.stats-typical-key-range::before { content:""; position:absolute; left:0; right:0; top:3px; height:3px; border-radius:2px; background:color-mix(in srgb, var(--src-paper) 55%, var(--text)) }
.stats-typical-key-range::after { content:""; position:absolute; left:6.5px; top:0; width:9px; height:9px; box-sizing:border-box; border-radius:50%; background:var(--bg); box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--src-paper) 55%, var(--text)) }
/* Single substitutions: a 20 x 20 grid of grey cells, shaded as the kcat against Km map, one-letter residues along the
   top (new) and left (wild type); beside it the facts and the commonest substitutions (under it below 1024px). */
.stats-subs { display:grid; grid-template-columns:minmax(0,440px) minmax(240px,1fr); gap:24px 48px; align-items:start }
.stats-subs-frame { display:grid; grid-template-columns:auto 16px minmax(0,1fr); color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-subs-x-title { grid-column:3; grid-row:1; margin:0 0 4px; color:var(--text); font-size:var(--fs-13); font-weight:600; line-height:var(--lh-13); text-align:center }
.stats-subs-x { grid-column:3; grid-row:2; display:grid; grid-template-columns:repeat(20,minmax(0,1fr)); padding-bottom:4px; text-align:center }
.stats-subs-y-title { grid-column:1; grid-row:3; margin:0 6px 0 0; color:var(--text); font-size:var(--fs-13); font-weight:600; line-height:var(--lh-13); text-align:center; writing-mode:vertical-rl; transform:rotate(180deg) }
.stats-subs-y { grid-column:2; grid-row:3; display:grid; grid-template-rows:repeat(20,minmax(0,1fr)); align-items:center; text-align:center }
.stats-subs-plot { position:relative; grid-column:3; grid-row:3; aspect-ratio:1 / 1; box-shadow:0 0 0 1px var(--line) }

/* A figure: plot, then "Figure N." and one sentence, then a 12px data line. */
.stats-fig { margin:0 }
.stats-fig > figcaption { display:grid; gap:4px; margin-top:12px; max-width:80ch }
.stats-fig-caption { color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-fig-caption strong { color:var(--text); font-weight:600 }

/* Colours of figure parts: fills at 60% with a 1px opaque outline (a ring colour where the fill is light). */
.stats-part-accepted { --part:var(--st-accepted) }
.stats-part-pending { --part:var(--st-pending); --part-line:var(--st-pending-ring) }
.stats-part-unverified { --part:var(--st-unverified) }
.stats-part-not-reviewed { --part:var(--st-not-reviewed) }
.stats-part-not-checked { --part:var(--st-unverified) }
.stats-part-disputed { --part:var(--st-disputed) }
.stats-part-same { --part:var(--cmp-same) }
.stats-part-differs { --part:var(--cmp-differs) }
.stats-part-new { --part:var(--cmp-new); --part-line:var(--cmp-new-ring) }
.stats-part-rounding { --part:var(--chg-precision); --part-line:var(--cmp-other-ring) }
.stats-part-magnitude { --part:var(--chg-magnitude); --part-line:color-mix(in srgb, var(--chg-magnitude) 65%, var(--text)) }
.stats-part-neutral { --part:var(--bar-neutral) }
.stats-part-caution { --part:var(--caution-mark); --part-line:var(--caution-ring) }
.stats-part-records { --part:var(--line-strong) }
.stats-part-human { --part:var(--bpg-green); --part-line:var(--checked) }
/* Between papers' bars (round 17): pairs within 2-fold in Read from the paper's cyan at 60%, 2- to 10-fold in a light
   cyan, more than 10-fold apart open (white, the cyan ring): one hue, darker for closer, as the histograms above wear it. */
.stats-part-fold-2 { --part:var(--src-paper); --part-line:var(--src-paper-ring) }
.stats-part-fold-10 { --part:color-mix(in srgb, var(--src-paper) 40%, var(--bg)); --part-line:var(--src-paper-ring) }
.stats-part-fold-more { --part:var(--bg); --part-line:var(--src-paper-ring) }
:is(.stats-seg, .stats-swatch).stats-part-fold-more { background:var(--bg) }
/* Enzyme classes: the class's colour (--ec-N), and a short bar of it before the class's number (deepened a little, so
   the light classes still show on white). */
.stats-ec-1 { --part:var(--ec-1) }
.stats-ec-2 { --part:var(--ec-2) }
.stats-ec-3 { --part:var(--ec-3) }
.stats-ec-4 { --part:var(--ec-4) }
.stats-ec-5 { --part:var(--ec-5) }
.stats-ec-6 { --part:var(--ec-6) }
.stats-ec-7 { --part:var(--ec-7) }
.stats-ec-key { display:inline-block; flex:0 0 3px; width:3px; height:12px; margin-right:5px; border-radius:2px; background:var(--part); background:color-mix(in srgb, var(--part) 85%, var(--text)); vertical-align:-1px }
/* Against the databases (part 7), as Browse colours them: same green, same number under another label mint,
   corrects red, different number brown, not in the databases cyan. A database's own "not listed" kinds (Results by
   database) are cyan three ways, never three tints: other values listed in cyan hatching, parameter not listed a light
   cyan, value in no database Not in the databases' own fill, each with the cyan ring as its outline, so they part by
   pattern and lightness in grey print too. A correction (Corrects a
   value; an earlier unit or magnitude change) is red drawn opaque, the sidebar square's own red: red at 60% (#F09386)
   is Not confirmed's salmon (#F39B7F) to the eye, and a correction must never look like a record waiting for review.
   The second way a correction is found (an exact factor found by code) is red hatching on white, never a lighter red. */
.stats-part-other-label { --part:var(--cmp-other); --part-line:var(--cmp-other-ring) }
.stats-part-corrects { --part:var(--chg-magnitude); --part-line:color-mix(in srgb, var(--chg-magnitude) 65%, var(--text)) }
.stats-part-corrects-2 { --part:var(--chg-magnitude); --part-line:var(--chg-magnitude) }
.stats-part-not-listed { --part:var(--cmp-new); --part-line:var(--cmp-new-ring) }
.stats-part-not-listed-2 { --part:color-mix(in srgb, var(--cmp-new) 45%, var(--bg)); --part-line:var(--cmp-new-ring) }
.stats-part-not-listed-hatch { --part:var(--cmp-new); --part-line:var(--cmp-new-ring) }
/* Records read from the paper wear Read from the paper's colour (BPG cyan, --src-paper, as on Browse's counts band and
   its chip), never Accepted's navy: Values per paper, the stripe inside Enzyme classes' accepted bars, the From paper
   counts (in the darker cyan) and the bars of the tables of records read from the paper. */
.stats-part-catlog, .stats-part-catlog-mark { --part:var(--src-paper); --part-line:var(--src-paper-ring) }
/* One flat fill: the colour at 60% (#RRGGBB99 on white) with a 1px opaque outline (a darker ring where the colour is
   light); a bar's outer ends are rounded 2px. */
.stats-seg, .stats-swatch { background:var(--part); background:color-mix(in srgb, var(--part) 60%, var(--bg)); box-shadow:inset 0 0 0 1px var(--part-line, var(--part)) }
/* The exceptions to the flat 60% fill, each kept apart from a colour it would otherwise meet: a correction opaque red;
   the exact-factor kind red hatching on white. */
:is(.stats-seg, .stats-swatch):is(.stats-part-corrects, .stats-part-magnitude) { background:var(--part) }
:is(.stats-seg, .stats-swatch):is(.stats-part-corrects-2, .stats-part-not-listed-hatch) { background:var(--bg); background:repeating-linear-gradient(135deg, var(--part) 0 1.5px, var(--bg) 1.5px 4px) }
/* Not checked (both its kinds, Unverified and Not reviewed) is slate hatching on white with a slate outline, never a
   flat slate fill: slate at 60% (#B5BDD2) is Accepted's navy at 60% (#8A98B8) a step lighter in the same hue, so the
   pattern, not lightness alone, tells the two apart. */
:is(.stats-seg, .stats-swatch):is(.stats-part-unverified, .stats-part-not-reviewed, .stats-part-not-checked) { background:var(--bg); background:repeating-linear-gradient(135deg, var(--part) 0 1.5px, var(--bg) 1.5px 4px) }
.stats-hatch-ground { fill:var(--bg) }
.stats-hatch-line { fill:var(--st-unverified) }
.stats-seg.is-start { border-top-left-radius:2px; border-bottom-left-radius:2px }
.stats-seg.is-end { border-top-right-radius:2px; border-bottom-right-radius:2px }
.stats-swatch { border-radius:2px }
/* The read-from-the-paper stripe (Review result, Enzyme classes) is Read from the paper's colour inside the accepted bar:
   a 4px band through its middle, set off from the accepted fill by a 1px white gap above and below, so it parts from that
   fill by more than lightness, in grey print too, and never glows. Thin, so the accepted bar keeps Accepted's navy (round
   17 fix pass: a 10px stripe through a 20px bar had made Accepted read cyan). A nonzero accepted or read-from-the-paper
   count is drawn at least 2px wide, so EC 7's 44 records show and the stripe stays within its accepted bar. Its swatch,
   in the legend and under the bar, is an accepted swatch with the band through it. */
.stats-track .stats-seg.stats-part-catlog-mark { top:50%; bottom:auto; height:4px; margin-top:-2px; background:var(--src-paper); box-shadow:0 -1px 0 var(--bg), 0 1px 0 var(--bg) }
.stats-chart[data-chart="ec-classes"] .stats-seg:is(.stats-part-accepted, .stats-part-catlog-mark) { min-width:2px }
.stats-swatch.stats-part-catlog-mark { --part:var(--st-accepted); background:var(--src-paper); background:linear-gradient(180deg, transparent 3px, var(--bg) 3px 4px, var(--src-paper) 4px 6px, var(--bg) 6px 7px, transparent 7px), color-mix(in srgb, var(--part) 60%, var(--bg)); box-shadow:inset 0 0 0 1px var(--st-accepted) }
.stats-v2-count { color:var(--src-paper-ink); font-weight:600 }
.stats-accepted-count { color:var(--st-accepted); font-weight:600 }
/* No glow anywhere. Pointing at a mark (or focusing the link in its row) dims the other marks of its figure (data-hl:
   bars, slices, ridges with their range, median and end stubs) and gives the mark a 2px outline in its own colour; its
   exact count shows in the tooltip line. Names and counts stay at full ink, so their contrast holds. */
.stats-fig.has-active [data-hl]:not(.is-active) :is(.stats-seg, .stats-ridge-svg, .stats-ridge-range, .stats-ridge-median, .stats-ridge-end) { opacity:0.42 }
.stats-chart-row.is-active .stats-seg:not(.stats-part-records, .stats-part-catlog-mark), .stats-seg[data-tip]:not(.stats-part-catlog-mark):hover { box-shadow:inset 0 0 0 2px var(--part-line, var(--part)) }
/* A lit row of the review-result table is tinted (more specific than the stats tables' transparent cells, which hid it). */
.stats-status-table.stats-table tbody tr.is-active > :is(th,td) { background:var(--surface-2) }
@media (prefers-reduced-motion: no-preference) {
  .stats-seg { transition:left 450ms cubic-bezier(0.2,0.7,0.2,1), width 450ms cubic-bezier(0.2,0.7,0.2,1), opacity 150ms ease }
  .stats-ridge-row :is(.stats-ridge-svg, .stats-ridge-range, .stats-ridge-median, .stats-ridge-end) { transition:opacity 150ms ease }
}
.stats-tip { position:fixed; left:0; top:0; z-index:150; max-width:min(340px, calc(100vw - 16px)); border-radius:var(--radius); background:var(--text); box-shadow:var(--tip-shadow); color:var(--bg); padding:6px 10px; font-size:var(--fs-12); line-height:var(--lh-12); pointer-events:none; font-variant-numeric:tabular-nums lining-nums }
/* Records (spec figure 8): a light grey bar (--line, outlined --line-strong) under the accepted overlay. */
.stats-part-records.stats-seg, .stats-part-records.stats-swatch { background:var(--line); box-shadow:inset 0 0 0 1px var(--line-strong) }
/* Each slice has one fill, its colour at 60% with a 1px opaque outline (design spec section 2): no gradient, so a slice
   reads as its colour all along and navy (Accepted) and slate (Not checked) stay apart; the bars keep theirs. */
.stats-swatch { display:inline-block; flex:0 0 10px; width:10px; height:10px; vertical-align:-1px }

/* Legends: inline above the plot, in segment order. */
.stats-legend { display:flex; flex-wrap:wrap; gap:4px 16px; margin:0 0 12px; padding:0; list-style:none; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-legend li { display:inline-flex; align-items:flex-start; gap:6px }
.stats-legend li > .stats-swatch { margin-top:3px }
.stats-legend-count { color:var(--muted) }
/* A legend's names that open Browse are underlined only under the pointer or focus (fix pass after round 16b: beside a
   name with no Browse filter, Same number, the underlined ones made the plain one look broken); the pointer and the
   name's title still say it is a link. */
.stats-legend a.stats-link { text-decoration-color:transparent }
.stats-legend a.stats-link:is(:hover, :focus-visible) { text-decoration-color:currentColor }
/* A count chart's legend with its Records | Share switch at the right. */
.stats-chart-tools { display:flex; flex-wrap:wrap; align-items:flex-start; justify-content:space-between; gap:8px 16px; margin:0 0 12px }
.stats-chart-tools .stats-legend { margin:0 }
.stats-switch { display:inline-flex; flex:0 0 auto; gap:2px; border:1px solid var(--line); border-radius:var(--radius); background:var(--surface-2); padding:2px }
.stats-switch-button { min-height:28px; border:0; border-radius:2px; background:transparent; color:var(--text-2); cursor:pointer; padding:0 10px; font-size:var(--fs-12); font-weight:500; line-height:var(--lh-12) }
.stats-switch-button:hover { color:var(--text) }
.stats-switch-button[aria-pressed="true"] { background:var(--bg); box-shadow:0 0 0 1px var(--accent-line); color:var(--accent) }
.stats-fig:not([data-mode="share"]) .stats-ref-share, .stats-fig[data-mode="share"] .stats-ref-records { display:none }

/* Bar charts: label, a 16px bar (rows 8px apart), value label; an axis under the bars. */
.stats-chart { --label-w:minmax(96px,30%) }
/* A chart that spans the row keeps its labels near their bars. */
.stats-wide .stats-chart:not(.stats-chart-percent) { --label-w:minmax(96px,240px) }
.stats-chart-percent { --label-w:88px }
/* Labels set on 16px lines, the bar's height, so bars of one-line rows sit 8px apart. */
.stats-chart-rows { display:grid; gap:8px; margin:0; padding:0; list-style:none }
/* The rows' own size is the value labels' 12px, so a value column given in ch (statsBarChart) fits them. */
.stats-chart-row, .stats-chart-axis, .stats-chart-head { display:grid; grid-template-columns:var(--label-w) minmax(0,1fr) var(--value-w,96px); align-items:center; column-gap:12px; font-size:var(--fs-12) }
/* The value columns' headings (Figure 5: Records, Accepted, From paper), 12px muted, each right-aligned over its column. */
.stats-chart-head { margin:0 0 6px }
.stats-chart-head > .stats-chart-value { grid-column:-2 / -1; color:var(--muted) }
/* Every 100% bar has one length, 560px, wherever it stands (fix pass after round 16b: 900, 916, 580 and 584px at
   1440px, so the supplement's measure changed from figure to figure); a narrower column shrinks it, and on a phone the
   bar spans the row. */
.stats-chart-percent :is(.stats-chart-row, .stats-chart-axis, .stats-chart-head) { grid-template-columns:var(--label-w) minmax(0,560px) var(--value-w,64px); justify-content:start }
/* A 100% bar in a half-width figure (the supplement's two to a row: each database against the values read from its papers,
   the earlier version's corrections) has one length too: its row less a fixed 200px for the names and numbers, so two
   charts whose names or numbers differ in width still draw equal bars (380 and 384px at 1440px before). Phones span the
   row with every bar, as below. */
@media (min-width: 641px) {
  .stats-part-grid > :not(.stats-wide) .stats-chart-percent :is(.stats-chart-row, .stats-chart-axis, .stats-chart-head) { grid-template-columns:var(--label-w) minmax(0,min(560px, 100% - 200px)) var(--value-w,64px) }
}
.stats-chart-label { min-width:0; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-12); overflow-wrap:anywhere }
.stats-chart-label small { display:block; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
/* A label with a breakdown under it (Figure 2's Other): the bar and the numbers stand on the name's line (all three are
   16px lines), not centred on the breakdown. */
.stats-chart-row.has-note { align-items:start }
.stats-chart-value { color:var(--text); font-size:var(--fs-12); line-height:var(--lh-12); text-align:right; white-space:nowrap }
/* A value label of several numbers (count, then share): each in its own right-aligned column; a column after the first is
   as wide as its widest entry in the chart (a hidden sizer, data-sizer, one entry shape per line, measured in the
   viewer's font; it takes no height), so counts line up. */
.stats-chart-value.has-parts { display:flex; justify-content:flex-end; align-items:flex-start; gap:6px }
/* a heading of two lines (Read from / the paper) stands its neighbours on its last line; below 360px it gives its short
   form (From paper), as the counts band does */
.stats-chart-head > .stats-chart-value.has-parts { align-items:flex-end }
.stats-head-short { display:none }
@media (max-width: 359px) {
  .stats-head-long { display:none }
  .stats-head-short { display:inline }
}
.stats-value-part[data-sizer] { display:inline-grid; justify-items:end }
/* The sizer is measured at 600, the boldest weight in a value column (Figure 5's From paper count), so a column of bold
   numbers and its regular heading come out equally wide. */
.stats-value-part[data-sizer]::before { content:attr(data-sizer); grid-area:1 / 1; min-width:max-content; height:0; overflow:hidden; visibility:hidden; white-space:pre; font-weight:600 }
.stats-value-part[data-sizer] > span { grid-area:1 / 1 }
/* The track is an axis container as wide as its axis's tick row (same column, same 12px font), so its gridlines give way
   with their labels (below). */
.stats-track { position:relative; display:block; height:16px; container:axis / inline-size }
.stats-track .stats-seg { position:absolute; top:0; bottom:0 }
.stats-refs { display:contents }
.stats-ref { position:absolute; top:-4px; bottom:-4px; width:0; border-left:1px solid var(--line-soft) }
.stats-chart-axis { margin-top:4px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
/* Each tick label is centred on its place, the end one too (it reaches into the axis row's empty value column), so the
   labels sit evenly; "0" starts at the axis. Where labels would touch they thin evenly: an axis 300px wide or less
   keeps every other one of six ticks, 0, 2 and 4 steps (0, 50,000 and 100,000 of 0-125,000, not only the ends; Figure 3
   at 1280-1440px), one 240px or less 0, the middle and the end of five, and one under
   24ch (the labels' own font, so a wider font thins sooner: 181px in the system font, 183px in Verdana) only the ends of
   four, whose labels would otherwise touch (Figure 5 at 641-700px, where its name and three value columns leave the bars
   about 130px). A gridline in the bars gives way with its label (stats-refs holds an axis's lines in its ticks' order),
   so no gridline is left unlabelled. */
.stats-axis-ticks { position:relative; height:16px; container:axis / inline-size }
.stats-axis-ticks > span { position:absolute; top:0; transform:translateX(-50%); white-space:nowrap }
.stats-axis-ticks > span:first-child { transform:none }
@container axis (max-width: 24ch) {
  :is(.stats-axis-ticks > span, .stats-refs > i):first-child:nth-last-child(4) ~ :not(:last-child) { visibility:hidden }
}
@container axis (max-width: 240px) {
  :is(.stats-axis-ticks > span, .stats-refs > i):first-child:nth-last-child(5) ~ :nth-child(even) { visibility:hidden }
}
@container axis (max-width: 300px) {
  :is(.stats-axis-ticks > span, .stats-refs > i):first-child:nth-last-child(6) ~ :nth-child(even) { visibility:hidden }
}
/* On phones a bar chart's axis spans the row and its end label ends at its tick (no empty column to reach into), so the
   last two labels need more room: there the labels thin sooner, by the labels' own font (ch; labels of up to 7
   characters, "125,000", 4px apart): six ticks keep every other one under 56ch (Figure 3 on a 375px phone: 0, 50,000
   and 100,000), five keep 0, the middle and the end under 45ch, and four keep only their ends under 34ch. */
@media (max-width: 640px) {
  @container axis (max-width: 56ch) {
    :is(.stats-axis-ticks > span, .stats-refs > i):first-child:nth-last-child(6) ~ :nth-child(even) { visibility:hidden }
  }
  @container axis (max-width: 45ch) {
    :is(.stats-axis-ticks > span, .stats-refs > i):first-child:nth-last-child(5) ~ :nth-child(even) { visibility:hidden }
  }
  @container axis (max-width: 34ch) {
    :is(.stats-axis-ticks > span, .stats-refs > i):first-child:nth-last-child(4) ~ :not(:last-child) { visibility:hidden }
  }
}
/* An axis whose labels would still touch keeps only its end labels and their gridlines (statsFitAxes measures them in the
   viewer's font: two panels side by side on a tablet leave a bar column of 80-90px). (Doubled class: it outranks the
   thinning above, which hides the last of six ticks.) */
.stats-chart.stats-chart[data-axis-ends] :is(.stats-axis-ticks > span, .stats-refs > i):not(:first-child, :last-child) { visibility:hidden }
.stats-chart.stats-chart[data-axis-ends] :is(.stats-axis-ticks > span, .stats-refs > i):last-child { visibility:visible }
.stats-ec-name { color:var(--text-2) }
.stats-ec-number { white-space:nowrap }
/* A muted line under a bar (Each database against the values read from its papers: the values from papers it does not
   list), in the bar's column and under the value. */
.stats-chart-aside { grid-column:2 / -1; margin-top:2px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-chart-rows:has(.stats-chart-aside) + .stats-chart-axis { margin-top:8px }
/* Database names as labels: STRENDA DB keeps one line in a wide font (Verdana with letter-spacing). */
.stats-chart-percent[data-chart="db-sources"] { --label-w:104px }
.stats-chart-percent[data-chart="db-classes"] { --label-w:minmax(96px,168px) }
/* A segment that opens Browse (the same filter is a link in the chart's text). */
.stats-seg[data-href] { cursor:pointer }
/* Part 7's lead: one 14px sentence under the part's heading, its result names linking into Browse. */
.stats-part-lead { margin:0 0 var(--sp-5); max-width:80ch; color:var(--text); font-size:var(--fs-14); line-height:var(--lh-14) }
/* A note right after a part's lead (an older comparison's factor-only values, still under Corrects in its figures). */
.stats-part-note { margin:calc(-1 * var(--sp-3)) 0 var(--sp-5); max-width:80ch }
/* Each value against the databases: the counts of the thin results right of each bar, each after its swatch. */
.stats-db-thin { display:inline-flex; justify-content:flex-end; gap:8px; font-variant-numeric:tabular-nums lining-nums }
.stats-db-thin > span { display:inline-flex; align-items:center; gap:4px }
/* Figure 8: each count is a column as wide as its widest count or its heading (Corrects, Differs) plus the swatch (10px
   and a 4px gap), its swatch right before the number; the headings stand right-aligned over the counts. */
.stats-db-thin > .stats-value-part[data-sizer]::before { padding-left:14px }
/* The columns' sizers have no baseline of their own: set the counts at the top of their 16px line, so the value stays one
   line tall and stands on the name's line (Figure 8's printed kcat/Km, a name with a note under it). */
.stats-chart-value > .stats-db-thin { vertical-align:top }
.stats-db-thin > .stats-value-part > span { display:inline-flex; align-items:center; gap:4px }
/* a thin result's head, the legend's name in two lines ("Corrects" / "a value") */
.stats-db-head { display:inline-block; text-align:right }
/* Part 7's tables: a count with its share under it. */
.stats-db-table td small { display:block; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-db-table tfoot :is(th,td) { border-top:1px solid var(--line); border-bottom:0; font-weight:600 }
.stats-db-table tfoot td small { font-weight:400 }
.stats-db-blocks { display:none; gap:6px; margin:0; padding:0; list-style:none; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-db-blocks strong { color:var(--text); font-weight:600 }
/* Corrections by cause and database: database names may take two lines (STRENDA DB) and the cells sit closer, so the
   table fits a half-width column in a wide font; where it still does not, the figure gives a line per database
   (stats-db-narrow, set by the page after measuring), as on phones. */
.stats-table.stats-db-cause-table :is(th,td) { padding-inline:6px }
.stats-table.stats-db-cause-table thead th { white-space:normal }
.stats-db-narrow .stats-db-cause-table { display:none }
.stats-db-narrow .stats-db-blocks { display:grid }
/* When a database lists a number for the same measurement: on the narrowest phones the paired count stands under the
   database's name and its own column goes, so the table fits 320px in a wide font. */
.stats-db-paired-note { display:none }
@media (max-width: 400px) {
  /* In a wide font (Linux's DejaVu Sans) the paired table still ran past its column at 320px: fixed layout, cells wrap. */
  .stats-table.stats-db-table { table-layout:fixed; width:100% }
  .stats-table.stats-db-table :is(th,td) { padding-inline:4px; white-space:normal; overflow-wrap:anywhere }
  .stats-db-table .stats-db-paired-col { display:none }
  .stats-db-table .stats-db-paired-note { display:block; color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12) }
}
/* Under a percent chart, the shares as a small table: the legend's names as column heads, each after its swatch, so colour
   is never the only key (round 15 polish); the numbers right-aligned under them. On phones the columns share the width
   (fixed layout) and the heads wrap. */
.stats-share-table { width:auto; min-width:0; margin:12px 0 0; border-collapse:collapse; table-layout:auto; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12); font-variant-numeric:tabular-nums lining-nums }
.stats-share-table tr, .stats-share-table tbody tr:nth-child(n), .stats-share-table tbody tr:hover { height:auto; background:transparent; cursor:auto; transition:none }
.stats-share-table :is(th, td) { position:static; z-index:auto; height:auto; padding:2px 0 2px 16px; border:0; background:transparent; color:inherit; font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12); text-align:right; vertical-align:bottom; white-space:nowrap }
.stats-share-table tr > :first-child { padding-left:0; text-align:left }
.stats-share-table thead th { max-width:9em; padding-bottom:4px; border-bottom:1px solid var(--line-soft); color:var(--text-2); font-weight:500; white-space:normal }
.stats-share-table thead td { border-bottom:1px solid var(--line-soft) }
.stats-share-table tbody th { min-width:72px; color:var(--text) }
.stats-share-table.stats-share-tall { display:none }
.stats-share-tall tbody th { white-space:normal }
.stats-share-tall tbody :is(th, td) { vertical-align:baseline }
.stats-share-tall tbody .stats-swatch { margin-right:4px; vertical-align:-1px }
@media (max-width: 640px) {
  .stats-share-table.stats-share-wide { display:none }
  .stats-share-table.stats-share-tall { display:table; width:100% }
  .stats-share-tall :is(th, td) { padding-left:8px }
  .stats-share-tall thead th { max-width:none; white-space:nowrap }
  .stats-share-tall tbody th { min-width:0 }
}
.stats-by-database { margin-top:16px; border-top:1px solid var(--line-soft); padding-top:12px; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-by-database p { margin:0 0 6px }
.stats-by-database ul { display:flex; flex-wrap:wrap; gap:4px 16px; margin:0; padding:0; list-style:none }
.stats-by-database li { white-space:nowrap }
.stats-by-database .stats-num { margin-left:2px; color:var(--muted) }

/* Figure 1: the review results as one 100% bar over their legend table, as wide as the table (fix pass after round 16b:
   a donut with the total in its hole). Pointing at a segment, or at its row, outlines it in its colour and dims the
   other segments. */
.stats-status-layout { display:flex; flex-direction:column; gap:10px; max-width:760px }
/* Review result's labels (round 17: on the figure, no legend table): a column under each result's part of the bar, as
   wide as the part, its name, records and share, then its parts in 12px, each on one line; a result too small for a
   column stands right under the bar's end with its swatch. Where a column cannot hold its lines (phones; a narrow part
   or a wide font: statsFitStatusLabels, measured) the labels are a key under the bar instead (is-key): a line per
   result, its swatch, name, records and share, its kinds indented under it, the minor results in order with them
   (round 17 fix pass: columns as wide as the parts broke "Not / reviewed / 3,333" word by word on phones). */
.stats-status-labels { display:grid; column-gap:0; row-gap:8px; font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-status-label { position:relative; display:flex; flex-direction:column; gap:2px; min-width:0; padding-right:8px }
.stats-status-label:not(.is-minor)::before { content:""; position:absolute; left:0; top:-10px; height:6px; border-left:1px solid var(--line-strong) }
.stats-status-name { display:flex; align-items:baseline; gap:6px; font-weight:600; white-space:nowrap }
.stats-status-name .stats-swatch { align-self:center }
.stats-status-count { color:var(--text); white-space:nowrap }
.stats-status-sub { display:flex; align-items:flex-start; gap:6px; margin-top:2px; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12); white-space:nowrap }
.stats-status-sub > .stats-swatch { margin-top:3px }
.stats-status-key { display:none }
.stats-status-minor { display:flex; flex-wrap:wrap; justify-content:flex-end; gap:4px 16px; grid-column:1 / -1 }
.stats-status-label.is-minor { flex-direction:row; align-items:baseline; gap:6px; padding:0; border:0 }
.stats-status-label.is-minor .stats-status-name { font-weight:600 }
.stats-status-labels.is-key { display:flex; flex-direction:column; gap:6px }
.stats-status-labels.is-key > span:empty { display:none }
.stats-status-labels.is-key .stats-status-minor { display:contents }
.stats-status-labels.is-key .stats-status-label { display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:baseline; column-gap:12px; row-gap:2px; padding:0 }
.stats-status-labels.is-key .stats-status-label::before { display:none }
.stats-status-labels.is-key .stats-status-name { white-space:normal }
.stats-status-labels.is-key .stats-status-key { display:inline-block }
.stats-status-labels.is-key .stats-status-sub { grid-column:1 / -1; margin:0; padding-left:16px; white-space:normal }
.stats-status-bar { height:20px }
.stats-status-bar .stats-seg.is-active { box-shadow:inset 0 0 0 2px var(--part-line, var(--part)) }
.stats-fig.has-active .stats-status-bar .stats-seg[data-hl]:not(.is-active) { opacity:0.42 }

/* Tables: compact rows, numbers right-aligned, an 80px bar. */
.stats-table { width:100%; min-width:0; table-layout:auto; border-collapse:collapse; font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-table th, .stats-table td { position:static; z-index:auto; height:auto; padding:6px 8px; border-bottom:1px solid var(--line-soft); background:transparent; color:var(--text); font-size:var(--fs-13); font-weight:400; line-height:var(--lh-13); text-align:left; vertical-align:top; white-space:normal }
.stats-table :is(th,td):first-child { padding-left:0 }
.stats-table :is(th,td):last-child { padding-right:0 }
.stats-table thead th { border-bottom-color:var(--line); color:var(--text-2); font-size:var(--fs-12); font-weight:600; line-height:var(--lh-12); vertical-align:bottom }
.stats-table tr, .stats-table tbody tr:nth-child(n) { height:auto; background:transparent; cursor:auto; transition:none }
.stats-table tbody tr:nth-child(n) > :is(th,td) { background:transparent }
.stats-table tbody tr:last-child > * { border-bottom:0 }
.stats-table .stats-num { text-align:right; white-space:nowrap }
.stats-table td.stats-muted { color:var(--muted) }
.stats-name { display:flex; align-items:baseline; gap:8px; min-width:0; overflow-wrap:anywhere }
.stats-name > .stats-swatch { align-self:flex-start; margin-top:4px }
.stats-name small { display:block; margin-top:2px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-row-sub .stats-name { padding-left:18px }
.stats-row-detail > * { padding-block:3px }
.stats-row-detail .stats-name { padding-left:18px; color:var(--text-2); font-size:var(--fs-12) }
.stats-row-detail td { color:var(--text-2); font-size:var(--fs-12) }
.stats-table .stats-row-detail th, .stats-table .stats-row-detail td { border-bottom-color:transparent }
.stats-table tr:has(+ .stats-row-detail) > * { border-bottom-color:transparent }
/* Quality (round 17: figures, no tables). Human review is a unit chart: one 5px square per record people checked on a
   6px pitch, 100 to a row (50 on phones, its narrow drawing), filled at 60% in its meaning colour (no value disputed in
   human-checked's green, a value disputed in Disputed's deep red, opaque as its dot is), a record with no PMID or DOI an
   open square in Not checked's slate. Its key, the counts in words, stands beside the squares from 1024px and under them
   below. The records with the human-checked tag are said under the panels. */
.stats-lead-links { display:flex; flex-wrap:wrap; gap:4px 24px; margin:0; font-size:var(--fs-13) }
.stats-units { display:grid; gap:24px }
.stats-units-panel { display:grid; gap:8px; min-width:0 }
.stats-units-title { margin:0; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-units-title strong { margin-right:6px; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-units-body { display:grid; grid-template-columns:minmax(0,599px) minmax(200px,1fr); gap:12px 32px; align-items:start }
.stats-units-chart { min-width:0; container-type:inline-size }
.stats-units-svg { display:block; width:100%; height:auto; shape-rendering:crispEdges }
.stats-units-svg.is-wide { max-width:599px }
.stats-units-svg.is-narrow { display:none; max-width:299px }
.stats-units-svg.is-narrowest { display:none; max-width:239px }
.stats-unit { fill:color-mix(in srgb, var(--part) 60%, var(--bg)) }
.stats-unit.stats-part-disputed { fill:var(--part) }
.stats-unit.is-open { fill:var(--bg); stroke:var(--part); stroke-width:1 }
.stats-fig.has-active .stats-unit[data-hl]:not(.is-active) { opacity:0.35 }
.stats-units-key { display:grid; gap:6px; margin:0; padding:0; list-style:none; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-units-key li { display:flex; align-items:flex-start; gap:8px }
.stats-units-key b, .stats-check-labels b { color:var(--text); font-weight:600 }
.stats-unit-swatch { flex:0 0 10px; width:10px; height:10px; margin-top:4px; background:var(--part); background:color-mix(in srgb, var(--part) 60%, var(--bg)) }
.stats-unit-swatch.stats-part-disputed { background:var(--part) }
.stats-unit-swatch.is-open { background:var(--bg); box-shadow:inset 0 0 0 1px var(--part) }
.stats-units-foot { margin:20px 0 0; max-width:80ch; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
/* Checks on the values: two panels, the second AI check's 100% bar (confirmed in Read from the paper's cyan, corrected
   in a correction's opaque red) with each part's count under its end, and the random audit's share removed as wrong on
   a small axis: an ink ring at the share over its 95% interval, a 2px line with end ticks (no meaning colour: a
   statistic, not a kind of value). Side by side from 1024px. */
.stats-checks { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:32px 48px; align-items:start }
.stats-check-panel { display:flex; flex-direction:column; gap:6px; min-width:0 }
.stats-check-name { margin:0; font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-check-covered { margin:0 0 8px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-check-bar { height:20px }
.stats-check-bar .stats-seg.is-active { box-shadow:inset 0 0 0 2px var(--part-line, var(--part)) }
.stats-fig.has-active .stats-check-bar .stats-seg[data-hl]:not(.is-active) { opacity:0.42 }
.stats-check-labels { display:flex; flex-wrap:wrap; justify-content:space-between; gap:4px 16px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-check-label .stats-muted { margin-left:2px }
.stats-check-result { margin:0; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-ci { padding-top:22px }
.stats-ci-plot { position:relative; height:20px; margin:0 12px; border-bottom:1px solid var(--line-strong) }
.stats-ci-line { position:absolute; top:9px; height:2px; background:var(--text-2) }
.stats-ci-line::before, .stats-ci-line::after { content:""; position:absolute; top:-4px; height:10px; border-left:2px solid var(--text-2) }
.stats-ci-line::before { left:-1px }
.stats-ci-line::after { right:-1px }
.stats-ci-dot { position:absolute; top:4px; width:12px; height:12px; margin-left:-6px; border-radius:50%; background:var(--bg); box-shadow:inset 0 0 0 3px var(--text) }
.stats-ci-value { position:absolute; top:-22px; color:var(--text); font-size:var(--fs-13); font-weight:600; line-height:var(--lh-13); white-space:nowrap; transform:translateX(-50%) }
.stats-ci-axis { position:relative; height:20px; margin:0 12px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-ci-axis > span { position:absolute; top:6px; white-space:nowrap; transform:translateX(-50%) }
.stats-ci-axis > span::before { content:""; position:absolute; left:50%; top:-6px; height:4px; border-left:1px solid var(--line-strong) }
.stats-ci-title { margin:6px 0 0; color:var(--text-2); font-size:var(--fs-12); line-height:var(--lh-12); text-align:center }
/* Errors found in CatLog: neutral bars (the counts carry no meaning colour), a route's kinds as parts of its bar, All
   (each value once) set off by a hairline and weight. */
.stats-errors-section > .stats-fig { max-width:920px }
.stats-wide .stats-chart[data-chart="errors"] { --label-w:minmax(140px,320px) }
.stats-chart[data-chart="errors"] .stats-chart-row[data-row="all"] { margin-top:4px; border-top:1px solid var(--line); padding-top:12px }
.stats-chart[data-chart="errors"] .stats-chart-row[data-row="all"] :is(.stats-chart-label, .stats-chart-value) { font-weight:600 }
@media (max-width: 1023px) {
  .stats-units-body, .stats-checks { grid-template-columns:minmax(0,1fr) }
}
@media (max-width: 640px) {
  .stats-units-svg.is-wide { display:none }
  .stats-units-svg.is-narrow { display:block }
}
/* The copy the chart's own room holds at its own size, never scaled (fix pass: on a 320px phone the 50-a-row copy drew
   at 288 of its 299px and at 641-661px the 100-a-row copy at 578-597 of 599, so the 1px gaps blurred): 100 to a row from
   599px of room, 50 from 299px, else 40 (239px; a 271px window). Browsers without container queries keep the window's
   rule above. */
@container (min-width: 599px) {
  .stats-units-svg.is-wide { display:block }
  .stats-units-svg.is-narrow, .stats-units-svg.is-narrowest { display:none }
}
@container (min-width: 299px) and (max-width: 598.98px) {
  .stats-units-svg.is-narrow { display:block }
  .stats-units-svg.is-wide, .stats-units-svg.is-narrowest { display:none }
}
@container (max-width: 298.98px) {
  .stats-units-svg.is-narrowest { display:block }
  .stats-units-svg.is-wide, .stats-units-svg.is-narrow { display:none }
}

/* Value ranges: three small log-scale histograms. */
.stats-ranges { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:24px 32px }
.stats-range { min-width:0; margin:0 }
.stats-range figcaption { font-size:var(--fs-14); font-weight:600 }
.stats-range-unit { color:var(--muted); font-weight:400 }
.stats-range-numbers { display:flex; flex-wrap:wrap; gap:4px 24px; margin:6px 0 12px; font-size:var(--fs-12) }
.stats-range-numbers dt { color:var(--muted) }
.stats-range-numbers dd { margin:2px 0 0; font-size:var(--fs-14); font-weight:500 }
.stats-histogram { position:relative; padding-bottom:24px }
.stats-histogram-bars { display:flex; align-items:flex-end; gap:2px; height:72px; border-bottom:1px solid var(--line) }
/* Value ranges is a single-series figure: --bar-neutral (design spec figure 7); each panel's heading names its
   parameter. The per-class small multiples draw each class's ridge in its class colour (.stats-ec-N on the row, the
   fill from that row's own gradient), its number beside it. */
.stats-range, .stats-ridges { --part:var(--bar-neutral) }
/* Figures of records read from the paper only (variants against their wild type, assay temperature and pH) wear Read
   from the paper's cyan; the value ranges of all records stay neutral. */
.stats-range:is(.stats-fold, .stats-condition) { --part:var(--src-paper) }
/* The light fills carry no information on their own: the bars' 1px outline and the ridge line give the shapes, so they
   are drawn darker than the colour (75% of it with --text: 5.3:1 for --bar-neutral, at least 3:1 for any BPG hue but
   mint), as the 10-90% line and the median are (WCAG 1.4.11). */
.stats-histogram-bars > span { flex:1 1 0; min-width:0; border-radius:2px 2px 0 0; background:var(--part); background:color-mix(in srgb, var(--part) 60%, var(--bg)); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--part) 75%, var(--text)) }
.stats-histogram-bars > span:hover { box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--part) 75%, var(--text)) }
.stats-histogram-bars > span.has-values { min-height:1px }
.stats-histogram-range { position:relative; height:12px }
.stats-histogram-range > span { position:absolute; top:5px; height:2px; border-radius:1px; background:color-mix(in srgb, var(--part) 60%, var(--text)) }
.stats-histogram-range > i { position:absolute; top:1px; width:10px; height:10px; margin-left:-5px; border-radius:50%; background:var(--bg); box-shadow:inset 0 0 0 2.5px color-mix(in srgb, var(--part) 60%, var(--text)) }
:is(.stats-histogram-axis, .stats-condition-axis) { position:absolute; left:0; right:0; bottom:0; height:22px; font-size:var(--fs-12); color:var(--muted); container:ridge-axis / inline-size }
:is(.stats-histogram-axis, .stats-condition-axis) > span { position:absolute; top:2px; transform:translateX(-50%); white-space:nowrap; line-height:1.2 }
:is(.stats-histogram-axis, .stats-condition-axis) > span::before { content:""; position:absolute; left:50%; top:-16px; height:4px; border-left:1px solid var(--line-strong) }
.stats-histogram-axis sup { font-size:var(--fs-12) }
.stats-range-count { margin:6px 0 0; font-size:var(--fs-12); color:var(--muted) }
/* kcat against Km: a density map on log axes whose decades are one size (so a line of equal kcat/Km runs at 45°): grey
   cells, darker for more records; thin lines of equal kcat/Km every hundredfold, labelled where they leave the plot;
   the diffusion limit as a light tan band with dashed tan edges (tan: a value beyond it carries a caution); each
   enzyme class's median as a dot in its class colour, ringed white. Beside it the facts and the class medians, a row
   lighting its dot; below 1024px the facts go under the map. */
.stats-map { display:grid; grid-template-columns:minmax(0,560px) minmax(260px,1fr); gap:24px 48px; align-items:start }
/* (the right column keeps the last x tick's half inside the figure; the lines' labels are inside the plot since the fix
   pass after round 16b, so neither the top nor the right side holds labels) */
.stats-map-frame { display:grid; grid-template-columns:44px minmax(0,1fr) 16px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-map-y-title { grid-column:1 / 3; grid-row:1; margin:0 0 12px; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-map-y { position:relative; grid-column:1; grid-row:2 }
.stats-map-y > span { position:absolute; right:8px; transform:translateY(50%); white-space:nowrap }
.stats-map-y > span::after { content:""; position:absolute; top:50%; right:-8px; width:4px; border-top:1px solid var(--line-strong) }
.stats-map-y sup, .stats-map-x sup { font-size:var(--fs-12) }
.stats-map-plot { position:relative; grid-column:2; grid-row:2; box-shadow:0 0 0 1px var(--line) }
.stats-map-svg { position:absolute; inset:0; display:block; width:100%; height:100%; overflow:hidden }
.stats-map-cells rect { fill:color-mix(in srgb, var(--bar-neutral) 55%, var(--text)); shape-rendering:crispEdges }
.stats-map-iso { fill:none; stroke:var(--text); stroke-opacity:0.3; stroke-width:1; vector-effect:non-scaling-stroke }
.stats-map-limit { fill:var(--caution-line); fill-opacity:0.42; stroke:none }
.stats-map-limit-edge { fill:none; stroke:var(--caution); stroke-width:1; stroke-dasharray:4 3; vector-effect:non-scaling-stroke }
/* An equal-kcat/Km line's label sits on its line, along its slope, on a plain ground that parts the line behind it (as a
   contour's label does), so it never reads as an axis tick. */
.stats-map-iso-label { position:absolute; z-index:1; padding:0 3px; border-radius:2px; background:var(--bg); color:var(--text-2); white-space:nowrap; transform:translate(-50%, 50%) rotate(-45deg); pointer-events:none }
.stats-map-limit-label { position:absolute; z-index:1; color:var(--caution); font-weight:500; white-space:nowrap; transform:translate(-50%, 50%) rotate(-45deg); pointer-events:none }
/* A class median: a 16px dot of its class colour with the class number in it (ink, white on navy and brown: 4.2:1 or
   more), ringed white, the smaller classes on top (--z); one moved off another (--dx, --dy) has a 1px line and a 5px
   dot of its colour back at its own place (.stats-map-leaders). */
.stats-map-dot { --dot-ink:var(--text); position:absolute; z-index:var(--z, 2); display:flex; width:16px; height:16px; align-items:center; justify-content:center; border-radius:50%; background:var(--part); box-shadow:0 0 0 1.5px var(--bg), 0 0 0 2.5px color-mix(in srgb, var(--part) 55%, var(--text)); color:var(--dot-ink); font-size:10px; font-style:normal; font-weight:600; line-height:1; transform:translate(calc(-50% + var(--dx, 0px)), calc(50% + var(--dy, 0px))) }
.stats-map-dot:is(.stats-ec-4, .stats-ec-7) { --dot-ink:#fff }
.stats-map-dot.is-active { z-index:20; box-shadow:0 0 0 1.5px var(--bg), 0 0 0 3.5px color-mix(in srgb, var(--part) 55%, var(--text)) }
.stats-fig.has-active .stats-map-dot[data-hl]:not(.is-active) { opacity:0.3 }
.stats-map-leaders { position:absolute; inset:0; z-index:1; width:100%; height:100%; overflow:visible; pointer-events:none }
.stats-map-leaders line { stroke:var(--text-2); stroke-width:1 }
.stats-map-leaders circle { fill:var(--part); stroke:var(--bg); stroke-width:1 }
.stats-map-x { position:relative; grid-column:2; grid-row:3; height:22px }
.stats-map-x > span { position:absolute; top:6px; transform:translateX(-50%); white-space:nowrap }
.stats-map-x > span::before { content:""; position:absolute; left:50%; top:-6px; height:4px; border-left:1px solid var(--line-strong) }
.stats-map-x-title { grid-column:2; grid-row:4; margin:4px 0 0; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14); text-align:center }
.stats-map-side { display:grid; align-content:start; gap:24px; min-width:0 }
.stats-map-facts { display:grid; gap:14px; margin:0 }
.stats-map-facts dt { color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-map-facts dd { margin:2px 0 0; color:var(--text); font-size:var(--fs-18); font-weight:600; line-height:var(--lh-18) }
.stats-map-facts dd small { display:block; margin-top:2px; color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12) }
.stats-map-facts dd .stats-muted { font-size:var(--fs-14); font-weight:500 }
/* kcat against Km's class medians (round 17: a dot plot, no table): per class its number in the map's own dot on a log
   axis of kcat and one of Km, the value beside the dot and the records at the end; the row lights the map's dot. One
   grid for the whole plot (its head, rows and tick row are subgrids), so the name column is as wide as the longest name
   ("EC 1 Oxidoreductases" in DejaVu Sans too: round 17 fix pass, it had been cut at 9.5em) and every row's tracks still
   line up; a 1px rule (stats-class-sep) between the kcat and the Km panel runs through the rows and the tick row, 30px
   from either track. Beside the map from 1280px, under its facts; under the map, as wide as the figure allows, from
   1024px to 1279px (the column beside the map is 350px there); after the facts below 1024px. */
.stats-class-dots { display:grid; grid-template-columns:max-content minmax(0,1fr) 1px minmax(0,1fr) max-content; column-gap:12px; min-width:0; font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-class-head, .stats-class-rows, .stats-class-row { display:grid; grid-column:1 / -1; grid-template-columns:max-content minmax(0,1fr) 1px minmax(0,1fr) max-content; grid-template-columns:subgrid; column-gap:12px; align-items:center }
.stats-class-head { margin:0 0 4px; color:var(--muted) }
.stats-class-head > span:first-child { color:var(--text); font-size:var(--fs-13); font-weight:600 }
.stats-class-head > span:last-child, .stats-class-n { text-align:right }
.stats-class-rows { margin:0; padding:0; list-style:none }
.stats-class-row { height:26px; border-bottom:1px solid var(--line-soft) }
.stats-class-label { min-width:0; overflow:hidden; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13); text-overflow:ellipsis; white-space:nowrap }
.stats-class-sep { align-self:stretch; margin-bottom:-1px; background:var(--line) }
.stats-class-axis > .stats-class-sep { margin:-2px 0 0 }
.stats-class-track { position:relative; align-self:stretch; margin:0 18px }
.stats-class-grid { position:absolute; top:3px; bottom:3px; border-left:1px solid var(--line-soft) }
.stats-class-track .stats-map-dot { width:14px; height:14px; font-size:9px }
.stats-class-value { position:absolute; top:50%; padding-left:11px; color:var(--text); white-space:nowrap; transform:translateY(-50%) }
.stats-class-value.is-left { padding:0 11px 0 0; transform:translate(-100%, -50%) }
.stats-class-n { color:var(--muted) }
.stats-class-axis { margin-top:2px }
.stats-class-ticks { position:relative; height:16px; margin:0 18px }
.stats-class-ticks > span { position:absolute; top:2px; transform:translateX(-50%); white-space:nowrap }
.stats-class-ticks sup { font-size:var(--fs-12) }
.stats-map-medians > .stats-class-dots { grid-column:1 / -1; max-width:760px }
@media (min-width: 1280px) {
  .stats-map-medians { grid-template-rows:auto 1fr }
  .stats-map-medians > .stats-map-frame { grid-row:1 / span 2 }
  .stats-map-medians > .stats-class-dots { grid-column:2; grid-row:2; max-width:none }
}
.stats-class-row.is-active { background:var(--surface-2) }
.stats-fig.has-active .stats-class-row[data-hl]:not(.is-active) .stats-map-dot { opacity:0.3 }
/* Before a name in a table, the class bar stands 6px from it (the name's flex gap, less its own margin). */
.stats-name > .stats-ec-key { margin-right:-2px }
.stats-map-legend li { align-items:center }
.stats-map-key-cells { display:inline-block; flex:0 0 28px; width:28px; height:10px; border-radius:2px; background:linear-gradient(90deg, color-mix(in srgb, var(--bar-neutral) 16%, var(--bg)), color-mix(in srgb, var(--bar-neutral) 55%, var(--text))) }
.stats-map-key-iso { display:inline-block; flex:0 0 14px; width:14px; height:0; border-top:1px solid color-mix(in srgb, var(--text) 45%, var(--bg)); transform:rotate(-45deg) }
.stats-map-key-limit { display:inline-block; flex:0 0 10px; width:10px; height:10px; border-radius:2px; background:color-mix(in srgb, var(--caution-line) 42%, var(--bg)); box-shadow:inset 0 0 0 1px var(--caution) }
.stats-map-key-dot { display:inline-block; flex:0 0 10px; width:10px; height:10px; border-radius:50%; background:conic-gradient(var(--ec-1) 0 14.3%, var(--ec-2) 0 28.6%, var(--ec-3) 0 42.9%, var(--ec-4) 0 57.1%, var(--ec-5) 0 71.4%, var(--ec-6) 0 85.7%, var(--ec-7) 0) }
/* CatLog and BRENDA by publication year (round 16): a line and a dot per year for each source over light gridlines, BRENDA
   in the grey of a count with no meaning colour (dot and line 3.7:1, its words --muted), CatLog in Read from the paper's
   cyan (dots BPG cyan ringed and joined by --src-paper-line, its words the cyan ink); the years BRENDA is still adding
   papers from on a plain grey band (--plot-band) with open dots. CatLog's total stands above the plot; the names and
   BRENDA's two counts are placed on the plot by statsPlaceYearLabels (hidden until placed), and the key above it shows
   only while a name has no room (.is-labelled hides it). A column per year gives the year's tooltip line and, pointed
   at, a hairline through its dots, which grow. */
.stats-years-note { margin:0 0 12px; color:var(--text); font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-years-papers { display:block; color:var(--text-2) }
.stats-fig.is-labelled .stats-years-key { display:none }
.stats-years-key li { align-items:center }
.stats-years-key-line { display:inline-block; flex:0 0 16px; width:16px; height:0; border-top:2px solid var(--years-line) }
.stats-years { display:grid; grid-template-columns:52px minmax(0,1fr) 16px; max-width:840px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-years-y-title { grid-column:1 / -1; grid-row:1; margin:0 0 16px; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-years-y { position:relative; grid-column:1; grid-row:2 }
.stats-years-y > span { position:absolute; right:8px; transform:translateY(50%); white-space:nowrap }
.stats-years-plot { position:relative; grid-column:2; grid-row:2; height:320px; border-bottom:1px solid var(--line-strong) }
.stats-years-x { position:relative; grid-column:2; grid-row:3; height:22px }
.stats-years-x > span { position:absolute; top:6px; transform:translateX(-50%); white-space:nowrap }
.stats-years-x > span::before { content:""; position:absolute; left:50%; top:-6px; height:4px; border-left:1px solid var(--line-strong) }
.stats-years-x-title { grid-column:2; grid-row:4; margin:4px 0 0; color:var(--text); font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14); text-align:center }
.stats-years-band { position:absolute; top:0; right:0; bottom:0; z-index:0; background:var(--plot-band) }
.stats-years-col { position:absolute; top:0; bottom:0; z-index:1 }
.stats-years-col.is-active::after { content:""; position:absolute; top:0; bottom:0; left:50%; border-left:1px solid var(--line-strong) }
.stats-years-svg { position:absolute; inset:0; z-index:2; display:block; width:100%; height:100%; overflow:visible; pointer-events:none }
.stats-years-grid { fill:none; stroke:var(--line-soft); stroke-width:1; vector-effect:non-scaling-stroke }
.stats-years-line { fill:none; stroke:var(--years-line); stroke-width:2; stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke }
.stats-years-dot { position:absolute; z-index:3; box-sizing:border-box; width:8px; height:8px; border:1.5px solid var(--years-line); border-radius:50%; background:var(--years-fill); transform:translate(-50%, 50%); pointer-events:none }
.stats-years-dot.is-open { background:var(--bg) }
.stats-years-dot.is-active { width:11px; height:11px }
.stats-years-label { position:absolute; z-index:4; visibility:hidden; color:var(--years-ink); white-space:nowrap; pointer-events:none }
.stats-years-label.is-placed { visibility:visible }
.stats-years-name { font-size:var(--fs-13); font-weight:600; line-height:var(--lh-13) }
/* BRENDA in the dark grey of secondary text (no data meaning), not --bar-neutral: that grey has CatLog's line's lightness
   (1.07:1), so in print or greyscale the two lines were one grey where they cross (round 16 review); this one is 2.4:1 */
:is(.stats-years-line, .stats-years-dot, .stats-years-label, .stats-years-key-line).is-brenda { --years-line:var(--text-2); --years-fill:var(--text-2); --years-ink:var(--text-2) }
:is(.stats-years-line, .stats-years-dot, .stats-years-label, .stats-years-key-line).is-catlog { --years-line:var(--src-paper-line); --years-fill:var(--src-paper); --years-ink:var(--src-paper-ink) }
/* Variants against their wild type: three histograms like Value ranges, a dashed line at the wild type (its name above
   the bars, clear of the peak beside it). */
/* Their axes' end labels stand centred on the end ticks: the plots keep 16px either side for them. */
/* (Value ranges' histograms too, round 15 polish: one width and left edge for Figures 4 and 6, the end labels inside) */
.stats-fold-plot, .stats-condition-plot, .stats-range > .stats-histogram { margin-inline:16px }
.stats-fold-plot { padding-top:18px }
.stats-fold-zero { position:absolute; top:0; bottom:24px; z-index:1; border-left:1px dashed var(--text-2); pointer-events:none }
.stats-fold-zero > span { position:absolute; top:0; left:4px; color:var(--text-2); font-size:var(--fs-12); font-style:normal; line-height:var(--lh-12); white-space:nowrap }
/* Assay temperature and pH: a bar per step, so a bar is a few pixels wide: solid bars (75% of the colour with --text,
   so each bar shows at 3:1 or more without an outline) with 1px gaps; a bar with records opens them in Browse. */
.stats-conditions { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px 48px }
.stats-condition-bars { display:flex; align-items:flex-end; gap:1px; height:96px; border-bottom:1px solid var(--line) }
.stats-condition-bars > span { flex:1 1 0; min-width:0; background:color-mix(in srgb, var(--part) 75%, var(--text)) }
.stats-condition-bars > span.has-values { min-height:1px }
.stats-condition-bars > [data-href] { cursor:pointer }
.stats-condition-bars > span:hover { background:var(--accent) }
.stats-condition-top dd { display:flex; flex-wrap:wrap; gap:2px 16px }
.stats-condition-value { white-space:nowrap }
/* What the wild-type values show (round 16): Between papers' three histograms in Value ranges' grid over its table at
   the same temperature and pH; Substrate specificity, Km and substrate size and kcat and assay temperature as two
   panels side by side from 1024px (one under the other below). All of records read from the paper: Read from the
   paper's cyan. The medians by size or temperature take Values by enzyme class's rows: a dot (median) on a line (middle
   half) per row, a little lower than a ridge's row as no curve stands over it. */
.stats-range.stats-insight, .stats-ridges.stats-medians { --part:var(--src-paper) }
.stats-insight-pair { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px 48px; align-items:start }
.stats-typical-table { max-width:560px }
/* A segment's own share (round 17): 12px ink on the bar's 60% fill, centred; hidden where it does not fit. */
.stats-seg-label { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; overflow:hidden; color:var(--text); font-size:var(--fs-12); line-height:1; white-space:nowrap; pointer-events:none }
.stats-seg-label.is-hidden { visibility:hidden }
.stats-fold-bars { margin-top:32px }
.stats-fold-bars .stats-chart-percent { --label-w:minmax(96px,200px) }
.stats-chart[data-chart="between-papers"] .stats-chart-rows { gap:4px }
.stats-chart[data-chart="between-papers"] .stats-chart-row[data-row$="-all"]:not(:first-child) { margin-top:10px }
.stats-fold-scope { color:var(--text-2); font-size:var(--fs-12) }
.stats-range-by-tested { min-width:0 }
.stats-wide .stats-range-by-tested .stats-chart { --label-w:minmax(72px,9.5em) }
.stats-range-by-title { margin:0 0 12px; font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-medians .stats-ridge-row { height:26px; align-items:center }
.stats-medians :is(.stats-ridge-label, .stats-ridge-value, .stats-ridge-n) { padding-bottom:0 }
.stats-medians .stats-ridge-plot::after { top:50%; bottom:auto; border-bottom-color:var(--line-soft) }
.stats-medians .stats-ridge-range { top:calc(50% - 1px); bottom:auto }
.stats-medians .stats-ridge-median { top:calc(50% - 4.5px); bottom:auto }
.stats-typical-table :is(th,td) small { display:block; margin-top:2px; color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12) }
/* The table at the same temperature and pH fits a phone: its number headings wrap. */
.stats-typical-table .stats-row-reference > * { border-top:1px solid var(--line) }
/* On the narrowest phones (320px) in a wide font the two tables keep inside the page: tighter cells, 12px type and
   headings and the record counts that may wrap (the release check of 2026-10-22 found them 1-9px too wide). */
@media (max-width: 360px) {
  .stats-typical-table { font-size:var(--fs-12); line-height:var(--lh-12) }
  .stats-typical-table :is(th,td) { padding-inline:4px; white-space:normal; overflow-wrap:anywhere }
}
/* Values by enzyme class: a ridge per class (each scaled to its own peak) overlapping the row above; the ridge under the
   pointer takes a thicker line and the others dim. The 10-90% line and the median dot sit on its baseline. Three panels side by side from
   1024px with the class number only (the name is in the tooltip line and in Biology); one per row below with names. */
.stats-ridge-panels { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:24px 32px }
.stats-ridges { --ridge-label:44px; --ridge-n:5ch }
.stats-ridges { min-width:0 }
.stats-ridge-defs { position:absolute; width:0; height:0; overflow:hidden }
/* Label, plot, median, n: the title, the rows and the axis share these columns at 12px (the n column is in ch). */
.stats-ridges-title, .stats-ridge-row, .stats-ridge-axis { display:grid; grid-template-columns:var(--ridge-label) minmax(0,1fr) 52px var(--ridge-n); column-gap:8px; font-size:var(--fs-12) }
.stats-ridges-title { align-items:baseline; margin:0 0 20px; line-height:var(--lh-12) }
.stats-ridges-title > span:first-child { grid-column:1 / 3; font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.stats-ridges-head { color:var(--muted); font-size:var(--fs-12); font-weight:400; line-height:var(--lh-12); text-align:right }
.stats-ridge-rows { margin:0; padding:0; list-style:none }
.stats-ridge-row { height:30px; align-items:end }
.stats-ridge-label { min-width:0; overflow:hidden; padding-bottom:2px; font-size:var(--fs-12); line-height:var(--lh-12); text-overflow:ellipsis; white-space:nowrap }
.stats-ridge-name { display:none; color:var(--text-2) }
.stats-ridge-plot { position:relative; align-self:stretch }
.stats-ridge-plot::after { content:""; position:absolute; left:0; right:0; bottom:0; border-bottom:1px solid var(--line) }
.stats-ridge-svg { position:absolute; left:0; bottom:0; display:block; width:100%; height:40px; overflow:visible }
.stats-ridge-area { stroke:none }
/* One flat fill under each curve (both stops alike: no fade). */
.stats-ridge-stop-top, .stats-ridge-stop-bottom { stop-color:var(--part); stop-opacity:0.4 }
.stats-ridge-line { fill:none; stroke:color-mix(in srgb, var(--part) 75%, var(--text)); stroke-width:1.5; vector-effect:non-scaling-stroke; stroke-linejoin:round }
/* The open-ended end bins: a short hatched stub of fixed height (not a share of the peak), its count in the tooltip. */
.stats-ridge-end { position:absolute; bottom:0; z-index:1; height:6px; background:repeating-linear-gradient(135deg, color-mix(in srgb, var(--part) 70%, var(--text)) 0 1px, transparent 1px 3px); box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--part) 70%, var(--text)) }
.stats-ridge-range { position:absolute; bottom:-1px; z-index:1; height:3px; border-radius:2px; background:color-mix(in srgb, var(--part) 55%, var(--text)) }
.stats-ridge-median { position:absolute; bottom:-4px; z-index:2; width:9px; height:9px; margin-left:-4.5px; border-radius:50%; background:var(--bg); box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--part) 55%, var(--text)) }
.stats-ridge-value { padding-bottom:2px; color:var(--text); font-size:var(--fs-12); line-height:var(--lh-12); text-align:right; white-space:nowrap }
.stats-ridge-n { padding-bottom:2px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12); text-align:right; white-space:nowrap }
/* A class with few values (fewer than 300): a lighter fill and a dashed outline, so it does not look as solid as a big one. */
.stats-ridge-row.is-few .stats-ridge-area { opacity:0.45 }
.stats-ridge-row.is-few .stats-ridge-line { stroke-dasharray:3 2 }
.stats-ridge-row.is-active .stats-ridge-line { stroke-width:2.5 }
.stats-ridge-row.is-active .stats-ridge-label { font-weight:600 }
.stats-ridge-axis { margin-top:6px; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.stats-ridge-ticks { position:relative; height:16px; container:ridge-axis / inline-size }
@container ridge-axis (max-width: 220px) {
  /* every second label gives way, its power of ten too (the sup has its own size); its tick mark stays (both value
     figures: their axes are as wide, so they thin alike) */
  :is(.stats-ridge-ticks, .stats-histogram-axis) > .stats-tick-alt, :is(.stats-ridge-ticks, .stats-histogram-axis) > .stats-tick-alt sup { font-size:0 }
}
.stats-ridge-ticks > span { position:absolute; top:2px; transform:translateX(-50%); white-space:nowrap }
.stats-ridge-ticks > span::before { content:""; position:absolute; left:50%; top:-8px; height:4px; border-left:1px solid var(--line-strong) }
.stats-ridge-ticks sup { font-size:var(--fs-12) }

.stats-detail-table { margin-top:12px; width:100%; min-width:0; table-layout:auto; border-collapse:collapse; font-size:var(--fs-13) }
.stats-detail-table tr, .stats-detail-table tbody tr:nth-child(n) { height:auto; background:transparent; cursor:auto; transition:none }
.stats-detail-table th, .stats-detail-table td { position:static; height:auto; background:transparent; padding:6px 12px; border-bottom:1px solid var(--line-soft); color:var(--text); text-align:right; font-size:var(--fs-13); line-height:var(--lh-13); font-weight:400; white-space:normal }
.stats-detail-table th:first-child { text-align:left; padding-left:0 }
.stats-detail-table thead th { color:var(--text-2); font-size:var(--fs-12); font-weight:600 }
.stats-detail-table :is(th,td):last-child { padding-right:0 }
.stats-detail-table :is(th,td) small { display:block; color:var(--muted); font-size:var(--fs-12) }
.stats-explanation { font-size:var(--fs-13); line-height:var(--lh-13) }
.stats-explanation summary { width:fit-content; min-height:36px; padding-block:9px; cursor:pointer; color:var(--accent) }
.stats-explanation summary:hover { text-decoration:underline; text-underline-offset:3px }
/* Every disclosure opens with the same + and −, as the supplement, the record and the Guide's Reference do (no
   triangles). */
.stats-explanation > summary, .guide-view .guide-details > summary { list-style:none }
.stats-explanation > summary::-webkit-details-marker, .guide-view .guide-details > summary::-webkit-details-marker { display:none }
.stats-explanation > summary::before, .guide-view .guide-details > summary::before { content:"+"; content:"+" / ""; display:inline-block; width:16px; color:var(--muted); font-weight:600 }
.stats-explanation[open] > summary::before, .guide-view .guide-details[open] > summary::before { content:"\2212"; content:"\2212" / "" }
.stats-explanation p { margin:8px 0 0; max-width:80ch; color:var(--muted) }
.stats-explanation dl { margin:8px 0 0 }
.stats-explanation dl > div { display:grid; grid-template-columns:130px 1fr; gap:12px; margin-top:6px }
.stats-explanation dt { font-weight:600 }
.stats-explanation dd { margin:0 }
.stats-unaccepted-fields { margin-top:8px }
.stats-unaccepted-fields table { max-width:760px }
.stats-explanation .stats-unaccepted-fields p { margin:8px 0 0 }
.stats-method-sub { color:var(--text-2) }
.stats-method { border-top:1px solid var(--line); padding-top:8px }
/* (under the closed supplement, whose heading line is already a hairline, How these numbers are counted has no second
   rule: two hairlines had framed an empty 48px band; open, the rule ends the supplement's figures) */
.stats-supp:has(> .stats-supp-all:not([open])) + .stats-method { border-top:0 }
/* Each figure's own rules, under its number (Figure 4, Table 1), its title first. */
.stats-method-figures { border-top:1px solid var(--line-soft); padding-top:4px }
.stats-method-title { color:var(--text); font-weight:500 }

/* Team: the loop of people and AI agents. */
.team-shell { max-width:1200px; margin:0 auto; padding:32px 24px 48px }
.team-heading h1 { margin:0; font-size:var(--fs-24); font-weight:600; line-height:var(--lh-24) }
.team-heading p { max-width:72ch; margin:8px 0 0; color:var(--text-2); font-size:var(--fs-16); line-height:var(--lh-16) }
.team-body { display:grid; gap:24px; margin-top:24px }
.team-figure { margin:0; border:1px solid var(--line); border-radius:4px; background:var(--bg); padding:16px }
.team-figure figcaption { margin-top:8px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.team-loop { display:block; width:100%; height:auto; margin:0 auto; overflow:visible; font-family:var(--font); font-variant-numeric:tabular-nums lining-nums }
/* 1004px: the wide loop's 910 units (round 14: AI critique in its lower-left corner) at the scale its 870 had at 960px */
.team-loop-wide { max-width:1004px }
.team-loop-narrow { display:none; max-width:320px }
/* The upright loop has no people or agents on it: its caption sends readers to the list instead. */
.team-caption-narrow { display:none }
.team-track { fill:none; stroke:var(--line-strong); stroke-width:3 }
.team-arrow { fill:none; stroke:var(--muted); stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round }
.team-branch { stroke:var(--line-strong); stroke-width:2; stroke-dasharray:4 4 }
.team-station-dot { fill:var(--bg); stroke:var(--text); stroke-width:2 }
.team-station-branch .team-station-dot { stroke:var(--text-2) }
/* SVG text in user units on the type scale: the wide loop prints them at about 1.1x on a desktop. */
.team-station-name { fill:var(--text); font-size:16px; font-weight:600 }
.team-station-number { fill:var(--text-2); font-size:13px }
.team-loop-narrow .team-station-name { font-size:14px }
.team-loop-narrow .team-station-number { font-size:12px }
.team-actor { cursor:default; outline:none }
.team-chip { stroke-width:1.5 }
.team-actor text { fill:var(--text); font-size:14px; font-weight:500 }
/* AI agents on the accent tint, people in neutral grey: the status navy and the comparison brown keep their meanings. */
/* The AI agents wear CatLog's reading colour (BPG cyan: a 12% tint, the 3:1 ring), the people stay neutral. */
.team-actor-ai .team-chip { fill:var(--src-paper-tint); stroke:var(--src-paper-ring) }
.team-actor-person .team-chip { fill:var(--surface-2); stroke:var(--muted) }
.team-link { stroke:var(--line-strong); stroke-width:1.5 }
/* The focus ring stands apart from the chip, as the site's 2px ring with its offset does. */
.team-focus-ring { fill:none; stroke:none; pointer-events:none }
.team-actor:focus-visible .team-focus-ring { stroke:var(--accent); stroke-width:2 }
/* Pointing at (or tabbing to) a person or agent lights their stations and fades the rest. */
.team-highlight .team-station, .team-highlight .team-actor, .team-highlight .team-legend-item { transition:opacity 120ms ease }
.team-highlight .team-station:not(.is-lit), .team-highlight .team-actor:not(.is-lit) { opacity:0.3 }
.team-station.is-lit .team-station-dot { fill:var(--accent); stroke:var(--accent) }
.team-actor.is-lit .team-chip { stroke-width:2.5 }
.team-actor.is-lit .team-link { stroke:var(--accent) }
.team-legend { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:24px }
.team-legend h2 { margin:0 0 8px; font-size:var(--fs-14); font-weight:600; line-height:var(--lh-14) }
.team-legend ul { display:grid; gap:4px; margin:0; padding:0; list-style:none }
.team-legend-item { border-radius:4px }
/* Each line is a toggle button that keeps its stations lit while pressed. */
.team-legend-button { display:flex; width:100%; align-items:flex-start; gap:10px; border:1px solid transparent; border-radius:4px; background:transparent; color:var(--text-2); cursor:pointer; padding:5px 7px; font:inherit; font-size:var(--fs-14); line-height:var(--lh-14); text-align:left }
.team-legend-item strong { color:var(--text); font-weight:600 }
.team-legend-item small { display:block; color:var(--muted); font-size:var(--fs-12); line-height:var(--lh-12) }
.team-legend-item:is(:hover,.is-lit) { background:var(--surface-2) }
.team-legend-button[aria-pressed="true"] { border-color:var(--accent-line); background:var(--accent-tint) }
.team-legend-button:focus-visible { outline-offset:0 }
/* Each line's mark is a filled 10px swatch in its chip's outline colour, as Stats' legends are drawn (a hollow circle or
   square read as an unticked radio button or checkbox): a grey dot for a person, an accent square for an AI agent. */
.team-legend-mark { flex:0 0 10px; width:10px; height:10px; margin-top:5px; background:var(--mark); background:color-mix(in srgb, var(--mark) 60%, transparent); box-shadow:inset 0 0 0 1px var(--mark) }
.team-legend-ai .team-legend-mark { --mark:var(--src-paper); border-radius:2px; box-shadow:inset 0 0 0 1px var(--src-paper-ring) }
.team-legend-person .team-legend-mark { --mark:var(--muted); border-radius:50% }
@media (prefers-reduced-motion: reduce) {
  .team-highlight .team-station, .team-highlight .team-actor { transition:none }
}

/* 1024-1279px: Figure 1 takes the row (its bar over its legend table, 640px at most) and Figure 2 the next one, as on
   tablets; the figures after them pair up as before. */
@media (min-width: 1024px) and (max-width: 1279px) {
  .stats-part-grid > .stats-status-section, .stats-part-grid > .stats-status-section + .stats-figure-section { grid-column:1 / -1 }
  .stats-part-grid > .stats-status-section + .stats-figure-section .stats-chart:not(.stats-chart-percent) { --label-w:minmax(96px,240px) }
}

@media (max-width: 1023px) {
  .stats-part-grid > * { grid-column:1 / -1 }
  .stats-years-plot { height:280px }
  .stats-map { grid-template-columns:minmax(0,560px) }
  .stats-subs { grid-template-columns:minmax(0,440px) }
  .stats-conditions { grid-template-columns:1fr; max-width:560px }
  .stats-shell { max-width:760px }
  .stats-ranges { grid-template-columns:1fr; max-width:560px }
  .stats-insight-pair { grid-template-columns:1fr; max-width:560px }
  /* One panel per row, each class named. */
  .stats-ridge-panels { grid-template-columns:1fr; gap:32px; max-width:560px }
  .stats-ridges { --ridge-label:minmax(0,150px) }
  .stats-ridge-name { display:inline }
}

/* Tablets and phones: the upright loop, with the legend beside it (under it on phones). */
@media (max-width: 959px) {
  .team-loop-wide, .team-caption-wide { display:none }
  .team-loop-narrow { display:block }
  .team-caption-narrow { display:inline }
  .team-body { grid-template-columns:minmax(0,354px) minmax(0,1fr); align-items:start }
  .team-legend { grid-template-columns:1fr }
}

/* Four headline numbers on a tablet: the number grows with the window from the phones' 28px (at 721px) to the 40px of
   1200px and over, so it never jumps or shrinks as the window widens. Below 1024px the page keeps a 760px column, so a
   column of the band is about 146px: there the number grows only to 30px, where a six-digit count in a wide font
   (Linux's DejaVu Sans Bold: 137px) still fits; from 1024px, with room, it grows on to 40px. The line stays 4px taller
   than the number, as at 28px and 40px. */
@media (min-width: 721px) and (max-width: 1199px) {
  .stats-totals .stats-totals-main dd { font-size:clamp(var(--fs-28), calc(28px + (100vw - 721px) * 0.0066), 30px); line-height:calc(1em + 4px) }
}
@media (min-width: 1024px) and (max-width: 1199px) {
  .stats-totals .stats-totals-main dd { font-size:clamp(30px, calc(30px + (100vw - 1024px) * 0.0569), var(--fs-40)) }
}

/* Phones: 28px key numbers two to a row (one under the other below 360px). */
@media (max-width: 720px) {
  .stats-totals dl { grid-template-columns:repeat(2,minmax(0,1fr)); gap:16px 0 }
  .stats-total:nth-child(odd)::before { display:none }
  .stats-totals .stats-totals-main dd { font-size:var(--fs-28); line-height:var(--lh-28) }
}
/* The narrowest phones: the four headline numbers one under the other, so Read from the paper keeps one line, also in a
   wide font (DejaVu Sans), and the human review's base reads in two lines, not five. */
@media (max-width: 359px) {
  .stats-totals .stats-totals-main { grid-template-columns:1fr; gap:8px 0 }
  .stats-totals-main .stats-total::before { display:none }
  /* A value heading of several words (Figure 5's From paper) takes one word per line, its column only as wide as its
     longest word or count (data-sizer-narrow), so the class names beside it stay whole; the headings stand on their
     last line, right above the counts. */
  .stats-value-part[data-sizer-narrow]::before { content:attr(data-sizer-narrow) }
  .stats-chart-head > .stats-chart-value.has-parts { align-items:flex-end }
  .stats-chart-head .stats-value-part > span { width:min-content; white-space:normal }
}

@media (max-width: 640px) {
  .stats-shell, .team-shell { padding:24px 16px 32px }
  .stats-years { grid-template-columns:48px minmax(0,1fr) 16px }
  .stats-years-plot { height:240px }
  .stats-totals .stats-totals-scope dd { font-size:var(--fs-18); line-height:var(--lh-18) }
  .stats-stack { gap:40px }
  .stats-band { padding:var(--sp-3) var(--sp-2) var(--sp-1) }
  .stats-total { padding:var(--sp-2) }
  .stats-part-title { font-size:var(--fs-18); line-height:var(--lh-18) }
  .stats-part-grid { gap:40px 0 }
  /* Phones: the class number only, so the curves keep their width (the names are in the supplement and the tooltip line); the
     same in the class medians beside kcat against Km, so their numbers keep their columns. */
  .stats-ridges { --ridge-label:44px }
  .stats-ridge-name, .stats-class-label .stats-ec-name { display:none }
  /* (the class numbers alone: "Class medians" wraps in their 44px, as before the plot became one grid) */
  .stats-class-dots { grid-template-columns:44px minmax(0,1fr) 1px minmax(0,1fr) max-content }
  .stats-class-ticks > span:not(:first-child, :last-child) { visibility:hidden }
  /* On phones each name sits above its bar, with its numbers right-aligned on the name's line (under Figure 5's
     headings), 8px from it, and the bar and the axis span the row, so the bars take the full width and a small segment
     (OED's accepted, BRENDA's) stays wide enough to see. A long class name (Figure 5) hyphenates; a name with a
     breakdown under it (Figure 2's Other) has its numbers on the name's first line, not on the breakdown's last. */
  .stats-chart-row, .stats-chart-axis, .stats-chart-head { grid-template-columns:minmax(0,1fr) var(--value-w,96px); column-gap:8px; row-gap:4px }
  .stats-chart-percent :is(.stats-chart-row, .stats-chart-axis, .stats-chart-head) { grid-template-columns:minmax(0,1fr) var(--value-w,64px) }
  .stats-chart-aside { grid-column:1 / -1; grid-row:3; margin-top:0 }
  /* Corrections by cause and database: a line per database instead of the table. */
  .stats-db-cause-table { display:none }
  .stats-db-blocks { display:grid }
  .stats-chart-label { grid-column:1; grid-row:1; align-self:end }
  .stats-chart.has-value-heads[data-chart="ec-classes"] .stats-chart-label { -webkit-hyphens:auto; hyphens:auto }
  .stats-chart-value { grid-column:2; grid-row:1; align-self:end }
  .stats-chart-row.has-note > .stats-chart-value { align-self:start }
  .stats-track { grid-column:1 / -1; grid-row:2 }
  .stats-chart-axis > span:first-child, .stats-chart-axis > span:last-child { display:none }
  .stats-chart-axis > .stats-axis-ticks { grid-column:1 / -1 }
  /* the axis has no empty column to reach into: its end label ends at its tick */
  .stats-axis-ticks > span:last-child { transform:translateX(-100%) }
  .stats-explanation dl > div { grid-template-columns:1fr; gap:0 }
  .stats-detail-table th, .stats-detail-table td { padding:6px 5px }
  .team-body { grid-template-columns:1fr }
  /* the loop uses the full width, so its 12px numbers stay 12px or more down to a 320px phone */
  .team-figure { border:0; border-block:1px solid var(--line); border-radius:0; padding:12px 0 }
}

@media print {
  /* The bars, swatches and columns are painted backgrounds: print them in colour even with background graphics off. */
  .stats-view, .team-view { -webkit-print-color-adjust:exact; print-color-adjust:exact }
  .stats-charts, .stats-part-grid { display:block }
  .stats-section { break-inside:avoid; margin-bottom:24px }
  /* Paper: no tooltip or switch. */
  .stats-tip, .stats-switch, .stats-contents { display:none !important }
  /* How these numbers are counted prints open (the Data ID and the counting rules); the script opens it before printing,
     this where a browser prints without telling the page. */
  .stats-method::details-content { content-visibility:visible; display:block }
  .stats-supp-all::details-content { content-visibility:visible; display:block }
  .stats-supp-toggle { display:none }
  .stats-part-title { break-after:avoid }
  .stats-ridge-panels { grid-template-columns:repeat(3,minmax(0,1fr)); max-width:none }
  .stats-ridges { --ridge-label:44px }
  .stats-ridge-name { display:none }
  .stats-totals { break-inside:avoid }
  /* Paper uses its full width (a landscape page is narrower than 1024px, where the screen keeps a 760px column). */
  .stats-shell { max-width:none; padding:0; zoom:0.8 }
  /* The headline counts keep one line each, also where the browser sizes the page as a phone (A4 measured upright). */
  .stats-totals dl { grid-template-columns:repeat(var(--stats-columns,4),minmax(0,1fr)); gap:0 }
  .stats-total:nth-child(n)::before { display:block }
  .stats-total:first-child::before { display:none }
  /* The three value-range histograms side by side on any paper size, so the figure and its caption share a page. */
  .stats-ranges { grid-template-columns:repeat(3,minmax(0,1fr)); max-width:none }
  .stats-fig > figcaption { break-before:avoid }
  /* Team on paper: the wide loop with its people and agents, then the legend in two columns, kept whole. */
  .team-view { overflow:visible; border:0 }
  .team-shell { padding:0 }
  .team-body { display:block }
  .team-figure { break-inside:avoid; margin-bottom:16px; padding:8px }
  .team-loop-wide { display:block; max-width:100% }
  .team-loop-narrow, .team-caption-wide { display:none }
  .team-caption-narrow { display:inline }
  .team-legend { grid-template-columns:repeat(2,minmax(0,1fr)); break-inside:avoid }
}

.guide-choice-link { grid-row:4; align-self:end; justify-self:start; white-space:nowrap }
.guide-note { margin:0 }
.guide-status-list dt { align-items:center; gap:7px }
.guide-citation { grid-template-columns:minmax(230px,0.75fr) minmax(360px,1fr) max-content; gap:28px; align-items:start }
.guide-citation-meta { gap:7px }

.guide-citation-line code { user-select:all }
.guide-citation-links { justify-items:start }

/* Stats and Guide: no search row. */
body:is(.stats-open,.guide-open,.team-open) .global-search { display:none }
body:is(.stats-open,.guide-open,.team-open) .app-header { grid-template-columns:max-content max-content max-content minmax(0,1fr) max-content; grid-template-areas:"brand nav links . actions" }
.brand-lockup { grid-area:brand }
.top-nav { grid-area:nav }
.external-nav { grid-area:links }
.global-search { grid-area:search }
.header-actions { grid-area:actions }
.detail-empty { display:none }

/* Column widths: the sidebar 256px (to 1439px, tablets included; at 1280-1439px the table needs the 16px so Review result
   stays in view), 288px (1440 and up); the record 440px (1024-1439), 480px (1440 and up). */
@media (max-width: 1439px) { :root { --sidebar-w:256px; --panel-w:440px } }

/* A record open on desktop: EC and the arrow give way; Status stays, with the first tag of its source line (from
   paper, not re-read) and without the other tags. The sorted column always stays (the table's data-sorted, set with
   the headers' aria-sort), so its arrow shows the order (round 17 fix pass: sorted by EC, nothing showed it); from
   1440px Organism gives way for a sorted EC instead. */
@media (min-width: 1024px) {
  body.detail-open :is(.col-open,.c-open), body.detail-open table:not([data-sorted="ec"]) :is(.col-ec,.c-ec) { display:none }
  body.detail-open #recordsBody .state-tag:not(:first-child) { display:none }
  /* With nothing in it to show (no chip, no count other than the page range), the title row takes no room (fix pass
     after round 16b: beside a record at 1024px its visually hidden lines kept a 30px row and a 45px empty band above
     Columns, Export and Sort); its hidden lines stay for screen readers. */
  .records-title:not(:has(> :not(.visually-hidden, .hidden, [hidden], #openFiltersButton))) { position:absolute; width:1px; height:1px; min-height:0; overflow:hidden; clip-path:inset(50%); padding:0 }
}
/* Below 1440px a record open beside the table also takes Organism's column (the record shows the organism), so the
   names and kcat, Km and kcat/Km stay in view (fix pass after round 16b: at 1024px the 536px pane cut kcat/Km at its
   edge, and at 1280px in a wide font seven rows read only "rat 17beta-hydroxysteroid…"). */
@media (min-width: 1024px) and (max-width: 1439px) {
  body.detail-open table:not([data-sorted="organism"]) :is(.col-organism,.c-organism) { display:none }
}
@media (min-width: 1440px) {
  body.detail-open table[data-sorted="ec"] :is(.col-organism,.c-organism) { display:none }
}

@media (max-width: 1180px) {
  .guide-citation { grid-template-columns:repeat(2,minmax(0,1fr)) }
  .guide-citation-links { grid-column:1 / -1 }
}

/* Tablets: the header in rows (brand and Download; tabs and the links out; search). */
@media (max-width: 1023px) {
  .app-header { grid-template-columns:minmax(0,1fr) max-content; grid-template-areas:"brand actions" "nav links" "search search"; column-gap:var(--sp-3); row-gap:6px; padding:var(--sp-2) var(--sp-4) 10px }
  body:is(.stats-open,.guide-open,.team-open) .app-header { grid-template-columns:minmax(0,1fr) max-content; grid-template-areas:"brand actions" "nav links" }
  /* Download ends where the links out under it end. */
  .header-actions { justify-self:end }
  .top-nav { justify-self:stretch; flex-wrap:nowrap; gap:var(--sp-1); min-width:0; overflow-x:auto; scrollbar-width:none }
  .top-nav::-webkit-scrollbar { display:none }
  .nav-tab { flex:0 0 auto; min-width:0; min-height:40px; padding:2px 10px 0 }
  .global-search { justify-self:stretch; width:100% }
}

/* A table with little room (beside the sidebar or a record, or on a tablet): tighter cells; a table still too wide
   scrolls sideways (Columns, Enzyme kept in view). */
.table-panel { container:records / inline-size }
@container records (max-width: 720px) {
  .records-header { grid-template-columns:minmax(0,1fr) }
  .records-tools { flex-wrap:wrap }
}
/* 721-1000px (beside the open sidebar or a record on a laptop): Export drops "results", and the chips
   share the toolbar's one 48px row while they fit beside it, Clear all last. When they do not fit, the toolbar keeps the
   row and the chips take the full width under it (never a narrow column, one per line and cut), with a count that is
   not the page range and "Clear search and filters". Row-reverse with the toolbar first keeps it at the right on the
   first row; the chips' block grows to fill the room left of it. */
@container records (min-width: 721px) and (max-width: 1000px) {
  .records-header { display:flex; flex-direction:row-reverse; flex-wrap:wrap; row-gap:var(--sp-2) }
  .records-tools { order:-1; flex:none }
  .records-title { flex:1 1 auto }
  .download-page-detail { display:none }
}
/* Beside an open record on a desktop the pane can be narrower still (536px at 1024px): Export drops "results" there
   too, so Columns and Export keep one row in a wide font (fix pass after round 16b: DejaVu Sans wrapped them). */
@media (min-width: 1024px) {
  @container records (max-width: 720px) {
    body.detail-open .download-page-detail { display:none }
  }
}
/* A table beside an open record (536px at 1024px) keeps its page controls on one line without the license line. */
@container records (max-width: 599px) {
  .table-licence { display:none }
}
@container records (max-width: 1100px) {
  table { --cell-x:6px }
  th.c-enzyme, td.c-enzyme { padding-left:10px }
  .load-notice.empty-notice { position:sticky; left:16px; max-width:min(520px,calc(100% - 32px)); margin:0 }
}

/* Tablets and phones: 16px gutters; the record is a full-height dialog over the page. */
@media (max-width: 1023px) {
  :root { --gutter:16px }
  body.detail-open { overflow:hidden }
  /* The record is a dialog here: Tab stays inside it, never on the skip link behind it. */
  body.detail-open .skip-link { display:none }
  .detail-panel { position:fixed; inset:0 0 0 auto; z-index:70; width:min(440px,100vw); height:100vh; height:100dvh; max-height:100vh; max-height:100dvh; box-shadow:var(--shadow-panel); transform:translateX(calc(100% + 18px)); visibility:hidden; pointer-events:none; transition:transform 160ms ease, visibility 160ms ease }
  body.detail-open .detail-panel { transform:translateX(0); visibility:visible; pointer-events:auto }
  /* Every column fits from about 910px. */
  table { min-width:900px }
  .col-ec { width:72px }
  .col-kcat, .col-km { width:80px }
  .col-efficiency { width:96px }
  .col-state { width:168px }
  .col-open { width:20px }
}

@media (max-width: 720px) {
  .brand-lockup { flex-wrap:wrap; min-width:0 }
  .header-actions { flex-wrap:wrap }
  .download-options { width:min(330px,calc(100vw - 32px)) }
  .detail-panel { width:100vw; border-left:0 }
  .table-scroll-controls > span { display:none }
  .pagination { display:grid; grid-template-columns:max-content 64px minmax(0,1fr) 32px 32px; gap:6px; padding:8px 12px }
  .table-licence { display:none }
  .pagination-label-detail { display:none }
  #pageLabel { margin-left:0; min-width:0; font-size:var(--fs-12) }
  .kv-line { grid-template-columns:96px minmax(0,1fr) }
  /* The record's values: Where goes under As printed. */
  .values-table :is(th,td).vt-where { display:none }
  .values-table small.vt-where-inline { display:block }
}

/* The narrowest phones: each row of a record's lists (Source, Against the databases, Conditions, ...) puts its label above
   its value, so a sentence or a comparison takes the panel's whole width instead of a narrow column beside the labels. */
@media (max-width: 400px) {
  .detail-kv { gap:10px }
  .kv-line { grid-template-columns:minmax(0,1fr); row-gap:2px }
}

/* On a phone or a screen up to 900px tall only the record's name and × stay in view as it scrolls (the whole header
   takes a third of the record or more there, with a long name almost half); EC, substrate, status and the record ID
   scroll with the record, and a rule shows under the name once it does. */
@media (max-width: 640px), (max-height: 900px) {
  .detail-top { display:contents }
  .detail-title { position:sticky; top:0; z-index:2; border-bottom:1px solid transparent; background:var(--bg); padding:var(--sp-4) 112px var(--sp-2) 20px }
  .detail-panel.is-scrolled .detail-title { border-bottom-color:var(--line) }
  .detail-title h2 { margin:0 }
  .detail-top > p { margin-bottom:var(--sp-1); padding:0 20px }
  .detail-top > p.detail-status { margin-right:20px; margin-left:20px; padding-right:0; padding-left:0 }
  .detail-top > p:last-child { margin-bottom:0; padding-bottom:12px }
  .detail-top + .detail-section { border-top:1px solid var(--line) }
}

/* Phones: a compact header and counts, one toolbar row, and each record as a card instead of a wide table. */
@media (max-width: 640px) {
  /* Brand, the links out and Download; then the four tabs across the width; then search (Browse only). */
  .app-header, body:is(.stats-open,.guide-open,.team-open) .app-header { grid-template-columns:max-content minmax(0,1fr) max-content; grid-template-areas:"brand links actions" "nav nav nav" "search search search"; column-gap:var(--sp-3); row-gap:var(--sp-1); padding:var(--sp-2) var(--sp-4) }
  body:is(.stats-open,.guide-open,.team-open) .app-header { grid-template-areas:"brand links actions" "nav nav nav" }
  .top-nav { gap:0 }
  .nav-tab { flex:1 1 0; min-height:40px; padding:2px var(--sp-1) 0 }
  /* The links out never run into the brand: with a wide system font they take two lines at the right instead. */
  .external-nav { justify-self:end; flex-wrap:wrap; justify-content:flex-end; min-width:0; gap:0 var(--sp-3); border-left:0; padding-left:0 }
  .nav-external { font-size:var(--fs-12) }
  .nav-external-long, .download-data-word { display:none }
  .nav-external-short { display:inline }
  .brand-lockup span:not(.visually-hidden) { display:none }
  .detail-top h2 { font-size:var(--fs-18) }
  /* The record's values: calc. and "!" go under the number, so As printed keeps its room and the table its width. */
  .values-table :is(th,td) { padding-right:6px; padding-left:6px }
  /* Unit's own cells 3px each side: a unit's minus signs (U+2212, wider than a hyphen, in DejaVu Sans most) would
     otherwise take As printed's room. */
  .values-table :is(thead th, tbody td):nth-child(3) { padding-right:3px; padding-left:3px }
  .values-table td.vt-value .vt-number { display:block }
  .values-table td.vt-value .vt-ghost { display:none }
  .values-table td.vt-value .metric-origin { margin-left:0 }
  .values-table td.vt-value .metric-origin + .value-flag { margin-left:4px }
  .values-table td.vt-value .value-approved.vt-ghost { display:inline }
  .values-table th.vt-value .vt-ghost:not(.value-approved) { display:none }
  .values-table .vt-printed { overflow-wrap:anywhere }
  body.filters-open { overflow:hidden }
  body.filters-open .skip-link { display:none }
  /* The page scrolls as a whole (2026-10-15: a pinned header, counts band and toolbar left 1.5-2.5 cards of list in
     view, kept Safari's toolbars from collapsing, and on an iPhone SE put the pager below the window): the list is as
     tall as its cards, the pager sticks to the foot of the window, and the page keeps its place behind the filter sheet
     and an open record. Browse only: Stats, the Guide and Team keep scrolling inside their own view under the header. */
  body:not(.stats-open,.guide-open,.team-open) .static-app { height:auto; min-height:100vh; min-height:100dvh }
  #catalogView, .workbench, .table-panel { min-height:0; overflow:visible }
  .table-wrap { flex:none; overflow:visible }
  .pagination { position:sticky; bottom:0; z-index:5 }
  body.detail-open { overflow:hidden }
  /* One toolbar row (Filters, Export, Sort); the chips and a count that is not the page range go below it. */
  .records-header { grid-template-columns:max-content minmax(0,1fr); min-height:0; align-items:center; gap:var(--sp-2); padding:var(--sp-2) var(--sp-4) }
  .records-title { display:contents }
  #openFiltersButton { display:inline-flex; grid-column:1; grid-row:1 }
  .records-tools { grid-column:2; grid-row:1; flex-wrap:nowrap; min-width:0 }
  #pageSummary, #clearResultsButton, #activeFilters { grid-column:1 / -1; grid-row:auto; justify-self:start }
  /* The chips row never grows past its row (a long chip ends in "…"): the table's box no longer clips it on phones. */
  #activeFilters { max-width:100%; min-width:0 }
  /* The cards have no headers: Sort ↑ (the direction, a tap reverses it) and the column menu stand in for them. "Sort"
     shows beside the menu where it fits (from 390px, 410px with a filter on), so the menu never reads as a review-result
     filter; narrower, its arrow alone does. */
  .sort-control { display:inline-flex; flex:1 1 auto; gap:var(--sp-1) }
  .records-tools select { flex:1 1 auto; width:auto; min-width:0 }
  .download-page-detail { display:none }
  /* Export results opens across the toolbar, inside the page's gutters. */
  .records-header { position:relative }
  .export-menu { position:static }
  .export-menu .download-options { top:calc(100% - 4px); left:16px; right:16px; width:auto }
  .table-scroll-controls { display:none }
  #recordTableWrap table, #recordTableWrap tbody { display:block; width:100%; min-width:0 !important }
  #recordTableWrap colgroup { display:none }
  /* Cards sort with the Sort control: the hidden column headers are no tab stops. */
  #recordTableWrap thead { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); visibility:hidden }
  #recordsBody tr { display:block; height:auto; border-bottom:1px solid var(--line-soft) }
  #recordsBody tr:nth-child(even) { background:var(--bg) }
  #recordsBody td { display:block; position:static; min-width:0; border:0; box-shadow:none; background:transparent; padding:0 }
  #recordsBody tr[data-key] { display:flex; flex-wrap:wrap; align-items:flex-start; gap:2px 12px; padding:10px 16px 12px }
  #recordsBody tr[data-key]:hover:not(.selected) { background:var(--hover) }
  #recordsBody tr.selected { background:var(--accent-tint); box-shadow:inset 3px 0 0 var(--accent) }
  #recordsBody tr.selected td, #recordsBody tr.selected td.c-enzyme { background:transparent; box-shadow:none }
  /* Name, then EC at the line's end; the row's ::before and ::after and the arrow cell are line breaks. */
  #recordsBody td.c-enzyme { flex:1 1 0; font-size:var(--fs-14) }
  #recordsBody td.c-ec { flex:0 1 auto; max-width:40%; margin-top:1px; color:var(--muted); font-size:var(--fs-12) }
  #recordsBody td.c-ec .clamp-2 { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
  #recordsBody td.c-ec .clamp-2::before { content:"EC\00a0" }
  #recordsBody tr[data-key]::before, #recordsBody tr[data-key]::after, #recordsBody td.c-open { content:""; flex:0 0 100%; height:0; overflow:hidden; order:1 }
  #recordsBody td.c-open { order:3 }
  #recordsBody tr[data-key]::after { order:5 }
  #recordsBody :is(td.c-organism,td.c-substrate) { order:2; flex:1 1 0; color:var(--text-2) }
  /* "organism · substrate": the card's 12px gap is taken back, so the dot has the same 4px on each side. */
  #recordsBody td.c-organism { flex:0 1 auto; max-width:60%; margin-right:-12px }
  /* Each wraps to two lines before it is cut, so cards that differ only in their substrate read apart on a phone (the
     full name stays in the title). */
  #recordsBody :is(td.c-organism,td.c-substrate) .clamp-2 { display:-webkit-box; max-height:none; overflow:hidden; -webkit-box-orient:vertical; -webkit-line-clamp:2; overflow-wrap:anywhere; white-space:normal }
  #recordsBody td.c-substrate .clamp-2::before { content:"\00b7"; content:"\00b7" / ""; margin:0 4px }
  /* The variant line comes right under the name, as in the table (the name keeps its two lines), then organism ·
     substrate and any note under them: a note never parts a variant from its enzyme. */
  #recordsBody .primary-cell .enzyme-form { display:none }
  #recordsBody .clamp-2.has-form { max-height:34px; -webkit-line-clamp:2 }
  #recordsBody td.c-form { display:block; order:1; flex:0 0 100% }
  /* A condition note is a grey line of its own under organism · substrate. */
  #recordsBody td.c-substrate.has-note { display:contents }
  #recordsBody td.c-substrate.has-note > .clamp-2 { order:2; flex:1 1 0; min-width:0; color:var(--text-2) }
  #recordsBody td.c-substrate .condition-note { order:2; flex:0 0 100%; font-size:var(--fs-12) }
  #recordsBody :is(td.c-kcat,td.c-km,td.c-eff) { order:4; flex:1 1 0; text-align:left; white-space:normal }
  /* The values lead the card (round 15 polish: at 13px/400 they had been its quietest text, under their 12px labels and
     beside a 13px/500 Accepted): 16/20px, 500, tabular; calc. and a caution's words keep their 12px. */
  #recordsBody :is(td.c-kcat,td.c-km,td.c-eff) .metric-with-note { font-size:var(--fs-16); font-weight:500; line-height:20px; font-variant-numeric:tabular-nums lining-nums }
  #recordsBody :is(td.c-kcat,td.c-km,td.c-eff) .metric-with-note :is(.metric-origin, .metric-inline-unit, .value-flag) { font-weight:400 }
  /* Each label is its name and unit as the table's headings write them, "kcat (s⁻¹)" with italic k and subscript cat; a
     label too wide breaks only before its unit. A value too wide for its cell (a wide font at 320px) breaks before its
     "× 10". */
  #recordsBody .card-label { display:block; color:var(--muted); font-size:var(--fs-12); line-height:14px }
  #recordsBody .card-label-unit { white-space:nowrap }
  #recordsBody .metric-with-note { justify-content:flex-start }
  #recordsBody .scientific-number { white-space:normal }
  #recordsBody .scientific-number sup { white-space:nowrap }
  /* The status keeps its two lines (status, then the source and tags). */
  #recordsBody td.c-status { order:6; flex:1 1 0; align-self:center }

  /* A caution shows its short words beside the "!" (no tooltip on a touch screen). Words wider than the value's third of
     the card ("above diffusion limit · kcat/Km mismatch") wrap under each other beside the "!", never past the card. */
  #recordsBody .value-flag { display:inline-flex; flex:0 1 auto; min-width:0; max-width:100%; align-items:flex-start; gap:3px; width:auto; height:auto; background:none; box-shadow:none; color:var(--caution); font-size:var(--fs-12); line-height:14px }
  #recordsBody .value-flag::before { display:grid; flex:0 0 14px; place-items:center; width:14px; height:14px; border-radius:50%; background:var(--caution-mark); box-shadow:inset 0 0 0 1px var(--caution-ring); color:var(--text) }
  #recordsBody .value-flag .visually-hidden { position:static; width:auto; min-width:0; height:auto; margin:0; clip:auto; clip-path:none; white-space:normal; overflow-wrap:anywhere }
  #recordsBody .state-tags { min-width:0; white-space:nowrap }
  #recordsBody tr.skeleton-row { padding:14px 16px }
  #recordsBody tr.skeleton-row td:not(.c-enzyme,.c-organism,.c-kcat) { display:none }
  #recordsBody tr.skeleton-row td { padding:3px 0 }
  #recordsBody tr.skeleton-row td.num span { width:30%; margin-left:0 }
  #recordsBody :is(tr.empty-row,tr.loading-row) td { padding:24px 16px }
  .load-notice.empty-notice { position:static; max-width:none }
}
/* The narrowest phones (an iPhone SE's 320px): side by side, organism and substrate each get too little width for two
   lines, so the substrate takes its own line under the organism, without the dot; on any phone a card whose organism
   takes two lines beside its substrate does the same (fitCardOrganisms). */
@media (max-width: 360px) {
  #recordsBody td.c-organism { flex:1 1 100%; max-width:none; margin-right:0 }
  #recordsBody td.c-substrate, #recordsBody td.c-substrate.has-note > .clamp-2 { flex:1 1 100% }
  #recordsBody td.c-substrate .clamp-2::before { content:none }
}
@media (max-width: 640px) {
  #recordsBody tr.organism-wraps td.c-organism { flex:1 1 100%; max-width:none; margin-right:0 }
  #recordsBody tr.organism-wraps :is(td.c-substrate, td.c-substrate.has-note > .clamp-2) { flex:1 1 100% }
  #recordsBody tr.organism-wraps td.c-substrate .clamp-2::before { content:none }
}

/* Phones and touch screens: the record's ‹, › and × are 44px targets with 8px more before ×, so a near miss on › never
   closes the record; the name keeps their 148px clear (the buttons' 140px and 4px on each side) and its line their
   height, so the line under a one-line name starts below them. */
@media (max-width: 640px), (pointer: coarse) {
  .detail-title .detail-title-buttons { top:4px; right:4px }
  .detail-title-buttons .icon-button { width:44px; height:44px }
  .detail-title-buttons .close-detail { margin-left:8px }
  .detail-title { min-height:32px; padding-right:92px }
}
@media (max-width: 640px), (max-height: 900px) and (pointer: coarse) {
  .detail-title { padding-right:148px }
}
/* Phones: the name keeps ‹ › × clear only beside them (a float their width and height: 128px from the 20px padding,
   32px from the 16px one), and takes the panel's width below them, so a long name is not a narrow column of short
   lines. */
@media (max-width: 640px) {
  .detail-title { padding-right:20px }
  .detail-title::before { content:""; float:right; width:128px; height:32px }
}
/* Phones and touch screens: a "?" (a filter group's, the record's Against the databases) keeps its 24px circle and
   is a 44px target, its hit area 10px round the circle (inside the group's 44px title row, clear of the chevron; above
   the record section's first line). */
@media (max-width: 640px), (pointer: coarse) {
  .detail-section.has-about > .section-about { position:relative }
  .section-about::after { content:""; position:absolute; inset:-11px }
}

/* Phones below 390px: kcat/Km (mM⁻¹ s⁻¹) does not fit its card's third, so every value label puts its unit on a second
   line ("kcat" over "(s⁻¹)"), as the table's headings do, and the three values stay on one line. */
@media (max-width: 389px) {
  #recordsBody .card-label-unit { display:block; margin-top:2px }
}

/* Phones above 360px, a record without As printed (an older record): Unit has the room, so calc. and "!" stay beside the
   number as on a wide screen and every row keeps one line; a unit wraps before the table outgrows its section. */
@media (min-width: 361px) and (max-width: 640px) {
  .values-table.vt-no-printed td.vt-value .vt-number { display:inline }
  .values-table.vt-no-printed td.vt-value .vt-ghost { display:inline }
  /* the "!" keeps its 14px when unseen too, so a row without one ends where a row with one does */
  .values-table.vt-no-printed td.vt-value .value-flag.vt-ghost { display:inline-grid }
  .values-table.vt-no-printed td.vt-value .metric-origin { margin-left:4px }
  .values-table.vt-no-printed td.vt-value .value-flag,
  .values-table.vt-no-printed td.vt-value .metric-origin + .value-flag { margin-left:6px }
  .values-table.vt-no-printed th.vt-value .vt-ghost:not(.value-approved) { display:inline-block }
  .values-table.vt-no-printed .vt-unit { white-space:normal }
}

/* Phones from 361px, a record with checks and As printed: the check takes 16px of Value, so with a wide system font
   (Verdana, DejaVu) As printed once broke a printed number ("0.0004" over "8"). There each number of As printed (and
   each unit with its power, min-1) stays whole, and up to 420px a two-part unit (mM⁻¹ s⁻¹) may take two lines and the
   cells come 2px closer (as at 360px), which gives As printed back about 35px: the table stays inside its section. */
@media (min-width: 361px) {
  .values-table.vt-checks .vt-printed .vt-whole { white-space:nowrap }
}
@media (min-width: 361px) and (max-width: 420px) {
  .values-table.vt-checks:not(.vt-no-printed) .vt-unit { white-space:normal }
  .values-table.vt-checks:not(.vt-no-printed) :is(th,td) { padding-right:4px; padding-left:4px }
  .values-table.vt-checks:not(.vt-no-printed) :is(th,td):first-child { padding-left:0 }
  .values-table.vt-checks:not(.vt-no-printed) :is(th,td):last-child { padding-right:0 }
}

/* Narrow phones (320px): a two-part unit (s⁻¹ mM⁻¹) may take two lines, so As printed keeps about 70px. The cells come
   closer than on other phones (here, after their 6px), and Value, whose numbers are right-aligned, needs no left padding. */
@media (max-width: 360px) {
  .values-table .vt-unit { white-space:normal }
  .values-table :is(th,td) { padding-left:4px; padding-right:4px }
  .values-table .vt-value { padding-left:0 }
  /* A value's "!" goes under its number at the right, as calc. does (a block box of 14px ignores text-align, so it once
     sat at the cell's left edge, far from its number). */
  .values-table td.vt-value .value-flag,
  .values-table td.vt-value .metric-origin + .value-flag { margin-left:auto }
}

/* Round 15 polish: on a phone a record's values read as the Guide's phone mock: parameter, value and unit on one line and
   "As printed: ..." on its own line under them, so Unit and As printed never run together ("mM⁻¹ s⁻¹ 0.01 mM⁻¹ s⁻¹") and
   calc. and the "!" stay beside their number. Label and Unit have fixed widths and every row keeps unseen copies of the
   others' marks, so the numbers end at one place. The column heads stay for screen readers. A record without As printed
   keeps its three columns. */
@media (max-width: 640px) {
  .values-table:not(.vt-no-printed), .values-table:not(.vt-no-printed) tbody { display:block; width:100% }
  .values-table:not(.vt-no-printed) thead { position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
  .values-table:not(.vt-no-printed) caption { display:block }
  .values-table:not(.vt-no-printed) tbody tr { display:grid; grid-template-columns:4.5em minmax(0, 1fr) 5.5em; align-items:baseline; column-gap:8px; border-bottom:1px solid var(--line-soft) }
  .values-table:not(.vt-no-printed) tbody :is(th, td) { width:auto; border-bottom:0; padding:6px 0 0 }
  .values-table:not(.vt-no-printed) tbody th { white-space:normal }
  .values-table:not(.vt-no-printed) td.vt-unit { padding:6px 0 0; white-space:normal }
  .values-table:not(.vt-no-printed) td.vt-printed { grid-column:1 / -1; padding:2px 0 6px; color:var(--text-2) }
  .values-table:not(.vt-no-printed) td.vt-printed::before { content:"As printed: "; color:var(--muted) }
  .values-table:not(.vt-no-printed) td.vt-value .vt-number { display:inline }
  .values-table:not(.vt-no-printed) td.vt-value .vt-ghost { display:inline }
  .values-table:not(.vt-no-printed) td.vt-value .value-flag { display:inline-grid; margin-left:6px }
  .values-table:not(.vt-no-printed) td.vt-value .metric-origin { display:inline; margin-left:4px }
  .values-table:not(.vt-no-printed) td.vt-value .metric-origin + .value-flag { margin-left:6px }
}
/* Below 340px Value has under 150px, too little for a long number with its check, calc. and "!" in a wide font: they go
   under their number at the right, as before, so a long number never pushes them onto a line of their own. */
@media (max-width: 339px) {
  .values-table:not(.vt-no-printed) td.vt-value .vt-number { display:block }
  .values-table:not(.vt-no-printed) td.vt-value .vt-ghost:not(.value-approved) { display:none }
  .values-table:not(.vt-no-printed) td.vt-value .metric-origin { display:block; margin-left:0 }
  .values-table:not(.vt-no-printed) td.vt-value .value-flag,
  .values-table:not(.vt-no-printed) td.vt-value .metric-origin + .value-flag { display:grid; margin-left:auto }
}

@media (max-width: 520px) {
  .guide-choice-link { width:100%; white-space:normal }
}

/* The smallest phones (below 360px): "Sort" is read out but not shown (its arrow stays, a 20px target) and the
   toolbar's buttons and gaps are narrower, so the Sort menu keeps about 120px and shows "Review result" whole, a Filters
   count included. */
@media (max-width: 359px) {
  /* The header's gaps are 8px, so "Paper ↗ Lab ↗" keeps one line beside the brand; only a wider font still wraps it. */
  .app-header, body:is(.stats-open,.guide-open,.team-open) .app-header { column-gap:var(--sp-2) }
  .external-nav { column-gap:var(--sp-2) }
  .sort-direction-word { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
  .sort-direction { min-width:20px; justify-content:center }
  .records-header { column-gap:6px }
  .records-tools { gap:6px }
  .records-header :is(#openFiltersButton, .export-menu > summary) { gap:var(--sp-1); padding-inline:6px }
  /* Export drops its chevron here, as Filters has none: the menu then shows "Review result" whole. */
  .records-header .export-menu > summary .chevron { display:none }
}
/* Phones from 360px: "Sort" gives way to its arrow alone (read out still) where the Sort menu would not show "Review
   result" whole in Linux's wider DejaVu font (round 17 fix pass: it read "Review resu" at 360px with no filter on, and
   at 390px with one): to 389px, and with a filter on (the Filters count takes room too) to 409px, where the toolbar's
   buttons are narrower and its gaps close up a little as well (DejaVu had left it 2px short at 360px). */
@media (min-width: 360px) and (max-width: 389px) {
  .sort-direction-word { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
  .sort-direction { min-width:20px; justify-content:center }
}
@media (min-width: 360px) and (max-width: 409px) {
  .records-header:has(#activeFilterCount:not(.hidden)) :is(#openFiltersButton, .export-menu > summary) { gap:var(--sp-1); padding-inline:var(--sp-2) }
  .records-header:has(#activeFilterCount:not(.hidden)) { column-gap:6px }
  .records-header:has(#activeFilterCount:not(.hidden)) .sort-direction-word { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap }
  .records-header:has(#activeFilterCount:not(.hidden)) .sort-direction { min-width:20px; justify-content:center }
}

@media (prefers-reduced-motion: reduce) {
  .catalog-load-progress, .catalog-load-progress > span, .detail-panel, .filter-rail, .filter-backdrop, .chevron, tbody tr { transition:none }
}

@media print {
  @page { size:landscape; margin:10mm }
  html, body, .static-app, .table-panel, .table-wrap, tbody tr { background:var(--bg) !important }
  .static-app, #catalogView, .workbench { display:block; height:auto; min-height:0; overflow:visible }
  .top-nav, .external-nav, .guide-view, .global-search, .header-actions, .search-suggestions, .filter-column, .filter-rail, .filter-backdrop, .records-header, .pagination, .detail-panel, .c-open, .col-open, .snapshot-more, .table-panel::before, .table-panel::after { display:none !important }
  .app-header { display:block; min-height:0; padding:0 0 8px }
  .table-wrap, .table-panel, .stats-view { overflow:visible; border:0 }
  table { min-width:0 !important }
  th, td { position:static !important; box-shadow:none !important; font-size:var(--fs-12) }
  th { height:auto }
  tbody tr { height:auto; break-inside:avoid }
  .clamp-2 { display:block; max-height:none }
  .stats-charts { grid-template-columns:repeat(2,minmax(0,1fr)) }
  .stats-section { break-inside:avoid }
}

/* Guide: short and plain (round 14, the user: "still so verbose, AI-ish, confusing"). A newcomer reads in a minute what
   CatLog is, how to read a record and what each label means. One column up to 1000px; prose keeps to 68ch. A calm,
   editorial look: hairlines, no boxes round the prose, no icons, no tinted washes or shadows; the pictures (the four
   steps, the numbered record, the legend) reuse the page's own components (status words, tags, values table, filter
   chips, database squares), so their colours follow the tokens. Every rule is scoped to .guide-view, so it wins over the older
   Guide rules above. */
/* Round 15 polish: the Guide sits in Stats' and Team's 1200px container with their 24px gutters, so a view's title keeps
   its place when the tabs change (the Guide's had stood 76px further right at 1440px); its content keeps to 1000px at the
   left, and every paragraph to one measure, 68 characters of its own size (three had run the whole 1000px, about 130
   characters a line). Tables and figures keep their width. */
.guide-view .guide-shell { width:auto; max-width:1200px; margin:0 auto; padding:32px 24px 56px; color:var(--text); font-size:var(--fs-16); line-height:var(--lh-16) }
.guide-view .guide-shell > * { max-width:1000px }
.guide-view .guide-shell p:not(table p) { max-width:68ch }
.guide-view .guide-shell :is(p, dd, dt, li, summary) { font-size:var(--fs-16); line-height:var(--lh-16) }
.guide-view .guide-shell :is(h1, h2, h3) { color:var(--text); font-weight:600; letter-spacing:0 }
.guide-view .guide-shell :where(.guide-section, .guide-citation, .guide-sources, .guide-heading) > :where(p, dl, ul, details),
.guide-view .guide-shell :where(.guide-citation > div > p) { max-width:68ch }
.guide-view .guide-heading h1 { margin:0; font-size:var(--fs-24); line-height:var(--lh-24) }
.guide-view .guide-shell .guide-lead { margin:12px 0 0; color:var(--text); font-size:var(--fs-18); line-height:28px }
.guide-view .guide-shell .guide-byline { margin:8px 0 0; color:var(--muted); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-shell h2 { margin:0 0 8px; font-size:var(--fs-20); line-height:var(--lh-20) }
.guide-view .guide-shell h3 { margin:0 0 6px; font-size:var(--fs-16); line-height:var(--lh-16) }
.guide-view .guide-shell p { margin:0 0 12px; color:var(--text) }
.guide-view .guide-shell :is(sub, sup) { line-height:0 }
.guide-view .guide-shell code { font-family:var(--font-mono); font-size:var(--fs-14); overflow-wrap:anywhere }
/* Sections stack in one column, divided by a hairline. */
.guide-view :is(.guide-section, .guide-citation, .guide-sources) { display:block; margin:40px 0 0; border:0; border-top:1px solid var(--line); padding:28px 0 0 }
.guide-view .guide-shell .guide-section > h3 { margin:28px 0 8px }
/* A section reached from the contents (or its own address, #guide-units) keeps a little room above its rule. */
.guide-view [id^="guide-"] { scroll-margin-top:16px }
/* Contents: the sections as a wrapped row of plain links. */
.guide-view .guide-contents { margin:24px 0 0; border-top:1px solid var(--line); padding:14px 0 0 }
.guide-view .guide-shell .guide-contents h2 { margin:0 0 6px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-contents ul { display:flex; flex-wrap:wrap; gap:4px 20px; margin:0; padding:0; list-style:none }
.guide-view .guide-shell .guide-contents li { display:flex; padding:0; font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-contents a { display:inline-flex; min-height:28px; align-items:center; color:var(--accent); font-size:var(--fs-14); font-weight:500; line-height:var(--lh-14) }
.guide-view .guide-contents a:hover { text-decoration:underline; text-underline-offset:3px }

/* How CatLog works: the four steps (Read, Check, Compare, Review) in a row, each under a 2px accent rule with its number;
   a small arrow sits on the rule between two steps. Then what the record keeps, and two links. Upright below 900px. */
/* "How CatLog reads a value" heads the four steps as a small label under the section's one heading (its anchor,
   #guide-how-read-title, takes the focus a record's link gives it). */
.guide-view .guide-shell .guide-how-read > h3.guide-flow-title { margin:16px 0 10px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-flow { display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:24px; margin:0; padding:0; list-style:none; counter-reset:flow }
.guide-view .guide-shell .guide-flow-step { position:relative; display:grid; grid-template-columns:minmax(0, 1fr); align-content:start; gap:4px; border-top:2px solid var(--accent); padding:10px 0 0; counter-increment:flow }
.guide-view .guide-flow-step + .guide-flow-step::before { content:""; position:absolute; top:-6px; left:-17px; width:6px; height:6px; border-top:2px solid var(--muted); border-right:2px solid var(--muted); transform:rotate(45deg) }
.guide-view .guide-flow-name { font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.guide-view .guide-flow-name::before { content:counter(flow) "\00a0\00a0"; content:counter(flow) "\00a0\00a0" / ""; color:var(--accent); font-variant-numeric:tabular-nums }
.guide-view .guide-flow-text { color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-shell .guide-keeps { margin:20px 0 0; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
/* The earlier version, in two short sentences under the four steps (#guide-earlier: a record not yet re-read links it). */
.guide-view .guide-shell .guide-earlier > h3.guide-flow-title { margin:24px 0 6px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-shell .guide-earlier > p { margin:0; max-width:68ch; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-shell .guide-loop-links { display:flex; flex-wrap:wrap; gap:4px 24px; margin:12px 0 0; font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-loop-links a { white-space:nowrap }
.guide-view .guide-loop-links a::after { content:"\00a0\2192"; content:"\00a0\2192" / "" }

/* Read a record: a record drawn with the panel's own parts, each numbered, beside the key to the numbers. The numbers
   are CSS counters, so a part the snapshot does not have (Against the databases) leaves no gap. They are plain accent
   figures, as a journal figure labels its parts (round 14: no filled discs). */
.guide-view .guide-anatomy { display:grid; grid-template-columns:minmax(0, 440px) minmax(0, 1fr); gap:24px 32px; align-items:start; margin:16px 0 0 }
.guide-view .guide-anatomy-card { border:1px solid var(--line); border-radius:var(--radius); background:var(--bg); counter-reset:part }
.guide-view .guide-anatomy-part { position:relative; border-bottom:1px solid var(--line-soft); padding:12px 16px 12px 44px; counter-increment:part }
.guide-view .guide-anatomy-part:last-child { border-bottom:0 }
.guide-view .guide-pin, .guide-view .guide-anatomy-key li::before { display:grid; width:20px; height:20px; place-items:center; color:var(--accent); font-size:var(--fs-14); font-weight:600; line-height:1; font-variant-numeric:tabular-nums lining-nums }
.guide-view .guide-pin { position:absolute; top:13px; left:13px }
.guide-view .guide-pin::before { content:counter(part) }
.guide-view .guide-shell .guide-anatomy-card :is(p, li) { margin:0; font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-shell .guide-anatomy-card .guide-anatomy-title { font-size:var(--fs-18); font-weight:600; line-height:var(--lh-18) }
.guide-view .guide-shell .guide-anatomy-card .guide-anatomy-meta { margin-top:2px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.guide-view .guide-shell .guide-anatomy-card .guide-anatomy-heading { margin-bottom:6px; font-weight:600 }
.guide-view .guide-anatomy-status { --status-ink:var(--st-accepted-ink); margin:0 }
.guide-view .guide-anatomy-card .values-table { margin:0 }
.guide-view .guide-shell .guide-anatomy-card .guide-anatomy-quote { border-left:2px solid var(--line); padding-left:10px; color:var(--text-2) }
.guide-view .guide-anatomy-quote > span { color:var(--text); font-weight:600 }
.guide-view .guide-anatomy-db { display:grid; gap:4px; padding:0; list-style:none }
.guide-view .guide-shell .guide-anatomy-checks .guide-anatomy-meta > span { margin-right:6px; color:var(--muted) }
.guide-view .guide-anatomy-db .db-mark { margin-right:6px }
.guide-view .guide-shell .guide-anatomy-more p { display:flex; flex-wrap:wrap; gap:4px 16px; color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }
.guide-view .guide-anatomy-key ol { margin:0; padding:0; list-style:none; counter-reset:key }
.guide-view .guide-shell .guide-anatomy-key li { position:relative; padding:0 0 14px 32px; color:var(--text-2); counter-increment:key }
.guide-view .guide-anatomy-key li::before { content:counter(key); position:absolute; top:2px; left:0 }
.guide-view .guide-anatomy-key strong { display:block; color:var(--text) }
.guide-view .guide-shell .guide-tip { margin:16px 0 0; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
/* Records and values (#guide-words, round 17, the user: "how are they going to know the values and records and
   entries?"): one Browse row drawn with the table's own cells and review badge, a bracket over its three values and one
   under the whole row (plain hairline brackets in --line-strong, muted 13px labels: a journal figure's annotation, no
   colour of their own); under 900px the row stacks as Browse's phone card does. Then the three words and the labels. */
.guide-view .guide-row-example { max-width:1000px; margin:16px 0 20px }
.guide-view .guide-row { display:grid; grid-template-columns:minmax(0, 1.4fr) minmax(0, 1fr) minmax(0, 1.2fr) max-content max-content max-content minmax(9.5em, max-content);
  grid-template-areas:". . . vb vb vb ." "h1 h2 h3 h4 h5 h6 h7" "c1 c2 c3 c4 c5 c6 c7" "rb rb rb rb rb rb rb"; column-gap:20px; align-items:start }
.guide-view .guide-row-head { align-self:end; border-bottom:1px solid var(--line); padding:0 0 6px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-row-head .header-unit { display:block; font-weight:400 }
.guide-view .guide-row-cell { padding:9px 0 10px; color:var(--text); font-size:var(--fs-14); line-height:var(--lh-14); overflow-wrap:anywhere }
.guide-view .guide-row-cell strong { font-weight:600 }
.guide-view .guide-row :is(.guide-row-head, .guide-row-cell).num { text-align:right; font-variant-numeric:tabular-nums lining-nums; white-space:nowrap; overflow-wrap:normal }
.guide-view .guide-row .state-badge { height:auto; row-gap:2px }
.guide-view .guide-row-span { position:relative; display:block; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13); text-align:center }
.guide-view .guide-row-span::after { content:""; position:absolute; left:0; right:0; height:6px; border:1px solid var(--line-strong) }
.guide-view .gr-values-span { grid-area:vb; margin:0 0 6px; padding:0 0 9px }
.guide-view .gr-values-span::after { bottom:0; border-bottom:0 }
.guide-view .gr-record-span { grid-area:rb; padding:11px 0 0 }
.guide-view .gr-record-span::after { top:0; border-top:0 }
.guide-view .gr-h-enzyme { grid-area:h1 } .guide-view .gr-h-organism { grid-area:h2 } .guide-view .gr-h-substrate { grid-area:h3 }
.guide-view .gr-h-kcat { grid-area:h4 } .guide-view .gr-h-km { grid-area:h5 } .guide-view .gr-h-eff { grid-area:h6 } .guide-view .gr-h-result { grid-area:h7 }
.guide-view .gr-enzyme { grid-area:c1 } .guide-view .gr-organism { grid-area:c2 } .guide-view .gr-substrate { grid-area:c3 }
.guide-view .gr-kcat { grid-area:c4 } .guide-view .gr-km { grid-area:c5 } .guide-view .gr-eff { grid-area:c6 } .guide-view .gr-result { grid-area:c7 }
.guide-view .guide-shell .guide-row-example figcaption { margin:10px 0 0; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-words-list dt { font-weight:600 }
.guide-view .guide-labels { margin-top:24px }
/* License and citation (#guide-licence, round 17): said once here; Browse's footer line links to it. */
.guide-view .guide-shell .guide-citation-meta dd > p { max-width:68ch; margin:0 0 6px }
.guide-view .guide-shell .guide-citation-meta dd > p:last-child { margin:0 }
.guide-view .guide-licence .guide-citation-meta { margin-bottom:16px }
.guide-view .guide-licence .guide-ref:first-of-type { margin-top:0 }
@media (max-width: 899px) {
  .guide-view .guide-row { grid-template-columns:repeat(3, minmax(0, 1fr)); max-width:480px; column-gap:16px;
    grid-template-areas:"c1 c1 c1" "c2 c2 c2" "c3 c3 c3" "vb vb vb" "h4 h5 h6" "c4 c5 c6" "c7 c7 c7" "rb rb rb" }
  .guide-view :is(.gr-h-enzyme, .gr-h-organism, .gr-h-substrate, .gr-h-result) { display:none }
  .guide-view .guide-row-cell { padding:2px 0 }
  .guide-view .gr-enzyme { font-size:var(--fs-16); line-height:var(--lh-16) }
  .guide-view :is(.gr-organism, .gr-substrate) { color:var(--text-2) }
  .guide-view .gr-values-span { margin-top:12px }
  .guide-view .guide-row :is(.guide-row-head, .guide-row-cell).num { text-align:left }
  .guide-view .gr-result { padding-top:10px }
}

/* Labels and colours: small legends in a grid (review result, tags, marks beside a value, against the databases, filters
   in use), each under a hairline, drawn with the table's own dot, tags, marks, squares and chips. */
.guide-view .guide-legend-grid { display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:24px 32px; margin:16px 0 0 }
.guide-view .guide-legend-group { min-width:0; border-top:1px solid var(--line); padding:10px 0 0 }
.guide-view .guide-shell .guide-legend-group > h3 { margin:0 0 2px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-legend-group .guide-status-list { margin:0; border-top:0 }
/* One term width for every group of Labels and colours (round 15 polish: Tags' definitions had started 32px left of
   Against the databases' in the same column), as wide as the databases' longest name with its square. */
.guide-view .guide-legend-group .guide-status-list > div { grid-template-columns:11.5em minmax(0, 1fr); gap:2px 12px; padding:7px 0 }
.guide-view .guide-shell .guide-legend-group :is(dt, dd) { font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-legend-group .guide-status-list .state-badge, .guide-view .guide-legend-group .guide-tag-list .state-tag { font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-legend-wide { grid-column:1 / -1 }
.guide-view .guide-legend-group .guide-db-legend dt { display:flex; align-items:baseline; gap:8px; font-weight:500 }
.guide-view .guide-legend-group .guide-db-legend .db-mark { flex:0 0 10px; align-self:flex-start; margin-top:5px }
.guide-view .guide-mark-sample { display:inline-flex; min-width:24px; align-items:center; color:var(--text-2) }
.guide-view .guide-mark-tick { color:var(--checked) }
.guide-view .guide-mark-tick .check-icon { width:14px; height:14px }
.guide-view .guide-chip-row { display:flex; flex-wrap:wrap; gap:6px; margin:6px 0 10px; padding:0; list-style:none }
.guide-view .guide-shell .guide-chip-row li { display:flex; max-width:100% }
.guide-view .guide-chip-row .filter-chip { cursor:default }
.guide-view .guide-chip-row .filter-chip:hover { border-color:var(--line-strong) }
.guide-view .guide-chip-row .filter-chip:hover .chip-x { color:var(--muted) }
.guide-view .guide-shell .guide-legend-group .guide-chip-key { color:var(--text-2); font-size:var(--fs-13); line-height:var(--lh-13) }

.guide-view .guide-link-list { display:grid; gap:8px; margin:0; padding:0; list-style:none }
.guide-view .guide-shell .guide-list-title { margin:20px 0 6px 24px; color:var(--muted); font-size:var(--fs-14); font-weight:500; line-height:var(--lh-14) }
.guide-view .guide-shell code.guide-try { border:1px solid var(--line); border-radius:2px; padding:0 5px; white-space:nowrap }
.guide-view .guide-flag { vertical-align:-2px; cursor:default }
/* Cautions: one table, a row per Cautions filter group (its name as the sidebar gives it), the cautions it holds as a
   plain list, each caution's name (as shown beside a value) in 600 and what it means in brackets; 14px, rules between
   rows. On phones each row stacks: the group, then its cautions. */
.guide-view .guide-caution-table { width:100%; margin:12px 0 0; border-collapse:collapse; table-layout:fixed }
.guide-view .guide-caution-table :is(th, td) { position:static; height:auto; border:0; border-top:1px solid var(--line-soft); background:transparent; padding:8px 16px 8px 0; color:var(--text-2); font-size:var(--fs-14); font-weight:400; line-height:var(--lh-14); text-align:left; vertical-align:top; white-space:normal }
/* (not the records table's rows: no fixed height, pointer or hover tint, no 900px minimum on narrow screens) */
.guide-view :is(.guide-caution-table, .guide-db-table) { min-width:0 }
.guide-view :is(.guide-caution-table, .guide-db-table) tbody tr, .guide-view :is(.guide-caution-table, .guide-db-table) tbody tr:is(:nth-child(even), :hover) { height:auto; background:transparent; cursor:default; transition:none }
.guide-view .guide-caution-table thead th { border-top:0; padding-top:0; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-caution-table thead th:nth-child(1) { width:28% }
.guide-view .guide-caution-table tbody th { color:var(--text); font-weight:600 }
.guide-view .guide-caution-table td :is(ul, p) { margin:0; padding:0; list-style:none; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-caution-table td p { margin-bottom:4px; color:var(--text) }
.guide-view .guide-shell .guide-caution-table td li { padding:0 0 4px; font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-caution-table td li:last-child { padding-bottom:0 }
.guide-view .guide-caution-table td strong { color:var(--text); font-weight:600 }
.guide-view .guide-caution-table :is(th, td):last-child { padding-right:0 }
.guide-view .guide-questions .guide-details > p { margin:8px 0 0; border-left:2px solid var(--line-soft); padding-left:16px }
/* Reference: Find records, Units, Downloads, Cite and Sources and licenses, each one row that folds open (closed at
   first; an address or link to one opens it): its name (16px/600) and a 14px gist of what it holds, a + or − before
   them; open, its content under the row. */
.guide-view .guide-ref { max-width:none; margin:0; border-top:1px solid var(--line-soft); padding:0 }
.guide-view .guide-ref:last-child { border-bottom:1px solid var(--line-soft) }
.guide-view .guide-ref > summary { position:relative; display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 16px; min-height:44px; cursor:pointer; list-style:none; padding:10px 0 10px 24px }
.guide-view .guide-ref > summary::-webkit-details-marker { display:none }
.guide-view .guide-ref > summary::before { content:"+"; content:"+" / ""; position:absolute; left:2px; top:10px; color:var(--muted); font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.guide-view .guide-ref[open] > summary::before { content:"\2212"; content:"\2212" / "" }
.guide-view .guide-shell .guide-ref > summary h3 { margin:0; color:var(--text); font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.guide-view .guide-shell .guide-ref-gist { color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-ref > summary:hover h3 { color:var(--accent) }
.guide-view .guide-ref > summary:focus-visible { outline:2px solid var(--accent); outline-offset:2px }
.guide-view .guide-ref > :not(summary) { max-width:68ch; margin-left:24px }
.guide-view .guide-ref > :last-child { margin-bottom:16px }
.guide-view .guide-shell .guide-reference > h2 { margin-bottom:8px }
/* Units: the three catalog units as rows (name, unit, meaning) under hairlines, then the rules in a list. */
.guide-view .guide-unit-cards { display:grid; gap:0; margin:0 0 12px; border-top:1px solid var(--line-soft); padding:0; list-style:none }
.guide-view .guide-shell .guide-unit-cards li { display:grid; grid-template-columns:5em 9em minmax(0, 1fr); align-items:baseline; column-gap:16px; border-bottom:1px solid var(--line-soft); padding:8px 0 }
.guide-view .guide-unit-name { color:var(--text-2); font-size:var(--fs-14); font-weight:600 }
.guide-view .guide-unit-value { color:var(--text); font-size:var(--fs-16); font-weight:600; line-height:var(--lh-16) }
.guide-view .guide-unit-what { color:var(--muted); font-size:var(--fs-14); line-height:var(--lh-14) }
/* Before you use the values: a short checklist. */
.guide-view .guide-checklist { display:grid; gap:6px; margin:0; padding:0; list-style:none }
.guide-view .guide-shell .guide-checklist li { position:relative; padding-left:22px }
/* A plain en dash as the bullet (round 14: a rotated chevron read as a closed section that does nothing). */
.guide-view .guide-checklist li::before { content:"\2013"; content:"\2013" / ""; position:absolute; top:0; left:2px; color:var(--muted) }
.guide-view .guide-choice-link { margin-top:16px; font-size:var(--fs-14) }
.guide-view .guide-shell .guide-note { margin:16px 0 0; color:var(--muted) }
/* Review status: the table's badge (the result's word in its colour, tags) beside its meaning. */
.guide-view .guide-status-list { margin:16px 0 0; border-top:1px solid var(--line-soft) }
.guide-view .guide-status-list > div { display:grid; grid-template-columns:11em minmax(0, 1fr); gap:4px 20px; align-items:start; border-bottom:1px solid var(--line-soft); padding:10px 0 }
.guide-view .guide-status-list dt { display:block }
.guide-view .guide-status-list .state-badge { display:inline-grid; height:auto; justify-items:start; align-content:start; max-width:100%; color:var(--text); font-size:var(--fs-16); line-height:var(--lh-16); white-space:nowrap }
.guide-view .guide-status-list .state-label { display:inline-flex; align-items:center; gap:4px; font-weight:500 }
.guide-view .guide-status-list .state-tags { color:var(--muted); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-status-list .state-tags:empty { display:none }
.guide-view .guide-status-list .state-tag + .state-tag::before { content:" · "; content:" · " / "" }
.guide-view .guide-status-list dd { margin:0 }
.guide-view .guide-details { margin:20px 0 0 }
.guide-view .guide-details > summary { color:var(--accent); font-weight:500; cursor:pointer }
.guide-view .guide-details > dl { margin:12px 0 0; border-left:2px solid var(--line-soft); padding-left:16px }
/* Tags: the table's tag words beside their meaning; human-checked keeps its check and colour. */
.guide-view .guide-tag-list .state-tag { color:var(--muted); font-size:var(--fs-16); font-weight:500; white-space:nowrap }
.guide-view .guide-tag-list .state-tag.human-checked { color:var(--checked) }
.guide-view .guide-tag-list .state-tag.source-paper { color:var(--src-paper-ink) }
.guide-view .guide-tag-list .check-icon { width:14px; height:14px; margin-right:4px; vertical-align:-1px }
/* Lists of terms (units, downloads, sources, citation details): term left, meaning right. */
.guide-view :is(.guide-download-list, .guide-term-list) { display:block; margin:4px 0 0; border-top:1px solid var(--line-soft) }
.guide-view :is(.guide-download-list, .guide-term-list) > div, .guide-view .guide-citation-meta > div { display:grid; grid-template-columns:11em minmax(0, 1fr); gap:4px 20px; border-bottom:1px solid var(--line-soft); padding:10px 0 }
.guide-view :is(.guide-download-list, .guide-term-list, .guide-status-list) > div:last-child { border-bottom:0 }
.guide-view :is(.guide-download-list, .guide-term-list, .guide-citation-meta) dt { color:var(--text); font-weight:600 }
.guide-view :is(.guide-download-list, .guide-term-list, .guide-citation-meta) dd { margin:0; color:var(--text); font-weight:400 }
.guide-view .guide-citation p { margin:0 0 12px; color:var(--text) }
.guide-view .guide-citation-meta { display:block; max-width:68ch; margin:8px 0 0; border-top:1px solid var(--line-soft) }
.guide-view .guide-data-id-note { display:block; margin-top:4px; color:var(--muted); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-data-id-note code { overflow-wrap:anywhere }
.guide-view .guide-citation-links { display:flex; flex-wrap:wrap; gap:8px 24px; margin:16px 0 0; font-size:var(--fs-16); font-weight:500 }
.guide-view .guide-shell .guide-sources .guide-note { margin:0 0 12px; color:var(--text) }
.guide-view .guide-shell .guide-sources .guide-curation-license { margin:16px 0 0; font-weight:400 }
/* Against the databases (#guide-databases): the lead, then the results as one table (each name after a 10px square in
   its colour, the shared .db-mark of Browse's group; Corrected earlier has none), values and records right-aligned in
   tabular figures, a row that narrows its parent indented under it; the caveat; then one disclosure with what is
   compared, the databases and three small tables side by side (one under another below 900px). */
.guide-view .guide-db-table { width:100%; max-width:640px; margin:8px 0 0; border-collapse:collapse; table-layout:auto }
.guide-view .guide-db-table caption { margin:0 0 4px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13); text-align:left }
.guide-view .guide-db-table :is(th, td) { position:static; height:auto; border:0; border-bottom:1px solid var(--line-soft); background:transparent; padding:7px 0; color:var(--text); font-size:var(--fs-14); font-weight:400; line-height:var(--lh-14); text-align:left; vertical-align:baseline; white-space:normal }
.guide-view .guide-db-table thead th { padding-top:0; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
.guide-view .guide-db-table :is(td, thead th + th) { width:6.5em; padding-left:16px; text-align:right; font-variant-numeric:tabular-nums lining-nums; white-space:nowrap }
.guide-view .guide-db-results tbody th { font-weight:500 }
.guide-view .guide-db-result { display:inline-flex; flex-wrap:wrap; align-items:baseline; column-gap:8px }
.guide-view .guide-db-mark { display:inline-block; flex:0 0 10px; width:10px; height:10px; align-self:center; vertical-align:-1px }
.guide-view .guide-db-nested th { padding-left:18px }
.guide-view .guide-db-sub { color:var(--text-2) }
.guide-view .guide-db-gloss { color:var(--muted); font-size:var(--fs-13); line-height:var(--lh-13) }
.guide-view .guide-shell .guide-db-note { margin:10px 0 0; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-db-more { max-width:none; margin:20px 0 0 }
.guide-view .guide-db-more > summary h3 { display:inline; margin:0; color:inherit; font-size:var(--fs-16); font-weight:500; line-height:var(--lh-16) }
.guide-view .guide-shell .guide-db-more > p { max-width:68ch; margin:10px 0 0; color:var(--text-2); font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-db-sources { margin:8px 0 0; padding:0; list-style:none; color:var(--text-2) }
.guide-view .guide-shell .guide-db-sources li { font-size:var(--fs-14); line-height:var(--lh-14) }
.guide-view .guide-db-count-inline { color:var(--muted) }
.guide-view .guide-db-tables { display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:16px 28px; align-items:start; margin:16px 0 0 }
.guide-view .guide-db-tables .guide-db-table { margin:0 }
@media (max-width: 899px) {
  .guide-view .guide-flow { grid-template-columns:minmax(0, 1fr); gap:12px }
  .guide-view .guide-shell .guide-flow-step { border-top:0; border-left:2px solid var(--accent); padding:0 0 0 12px }
  .guide-view .guide-flow-step + .guide-flow-step::before { display:none }
  .guide-view .guide-anatomy { grid-template-columns:minmax(0, 1fr) }
  .guide-view .guide-anatomy-card { max-width:480px }
  .guide-view .guide-db-tables { grid-template-columns:minmax(0, 1fr); max-width:640px }
}
@media (max-width: 760px) {
  .guide-view .guide-legend-grid { grid-template-columns:minmax(0, 1fr) }
}
@media (max-width: 640px) {
  .guide-view .guide-shell .guide-lead { font-size:var(--fs-16); line-height:var(--lh-16) }
  /* Cautions: each row stacks, the name over its group and meaning. */
  .guide-view .guide-caution-table thead { display:none }
  .guide-view .guide-caution-table, .guide-view .guide-caution-table tbody, .guide-view .guide-caution-table tr { display:block }
  .guide-view .guide-caution-table tr { border-top:1px solid var(--line-soft); padding:8px 0 }
  .guide-view .guide-caution-table :is(th, td) { display:block; width:auto; border:0; padding:0 }
  .guide-view .guide-caution-table tbody th { width:auto; margin-bottom:4px; color:var(--muted); font-size:var(--fs-13); font-weight:500; line-height:var(--lh-13) }
  .guide-view .guide-ref > :not(summary), .guide-view .guide-shell .guide-ref > .guide-list-title { margin-left:0 }
  /* The units as three short rows: name, unit, meaning under them. */
  .guide-view .guide-shell .guide-unit-cards li { grid-template-columns:4.5em minmax(0, 1fr); row-gap:2px }
  .guide-view .guide-unit-what { grid-column:1 / -1 }
  /* The results: values and records in narrower columns. */
  .guide-view .guide-db-table :is(td, thead th + th) { width:auto; padding-left:12px }
  /* The example record's values: each printed form on its own line under its value, as a phone has room for. */
  .guide-view .guide-values-table, .guide-view .guide-values-table tbody { display:block; width:100% }
  .guide-view .guide-values-table thead { display:none }
  .guide-view .guide-values-table caption { display:block }
  .guide-view .guide-values-table tbody tr { display:grid; grid-template-columns:4em minmax(0, 1fr) 5em; align-items:baseline; column-gap:8px; border-bottom:1px solid var(--line-soft) }
  .guide-view .guide-values-table tbody :is(th, td) { width:auto; border-bottom:0; padding:6px 0 0 }
  .guide-view .guide-values-table td.vt-printed { grid-column:1 / -1; padding:2px 0 6px; color:var(--text-2) }
  .guide-view .guide-values-table td.vt-printed::before { content:"As printed: "; color:var(--muted) }
  .guide-view .guide-legend-group .guide-status-list > div { grid-template-columns:minmax(0, 1fr) }
  /* (a mark is one character wide: it keeps its meaning beside it) */
  .guide-view .guide-legend-group .guide-mark-list > div { grid-template-columns:2.5em minmax(0, 1fr) }
  .guide-view .guide-anatomy-part { padding-left:40px }
}

@media (max-width: 640px) {
  .guide-view .guide-shell { padding:24px 16px 40px }
  .guide-view .guide-status-list > div, .guide-view :is(.guide-download-list, .guide-term-list) > div, .guide-view .guide-citation-meta > div { grid-template-columns:minmax(0, 1fr); gap:2px }
}
