/* =============================================================================
   INGANCI RESEARCH — pattern library stylesheet
   -----------------------------------------------------------------------------
   Plain CSS. No build step, no Tailwind, no preprocessor. Built against the
   pilot port of SW-R-2026-001 ("aerials") and intended to serve all six
   ported research papers without modification — only the HTML instantiates
   these classes differently per paper.

   TOKENS: every colour and every font-family in this file is a var(--...)
   reference into the host page's token stylesheet (identity/tokens.css at
   the time this was written). This file defines NO color and NO font-family
   literally — the ground palette and typeface are still open founder
   decisions (see inganci-rebuild/PLAN.md T6, the 5-way type audit). Swapping
   the token file's values must be sufficient to reskin every paper.

   Tokens consumed (all expected to exist on the host page):
     --ink  --ink-soft  --dim  --core  --hair  --hair-strong  --ground
     --raised  --sunk  --signal  --core-band
     --font-display  --font-label  --font-prose
     --measure  --shell  --gutter  --radius

   NAMING:
     .eyebrow / .kicker-index / .t-title-* / .t-body-lg / .prose-sw
       — typographic primitives, lifted verbatim (by class name) from
         statswing-site's globals.css, token-ized. Reuse these names as-is
         for the other five papers; do not rename them per-paper.
     .rp-*
       — new structural/component classes for the recurring research-article
         patterns (hero, status chip, byline, figure, table, boxes, refs,
         implications, tags, share). See the report this ships with for the
         full vocabulary list.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   0a. The one unscoped rule in this file, and it is deliberate.

   Everything else here is scoped to .rp-article so the stylesheet is safe to
   load beside host chrome. But that scoping left `body` with NO background at
   all: the ground token was declared and never painted, so the pages were
   riding on the browser's default white and merely looked correct. Published
   as an artifact — or opened by anyone whose host paints its own ground — the
   article would render dark-on-dark. A page must paint its own ground.

   `background-color` rather than the `background` shorthand, so a host that
   has set a background-image on body keeps it.
   ----------------------------------------------------------------------------- */

body {
  background-color: var(--ground);
  color: var(--ink);
  /* …and no UA gutter around it. The 8px default margin left an 8px band of
     --ground down both sides of every full-bleed element on the page — most
     visibly the implications panel, whose --raised fill and hairline edges
     stopped short of the viewport. Measured, 2026-08-25. */
  margin: 0;
}

/* -----------------------------------------------------------------------------
   0b. THE TYPE DIAL — every typographic value in this file, expressed as a role.

   Added 2026-08-25 for the research-template type audit. Before this, sizes,
   weights, tracking and leading were literals scattered through the file, which
   meant a face could only be swapped by find-and-replace and no two faces could
   be compared honestly: every face below is drawn on a different body (different
   x-height, fitting, optical weight at the same nominal size), so substituting
   one for another and leaving Archivo's numbers in place breaks three of them
   and hands the incumbent an unearned win.

   So: roles here, values in the [data-type] blocks that follow. The defaults in
   this block ARE Archivo's dial — the five papers that carry no [data-type]
   attribute render exactly as they did before this change.

   Two laws hold across every pairing because they belong to the institution,
   not to the face: prose is left-aligned, and the micro-register is caps.
   ----------------------------------------------------------------------------- */

:root {
  /* display / h1 */
  --rp-t-title:   clamp(2.35rem, 4.6vw, 3.9rem);
  --rp-w-title:   600;
  --rp-tr-title:  -0.045em;
  --rp-lh-title:  1.03;
  --rp-mw-title:  16em;   /* title measure, in title ems — controls line count */

  /* section / h2 */
  --rp-t-h2:      1.75rem;
  --rp-w-h2:      600;
  --rp-tr-h2:     -0.02em;
  --rp-lh-h2:     1.15;

  /* sub / h3 */
  --rp-t-h3:      1.28rem;
  --rp-w-h3:      600;
  --rp-tr-h3:     -0.01em;
  --rp-lh-h3:     1.2;

  /* dek / standfirst */
  --rp-t-lede:    1.3rem;
  --rp-w-lede:    400;
  --rp-tr-lede:   -0.012em;
  --rp-lh-lede:   1.5;

  /* running prose */
  --rp-t-body:    1.08rem;
  --rp-lh-body:   1.76;
  --rp-w-strong:  600;

  /* small print — boxes, captions, references, sidenotes, table */
  --rp-t-small:   14px;
  --rp-t-note:    13px;
  --rp-lh-note:   1.55;

  /* micro-register — eyebrows, status row, tags, index, meta */
  --rp-t-label:   11px;
  --rp-tr-label:  0.16em;
  --rp-w-label:   700;
  --rp-t-meta:    13px;
  --rp-tr-meta:   0.02em;

  /* ---- the vertical rhythm ----
     BEFORE (measured on the shipped page, 1440px): the article had exactly
     TWO intervals — a 20px paragraph gap and a 32px "section" gap. 1.6:1. The
     eye does not read 1.6:1 as hierarchy, so the document had no visible
     structure between "new paragraph" and "new chapter".

     AFTER (measured, same width, RECORD pairing): 21 → 42 → 86 → 112.
     Each text-hierarchy step is ~2× the one below it. The block interval
     (36px, prose ↔ figure/box) deliberately sits between the paragraph and
     the subsection: a figure is an interruption, not a subordinate section,
     and should not out-rank an h3.

     --rp-space-section is in h2 ems so it scales with the heading it opens,
     not with the body. */
  --rp-space-para:    1.15em;   /* between paragraphs, in body ems   ≈ 21px */
  --rp-space-block:   2.25rem;  /* prose ↔ figure / box / table      = 36px */
  --rp-space-section: 2.2em;    /* above an h2's RULE, in h2 ems     ≈ 60px
                                   (+0.95em rule→text = 86px total)        */
  --rp-space-field:   clamp(3rem, 8vw, 7rem);   /* masthead ↔ field  = 112px */

  /* the reading column. NOT --measure: `ch` is the width of the ZERO glyph,
     which for every face here is wider than the average lowercase letter, so a
     nominal 68ch sets ~74 real characters in Archivo — past the top of the
     45–75 band. Each pairing dials this until it sets ~68 real characters,
     measured, not assumed. See the audit note in the report. */
  --rp-measure:   62ch;   /* Archivo: 62ch sets 68 real characters */
}

/* ============================================================================
   THE FOUR PAIRINGS — long-form scholarly reading, switchable via [data-type]
   on <html>. Each is a hypothesis about what kind of institution publishes
   this page; each is dialled until it holds on its own terms.

   Production keeps exactly one of these blocks and folds it into tokens.css.
   The switcher control (.rp-typeswitch) does not ship.
   ========================================================================= */

/* -------------------------------------------------------------- 1 · RECORD
   Libre Franklin heads · Newsreader sets the text · Archivo Narrow labels.
   HYPOTHESIS: the institution is a newspaper of record — research is
   journalism with citations, and the page should look like the rest of the
   site because it is not a separate object from the company. This is the
   settled site pairing (Franklin + Newsreader) carried into the template; the
   house's condensed narrow is retained for the micro-register so the paper
   still signs itself the way every other Inganci surface does.

   Franklin Gothic headlines are heavy, so display goes to 800 and the leading
   closes. Newsreader has a generous x-height but a dense bold — strong drops
   to 600 so emphasis does not blacken the paragraph. Newsreader is narrower
   than Archivo per character, so the measure comes down in ch to hold the
   same real character count.                                                */
/* ▓▓▓ RATIFIED — Joel, 2026-08-25. RECORD is the research pairing. ▓▓▓
   The other three blocks stay for now because the switcher is still a review
   tool; on the shipped site they collapse to this one and the Google Fonts
   link drops from ten families to three. Do NOT re-open the type question by
   leaving the switcher on a public page — an institution that ships a font
   picker is still deciding. */
[data-type="record"] {
  --font-display: "Libre Franklin", system-ui, -apple-system, sans-serif;
  --font-prose:   "Newsreader", Georgia, "Times New Roman", serif;
  --font-label:   "Archivo Narrow", "Archivo", system-ui, sans-serif;

  --rp-t-title:   clamp(2.3rem, 4.5vw, 3.8rem);
  --rp-w-title:   800;
  --rp-tr-title:  -0.028em;
  --rp-lh-title:  1.0;
  --rp-mw-title:  15.5em;

  --rp-t-h2:      1.7rem;
  --rp-w-h2:      700;
  --rp-tr-h2:     -0.018em;
  --rp-lh-h2:     1.14;

  --rp-t-h3:      1.22rem;
  --rp-w-h3:      700;
  --rp-tr-h3:     -0.006em;

  --rp-t-lede:    1.35rem;
  --rp-tr-lede:   -0.008em;
  --rp-lh-lede:   1.52;

  --rp-t-body:    1.16rem;   /* Newsreader runs small at nominal size */
  --rp-lh-body:   1.68;
  --rp-w-strong:  600;       /* Newsreader 700 blackens a paragraph */

  --rp-t-small:   14.5px;
  --rp-t-note:    13.5px;

  --rp-t-label:   11px;
  --rp-tr-label:  0.16em;
  --rp-w-label:   700;
  --rp-t-meta:    13px;

  --rp-measure:   56ch;   /* Newsreader is wide per ch, narrow per letter */
  --arrow-w:      1.75;
}

/* ------------------------------------------------------------- 2 · JOURNAL
   Source Serif 4 throughout · IBM Plex Mono labels.
   HYPOTHESIS: the institution is a press. One optically-sized serif does both
   display and text, exactly as a typeset journal does — Source Serif 4 is a
   variable font with a real optical-size axis (8–60), so the title gets a
   display cut and the body gets a text cut from the same drawing, without a
   second personality. The only other voice is a mono, because everything in
   the micro-register is an identifier or a quantity — SW-R-2026-001,
   15 March 2026, [7], ≤1.5 m — and a mono renders those correctly by design:
   fixed advance, unambiguous 0/O and 1/l.

   A 600-weight serif holds display presence without clumsiness, and serifs
   need roughly a quarter of a grotesque's negative tracking. Plex Mono is the
   widest face in this file, so its label tracking falls by half or the
   micro-register turns to gravel.                                            */
[data-type="journal"] {
  --font-display: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-prose:   "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-label:   "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;

  --rp-t-title:   clamp(2.5rem, 5vw, 4.15rem);
  --rp-w-title:   600;
  --rp-tr-title:  -0.014em;
  --rp-lh-title:  1.05;
  --rp-mw-title:  15em;

  --rp-t-h2:      1.8rem;
  --rp-w-h2:      600;
  --rp-tr-h2:     -0.01em;
  --rp-lh-h2:     1.16;

  --rp-t-h3:      1.3rem;
  --rp-w-h3:      600;
  --rp-tr-h3:     -0.006em;

  --rp-t-lede:    1.38rem;
  --rp-tr-lede:   -0.006em;
  --rp-lh-lede:   1.5;

  --rp-t-body:    1.16rem;
  --rp-lh-body:   1.7;
  --rp-w-strong:  600;

  --rp-t-small:   14.5px;
  --rp-t-note:    13.5px;

  --rp-t-label:   10.5px;
  --rp-tr-label:  0.08em;    /* mono is already wide */
  --rp-w-label:   500;       /* Plex Mono 600 is heavier than Archivo Narrow 600 */
  --rp-t-meta:    12px;
  --rp-tr-meta:   0.01em;

  --rp-measure:   68ch;
  --arrow-w:      1.6;
}

/* -------------------------------------------------------------- 3 · BUREAU
   Public Sans heads · Literata sets the text · JetBrains Mono labels.
   HYPOTHESIS: the institution is a standards body. Public Sans is the United
   States Web Design System's face — the literal typeface of official
   publication, drawn to be unremarkable on purpose. Literata was commissioned
   for long-form reading on screens and has the sturdiest text colour of the
   four. JetBrains Mono carries the apparatus. The claim is neutrality and
   compliance: this is a statistical release, not an essay, and nothing about
   the typography is asking to be admired.

   Public Sans is wide and even, so display tracking eases and label tracking
   comes down. Literata has a large x-height and a wide body, so the nominal
   size barely rises and the measure falls hard in ch.                        */
[data-type="bureau"] {
  --font-display: "Public Sans", system-ui, -apple-system, sans-serif;
  --font-prose:   "Literata", Georgia, "Times New Roman", serif;
  --font-label:   "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;

  --rp-t-title:   clamp(2.2rem, 4.3vw, 3.6rem);
  --rp-w-title:   700;
  --rp-tr-title:  -0.026em;
  --rp-lh-title:  1.06;
  --rp-mw-title:  16em;

  --rp-t-h2:      1.65rem;
  --rp-w-h2:      700;
  --rp-tr-h2:     -0.016em;
  --rp-lh-h2:     1.18;

  --rp-t-h3:      1.2rem;
  --rp-w-h3:      700;
  --rp-tr-h3:     -0.006em;

  --rp-t-lede:    1.28rem;
  --rp-tr-lede:   -0.008em;
  --rp-lh-lede:   1.54;

  --rp-t-body:    1.06rem;   /* Literata already sets large */
  --rp-lh-body:   1.74;
  --rp-w-strong:  600;

  --rp-t-small:   13.5px;
  --rp-t-note:    12.5px;

  --rp-t-label:   10px;
  --rp-tr-label:  0.09em;
  --rp-w-label:   600;
  --rp-t-meta:    11.5px;
  --rp-tr-meta:   0.01em;

  --rp-measure:   63ch;
  --arrow-w:      1.5;
}

/* ---------------------------------------------------------- 4 · CONTINUITY
   Archivo heads · Spectral sets the text · IBM Plex Mono labels.
   HYPOTHESIS: only the reading face ever needed to change. The masthead stays
   on Archivo, so the research page still looks like Inganci and still ties to
   SCOUTSWING; Spectral — drawn by Production Type expressly for reading text
   on screens — takes the body, because prose is the one thing the incumbent
   build actually gets wrong; identifiers go mono. This is the minimum-change
   test: if it holds, nothing about the identity has to move at all.

   Spectral is drawn on a narrow body with a modest x-height, so its nominal
   size rises and the measure falls. Display register is untouched — that is
   the point of the pairing.                                                  */
[data-type="continuity"] {
  --font-display: "Archivo", system-ui, -apple-system, sans-serif;
  --font-prose:   "Spectral", Georgia, "Times New Roman", serif;
  --font-label:   "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;

  --rp-t-lede:    1.32rem;
  --rp-tr-lede:   -0.006em;
  --rp-lh-lede:   1.52;

  --rp-t-body:    1.13rem;
  --rp-lh-body:   1.72;
  --rp-w-strong:  600;

  --rp-t-small:   14px;
  --rp-t-note:    13px;

  --rp-t-label:   10.5px;
  --rp-tr-label:  0.08em;
  --rp-w-label:   500;
  --rp-t-meta:    12px;
  --rp-tr-meta:   0.01em;

  --rp-measure:   67ch;
  --arrow-w:      1.6;
}

/* -----------------------------------------------------------------------------
   0. Base — scoped to .rp-article so this file is safe to load on any page
      without clobbering host chrome (nav/footer) that isn't part of this
      pattern library.
   ----------------------------------------------------------------------------- */

.rp-article,
.rp-article * {
  box-sizing: border-box;
}

.rp-article {
  font-family: var(--font-prose);
  color: var(--ink-soft);
}

.rp-article h1,
.rp-article h2,
.rp-article h3,
.rp-article p,
.rp-article ul,
.rp-article ol,
.rp-article li,
.rp-article figure,
.rp-article blockquote,
.rp-article table,
.rp-article th,
.rp-article td,
.rp-article dl,
.rp-article dd {
  margin: 0;
  padding: 0;
}

.rp-article ul,
.rp-article ol {
  list-style: none;
}

.rp-article img,
.rp-article svg {
  max-width: 100%;
  display: block;
}

.rp-article a {
  color: inherit;
}

/* drawn arrows — see the <defs> sprite in each document head of body.
   Selector is `.rp-article svg.a`, not bare `.a`: rule 0 above sets
   `.rp-article svg { display: block }` at equal-or-higher specificity than a
   plain `.a` class would carry, which was flattening these into their own
   line wherever they follow inline text (e.g. "Link ↗"). Qualifying with
   `.rp-article svg` gives this the specificity edge it needs to win. */
.rp-article svg.a {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: -0.15em;
  flex: none;
  stroke-width: var(--arrow-w, 1.75);
}

.rp-article :focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

/* Visually-hidden but accessible — for labels a sighted reader doesn't need
   but a screen reader / crawler benefits from having explicit. */
.rp-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* -----------------------------------------------------------------------------
   1. Typographic primitives — lifted from statswing-site globals.css.
      Original values preserved; only the token *names* changed
      (--serif/--sans/--narrow -> --font-prose/--font-display/--font-label).
   ----------------------------------------------------------------------------- */

.eyebrow {
  margin: 0;
  color: var(--core);
  font: var(--rp-w-label) var(--rp-t-label) / 1.3 var(--font-label);
  letter-spacing: var(--rp-tr-label);
  text-transform: uppercase;
}

.kicker-index {
  font: var(--rp-w-label) calc(var(--rp-t-label) + 1px) / 1 var(--font-label);
  letter-spacing: var(--rp-tr-label);
  color: var(--core);
}

.t-title-lg {
  margin: 0;
  color: var(--ink);
  font: var(--rp-w-title) var(--rp-t-title) / var(--rp-lh-title) var(--font-display);
  letter-spacing: var(--rp-tr-title);
}

.t-title-md {
  margin: 0;
  color: var(--ink);
  font: var(--rp-w-h2) clamp(1.55rem, 2.5vw, 2.2rem) / 1.1 var(--font-display);
  letter-spacing: var(--rp-tr-h2);
}

.t-title-sm {
  margin: 0;
  color: var(--ink);
  font: var(--rp-w-h3) var(--rp-t-h3) / 1.18 var(--font-display);
  letter-spacing: var(--rp-tr-h3);
}

.t-body-lg {
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--font-prose);
  font-size: var(--rp-t-lede);
  line-height: var(--rp-lh-lede);
  letter-spacing: var(--rp-tr-lede);
}

/* .prose-sw — long-form article body. Wrap raw article markup (headings,
   paragraphs, blockquotes, links, tables) in one .prose-sw container per
   run of continuous body copy; break out of it for figures/boxes/tables
   that need their own rp-* treatment, then re-open a new .prose-sw after. */
.prose-sw {
  max-width: var(--rp-measure);
  color: var(--ink-soft);
  font-family: var(--font-prose);
  font-size: var(--rp-t-body);
  line-height: var(--rp-lh-body);
}
/* NOTE: must be scoped under .rp-article. The scoped reset above sets
   `.rp-article p { margin: 0 }` at specificity (0,1,1); a bare
   `.prose-sw > * + *` is only (0,1,0) and loses regardless of source order,
   which silently collapsed every paragraph gap in the article body. */
.rp-article .prose-sw > * + * {
  margin-top: var(--rp-space-para);
}

/* SPECIFICITY FIX (2026-08-25 audit). These two rules were written as
   `.prose-sw h2` / `.prose-sw h3` — specificity (0,1,1). The generic sibling
   rule immediately above is `.rp-article .prose-sw > * + *` — (0,2,0), which
   WINS. Every h2 that followed a sibling (i.e. all of them but the first) was
   therefore getting margin-top: 1.15em = 32px instead of the intended 2.5em =
   70px, and every h3 was getting 24px instead of 41px. Measured, not guessed:
   a section break was rendering at 1.6× a paragraph gap, so the document had
   no visible section structure at all. Re-scoping under .rp-article takes both
   to (0,2,1) and restores the declared values.

   The h2 also gains the section rule — see §14, "dividers". */
.rp-article .prose-sw h2 {
  margin: var(--rp-space-section) 0 0.5em;
  color: var(--ink);
  font: var(--rp-w-h2) var(--rp-t-h2) / var(--rp-lh-h2) var(--font-display);
  letter-spacing: var(--rp-tr-h2);
}
.rp-article .prose-sw h3 {
  margin: 2.15em 0 0.55em;
  color: var(--ink);
  font: var(--rp-w-h3) var(--rp-t-h3) / var(--rp-lh-h3) var(--font-display);
  letter-spacing: var(--rp-tr-h3);
}
.prose-sw a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: var(--core);
  text-underline-offset: 3px;
}
.prose-sw strong {
  color: var(--ink);
  font-weight: var(--rp-w-strong);
}
.prose-sw em {
  font-style: italic;
}

/* Normalisation: the source left <blockquote> unstyled (it relied on
   Tailwind preflight zeroing UA defaults, then inherited prose-sw's body
   color — so quotes were visually indistinguishable from paragraphs). This
   library gives blockquote real, intentional treatment, matching the
   Quote primitive used elsewhere in the family (border-left in --core). */
/* SPECIFICITY FIX (2026-08-25 audit): (0,1,1) lost to
   `.rp-article .prose-sw > * + *` at (0,2,0), so pull-quotes were sitting on
   the ordinary paragraph interval (21px) instead of the declared 1.5em (28px)
   — the quote read as a paragraph with a stripe. */
.rp-article .prose-sw blockquote {
  margin: 1.6em 0;
  padding-left: 1.25em;
  border-left: 2px solid var(--core);
  color: var(--ink);
}
.prose-sw blockquote p + p {
  margin-top: 0.5em;
}
.prose-sw blockquote footer {
  margin-top: 0.5em;
  color: var(--dim);
  font-size: 13px;
  font-style: normal;
}

/* -----------------------------------------------------------------------------
   2. Layout scaffolding — every section on a research page nests
      .rp-section > .rp-shell > .rp-col. Reuse this chain unmodified; the
      only thing that changes per-section is which tone/space modifiers
      land on .rp-section.
   ----------------------------------------------------------------------------- */

.rp-section {
  padding: 5rem 0; /* space: md (default) */
}
.rp-section--sm {
  padding: 3.5rem 0;
}
.rp-section--panel {
  background: var(--raised);
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
}

.rp-shell {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.rp-col {
  max-width: var(--measure);
  margin-inline: auto;
}

/* An anchor-targeted section (e.g. #addendum, linked from a companion-pointer
   callout or a sibling paper) needs the same landing offset the reference
   list already gives its <li> targets, or a sticky header would occlude the
   heading it jumps to. Generic on [id] so any future in-page anchor inherits
   it for free. */
.rp-section[id] {
  scroll-margin-top: 6rem;
}

@media (max-width: 640px) {
  .rp-section {
    padding: 3rem 0;
  }
  .rp-section--sm {
    padding: 2.25rem 0;
  }
}

/* -----------------------------------------------------------------------------
   3. Hero — the article masthead: eyebrow, h1, lede, byline, epistemic
      status. Lives in a <header>.
   ----------------------------------------------------------------------------- */

.rp-hero {
  position: relative;
  overflow: hidden;
}

/* NEUTRALISED. The source carried a decorative radial wash behind the hero.
   Gradients are out of the institutional register — the site design bans them
   outright, and the whole page argument is that structure comes from rules and
   space, not atmosphere. Kept as an empty hook so the markup does not have to
   change if a hero treatment is ever wanted; it paints nothing today. */
.rp-hero__glow {
  display: none;
}

.rp-hero__inner {
  position: relative;
  z-index: 1;
}

/* SPECIFICITY FIX (2026-08-25 audit). Both .rp-hero__eyebrow and
   .rp-hero__lede are <p> elements, and §0's reset — `.rp-article h1, h2, h3,
   p, … { margin: 0 }` — is (0,1,1) against these rules' (0,1,0). The reset
   WON. Measured on the shipped page: eyebrow→title gap 0px (declared 24px),
   title→lede gap 0px (declared 24px). The founder's complaint that "the dek
   sits tight under the title with no breathing room" was not a design
   judgement — it was this bug. .rp-hero__meta (a <div>) and .rp-hero__status
   (an <aside>) are not in the reset's selector list, which is why those two
   gaps were the only ones that ever rendered.

   Re-scoping under .rp-article takes these to (0,2,0) and they win. The five
   papers that still use .rp-hero get the fix with no markup change. */
.rp-article .rp-hero__eyebrow {
  margin: 0 0 1.75rem;
}

.rp-article .rp-hero__title {
  max-width: var(--rp-mw-title);
}

.rp-article .rp-hero__lede {
  max-width: 60ch;
  margin-top: 1.75rem;
}

.rp-article .rp-hero__meta {
  margin-top: 2rem;
}

.rp-article .rp-hero__status {
  margin-top: 2rem;
}

/* -----------------------------------------------------------------------------
   4. Epistemic status chip — the dated warrant aside under the hero.
   ----------------------------------------------------------------------------- */

.rp-status {
  border-radius: var(--radius);
  padding: 1.25rem;
  /* The core is the WARRANT tone, and the family law is that the warrant colour
     is never a fill — it marks, it does not wash. A 10% accent tint across a
     block this size reads as a pink panel on the cool institutional ground and
     spends the one warm element on a background. The surface goes neutral; the
     status LABELS keep the core, which is where the warrant actually lives. */
  background: var(--sunk);
  border: 1px solid var(--hair-strong);
}

.rp-status__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1.5rem;
  color: var(--core);
  font: var(--rp-w-label) calc(var(--rp-t-label) + 1px) / 1.3 var(--font-label);
  letter-spacing: calc(var(--rp-tr-label) - 0.04em);
  text-transform: uppercase;
}

/* SPECIFICITY FIX: <p>, (0,1,0) vs the reset's (0,1,1). Rendered flush
   against the status row — measured 0px against a declared 8px. */
.rp-article .rp-status__desc {
  margin-top: 0.6rem;
  color: var(--ink-soft);
  font-family: var(--font-prose);
  font-size: var(--rp-t-note);
  line-height: var(--rp-lh-note);
}

/* -----------------------------------------------------------------------------
   5. Article byline (date · authors · reading time).
   ----------------------------------------------------------------------------- */

.rp-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1rem;
  color: var(--dim);
  font-family: var(--font-label);
  font-size: var(--rp-t-meta);
  letter-spacing: var(--rp-tr-meta);
}

.rp-meta__sep {
  opacity: 0.6;
}

/* -----------------------------------------------------------------------------
   6. Figure — diagram/chart + caption + source line.
   ----------------------------------------------------------------------------- */

.rp-figure {
  margin: 2rem 0;
}

.rp-figure__frame {
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--hair);
}

.rp-figure__media {
  background: var(--ground);
  padding: 1rem;
}

.rp-figure figcaption {
  margin-top: 0.85rem;
  color: var(--dim);
  font-family: var(--font-prose);
  font-size: var(--rp-t-note);
  line-height: var(--rp-lh-note);
}

/* Flat chart PNGs (mechanics-poc, possession-adjustment,
   possession-adjustment-reanalysis) — unlike the inline SVGs, a raster
   <img> has its own intrinsic size and won't fill .rp-figure__media on its
   own; base .rp-article img only caps overflow via max-width. Force it to
   the frame's full width, matching how the inline SVGs already behave. */
.rp-figure__media img {
  width: 100%;
  height: auto;
}

/* -----------------------------------------------------------------------------
   7. Table — provider-comparison / data tables inside prose.
   ----------------------------------------------------------------------------- */

.rp-table-wrap {
  overflow-x: auto;
  margin-top: 1.15em;
}

.rp-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--raised);
  font-family: var(--font-prose);
  font-size: var(--rp-t-small);
  line-height: 1.5;
}

.rp-table th,
.rp-table td {
  text-align: left;
  vertical-align: top;
  padding: 10px 12px;
}

/* Column headers (<th scope="col"> in <thead>) get the heavier rule. */
.rp-table thead th {
  border-bottom: 1.5px solid var(--hair-strong);
  color: var(--ink);
  font-weight: 600;
}

/* Body rows — including a <th scope="row"> first cell, when the first
   column is itself a row label (e.g. the provider-name column). */
.rp-table tbody th,
.rp-table tbody td {
  border-bottom: 1px solid var(--hair);
}
.rp-table tbody th[scope="row"] {
  color: var(--ink);
  font-weight: 600;
}
.rp-table tbody td {
  color: var(--ink-soft);
  font-weight: 400;
}

/* -----------------------------------------------------------------------------
   8. Box — the one shared shape for every labelled callout: Key Finding,
      Methodological Note, Data Sources and Reproducibility, Cite This
      Publication. This replaces the source's three separate "Key Finding"
      treatments with a single reusable card. Default surface is --raised;
      modifiers change the surface/emphasis, never the structure.
   ----------------------------------------------------------------------------- */

.rp-box {
  margin-top: 2rem;
  border-radius: var(--radius);
  padding: 1.25rem;
  background: var(--raised);
  border: 1px solid var(--hair);
}
.rp-box + .rp-box {
  margin-top: 1rem;
}

.rp-box--sunk {
  background: var(--sunk);
}

/* Addendum — a full corrective section appended after publication, revising
   or partially superseding the original claim (possession-adjustment's
   #addendum, pointing at its companion reanalysis). Distinct from
   .rp-box--finding: a TOP rule rather than a LEFT rule, because the addendum
   sits chronologically after the article rather than beside a claim within
   it. The core still only marks the edge — the surface stays neutral. */
.rp-box--addendum {
  border-color: var(--hair-strong);
  border-top: 3px solid var(--core);
}

/* Links inside any box (companion-pointer callouts, the addendum, methodology
   notes that cite a sibling paper) — boxes sit outside .prose-sw, so they
   don't inherit .prose-sw a's underline treatment. Same visual rule, scoped
   to .rp-box instead. */
.rp-box a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: var(--core);
  text-underline-offset: 3px;
}

/* Same law as .rp-status: no accent fill. The key finding earns its emphasis
   from a 2px core rule on the leading edge — a mark, not a wash — and from
   its core label. Everything else stays neutral. */
.rp-box--finding {
  background: var(--raised);
  border-color: var(--hair-strong);
  border-left: 2px solid var(--core);
}
.rp-box--finding .rp-box__label {
  color: var(--core);
}

/* SPECIFICITY FIX: the label is an <h2>/<h3>, (0,1,0) vs the reset's (0,1,1).
   Every callout label — Key Finding, Methodological Note, Data Sources, Cite
   This Publication — was sitting flush on its first line of body copy. */
.rp-article .rp-box__label {
  display: block;
  margin-bottom: 0.55rem;
  color: var(--dim); /* .eyebrow's default --core is overridden here; the
                         label reads as a field name, not a live-status
                         chip. Combine as class="eyebrow rp-box__label". */
}

.rp-box p {
  color: var(--ink-soft);
  font-family: var(--font-prose);
  font-size: var(--rp-t-small);
  line-height: 1.65;
}
.rp-box p + p {
  margin-top: 0.75em;
}

/* Dual-attribution citation — the founder-settled "Cite This Publication"
   shape: inganci.com is the citable identifier (full rp-box p treatment
   above); this is the smaller secondary line recording the original
   statswing.com publication underneath it. */
/* the dual-attribution secondary line is a continuation of the citation, not
   a new paragraph, so it overrides `.rp-box p + p`'s interval — which needs
   (0,2,0) to beat that rule's (0,1,1)+source order. */
.rp-article .rp-box__cite-secondary {
  margin-top: 0.5em;
  color: var(--dim);
  font-size: calc(var(--rp-t-small) - 1.5px);
  font-style: italic;
}

/* -----------------------------------------------------------------------------
   9. Implications by audience — the 2-up card grid.
   ----------------------------------------------------------------------------- */

.rp-implications {
  margin-top: 1.5rem;
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}
@media (min-width: 640px) {
  .rp-implications {
    grid-template-columns: repeat(2, 1fr);
  }
}

.rp-implications__card {
  border-radius: var(--radius);
  padding: 1.5rem;
  background: var(--ground);
  border: 1px solid var(--hair);
}

.rp-implications__card p {
  margin-top: 0.6rem;
  color: var(--dim);
  font-family: var(--font-prose);
  font-size: var(--rp-t-small);
  line-height: 1.65;
}

/* Same link treatment as .rp-box a — implications cards sit outside .prose-sw
   too. Needed once (possession-adjustment's "For researchers" card
   cross-references /research/aerials inline) but scoped generically rather
   than one-off, since any card could reasonably cite another paper. */
.rp-implications__card a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: var(--core);
  text-underline-offset: 3px;
}

/* -----------------------------------------------------------------------------
   10. References — ordered list with manual bracket numbering (native <ol>
       markers are suppressed by the base reset above; the visible [N] is
       real text content, not CSS ::before, so it survives copy/paste and
       text-only crawlers).
   ----------------------------------------------------------------------------- */

/* SPECIFICITY FIX: <ol>, (0,1,0) vs the reset's (0,1,1). The reference list
   was flush against the "References" heading. */
.rp-article .rp-refs {
  margin-top: 1.5rem;
  color: var(--dim);
  font-family: var(--font-prose);
  font-size: var(--rp-t-note);
  line-height: var(--rp-lh-note);
}

.rp-refs li {
  display: flex;
  gap: 0.75rem;
  scroll-margin-top: 6rem; /* footnote target offset for a sticky header;
                               see .rp-cite-ref below */
}
.rp-refs li + li {
  margin-top: 0.75rem;
}

.rp-refs__num {
  flex-shrink: 0;
  color: var(--core);
  font-weight: 500;
}

.rp-refs a {
  color: var(--ink);
  text-decoration-line: underline;
  text-decoration-color: color-mix(in srgb, var(--core) 28%, transparent);
  text-underline-offset: 3px;
}

/* -----------------------------------------------------------------------------
   11. Citation link — the ONE normalised in-text citation pattern for every
       paper: <sup><a href="#ref-N" class="rp-cite-ref">[N]</a></sup>.
       Also used, unwrapped by <sup>, for citations inside figure captions.
   ----------------------------------------------------------------------------- */

/* The UA sets <sup> to `font-size: smaller` (~83%), which on an 18px serif
   body renders a 15px superscript — at 600 weight and in the accent, the
   citation marks were competing with the prose rather than annotating it.
   0.7em is the smallest that still reads two digits cleanly at 13px. */
.rp-article sup {
  font-size: 0.7em;
}

.rp-cite-ref {
  color: var(--core);
  font-weight: 600;
  text-decoration: none;
}
.rp-cite-ref:hover,
.rp-cite-ref:focus-visible {
  text-decoration: underline;
}

/* -----------------------------------------------------------------------------
   12. Tags.
   ----------------------------------------------------------------------------- */

.rp-tags {
  margin-top: 2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* SPECIFICITY FIX: <li>, and the reset sets `padding: 0` at (0,1,1) against
   this rule's (0,1,0). The tags were rendering as 0-height-padding pills —
   text touching the top and bottom of its own border. Horizontal padding
   survived only because the shorthand's left/right were re-declared here at
   equal specificity but later source order; the vertical pair lost. */
.rp-article .rp-tag {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius);
  padding: 0.3rem 0.75rem;
  background: var(--raised);
  border: 1px solid var(--hair);
  color: var(--dim);
  font-family: var(--font-label);
  font-size: calc(var(--rp-t-meta) - 1px);
  font-weight: 500;
  letter-spacing: var(--rp-tr-meta);
}

/* -----------------------------------------------------------------------------
   13. Article footer — tags + share/PDF affordance.
   ----------------------------------------------------------------------------- */

.rp-article-footer {
  margin-top: 0; /* .rp-tags and .rp-share carry their own top spacing */
}

.rp-share {
  margin-top: 2rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.rp-pdf-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border-radius: var(--radius);
  padding: 0.5rem 1rem;
  border: 1px solid var(--hair-strong);
  color: var(--ink);
  font-family: var(--font-label);
  font-size: var(--rp-t-meta);
  font-weight: 500;
  letter-spacing: var(--rp-tr-meta);
  text-decoration: none;
}
.rp-pdf-link:hover {
  background: var(--raised);
}
.rp-pdf-link svg {
  flex-shrink: 0;
}

/* the dark stratum re-points the accent — see tokens.css. Blues are dark hues:
   superb on white, ~2.2 on near-black. One rule, so every component that says
   var(--core) keeps saying it and simply works on either ground. */
.is-dark { --core: var(--core-band); }

/* =============================================================================
   14. THE READING FIELD — masthead, three-column reading grid, section index,
       margin references, section dividers.

   Added 2026-08-25. Everything below is ADDITIVE: the five papers that still
   use §3's .rp-hero and a plain .rp-col render exactly as before. Turning a
   paper onto this treatment is markup work only — see the porting note at the
   foot of this file.

   ONE DISCIPLINE, ENFORCED THROUGHOUT THIS SECTION: every rule that touches a
   <p>, <h1>–<h3>, <ol>, <ul>, <li>, <figure> or <blockquote> is scoped under
   .rp-article, because §0's reset zeroes those at specificity (0,1,1) and an
   unscoped single class loses to it. Two shipped bugs in §3 and §1 came from
   exactly that (see the FIX comments there). Do not write a bare `.rp-x`
   margin rule in this file.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   14a. The field geometry.

   The reading field is a centred measure with two EQUAL margins: the left one
   carries the map (section index), the right one carries the apparatus
   (references). Equal, because the masthead rule and the reading column must
   share one centre axis — asymmetric rails would slide the body column off the
   masthead's axis by half their difference, and the page would read as two
   grids that nearly agree.

   The max-width is derived, not declared, so there is exactly one number to
   change: --rp-measure. Because the whole field is capped at
   measure + 2·(rail + gap) and the centre track is 1fr, a viewport narrower
   than that shrinks the TEXT and leaves the rails intact — the sidenotes can
   never push the page into horizontal overflow.
   ----------------------------------------------------------------------------- */

.rp-article {
  --rp-rail-w:   0px;
  --rp-rail-gap: 0px;
}

@media (min-width: 1000px) {
  .rp-article { --rp-rail-w: 158px; --rp-rail-gap: 26px; }
}
@media (min-width: 1200px) {
  .rp-article { --rp-rail-w: 210px; --rp-rail-gap: 36px; }
}

/* The shared width of the masthead rule and the reading grid. font-size is set
   to the prose size on purpose: --rp-measure is in `ch`, and `ch` resolves
   against the element's OWN font-size. Sized at the 16px root it would come out
   ~14% short of the measure the prose actually sets. Every descendant declares
   its own size, so this affects the ch arithmetic and nothing else. */
.rp-field {
  max-width: calc(var(--rp-measure) + 2 * (var(--rp-rail-w) + var(--rp-rail-gap)));
  margin-inline: auto;
  font-size: var(--rp-t-body);
}

/* The end-matter columns (implications, references) still use §2's .rp-col,
   whose max-width is the --measure token resolved at the 16px root. Inside a
   page running the reading field that lands ~45px wider than the reading
   column, and the page visibly steps outwards at the implications panel —
   measured 572px vs 617px at 1440. This modifier re-points those columns at
   the SAME measure the reading field uses, resolved at the same font-size. */
.rp-col--read {
  /* Tracks the reading column exactly at every width. The flow track is
     min(measure, container − both rails); mirroring that here keeps ONE column
     axis down the whole page instead of a step at the implications panel.
     Requires .rp-shell--field on the parent so `100%` is the same container. */
  max-width: min(
    var(--rp-measure),
    calc(100% - 2 * (var(--rp-rail-w) + var(--rp-rail-gap)))
  );
  font-size: var(--rp-t-body);
}

/* The masthead and the reading field share a slightly wider shell than the
   rest of the page. Measured reason: at the 1180 shell the field's derived
   max-width exceeded the container for three of the four pairings, so the
   TEXT track absorbed the shortfall and --rp-measure stopped being the thing
   that set the measure. 1280 puts every pairing under the clamp, which makes
   --rp-measure the single honest control again. Nothing else on the page
   changes width: the implications panel rules are full-bleed and the
   references column is centred, so there is no edge to mis-align. */
.rp-shell--field {
  max-width: 1280px;
}

/* -----------------------------------------------------------------------------
   14b. Masthead — the title page.

   THE CENTRING DECISION, stated so it can be argued with. The house is
   left-aligned everywhere, and this is the one deliberate departure. It is
   confined to the masthead and it stops at the rule.

   The argument: this block is a TITLE PAGE, not the top of an article. Nothing
   in it is read continuously — it is an identifier (category, number), a date,
   a duration and a name-of-the-work. Centring is what a monograph, a journal
   offprint and a museum wall label all do with exactly that content, and it
   marks the block as a different KIND of object from the argument beneath it.

   The rule is the boundary. Above it the page is symmetric and formal; below it
   the page is a reading field — left-aligned, asymmetric in what the two
   margins carry, and continuous. Every multi-line block a reader actually READS
   (dek, epistemic status, key finding, prose) sits below the rule and stays
   left-aligned. So the house law is never broken; it is scoped.

   The byline is gone from here. What survives, and why: the CATEGORY and the
   PUBLICATION NUMBER (this is the institution's identifier for the work — an
   institution publishes, so the masthead carries the institution's stamp, not a
   person's), the DATE (the publication fact), and the READING TIME (reader
   service, a fact about the artefact rather than about its author). The author
   is credited where scholarship credits authors: the citation block.
   ----------------------------------------------------------------------------- */

.rp-mast {
  position: relative;
}

.rp-article .rp-mast__inner {
  padding-top: clamp(3.25rem, 7vw, 6.5rem);
  padding-bottom: clamp(2.5rem, 4.75vw, 4.25rem);
  border-bottom: 1px solid var(--hair-strong);
  text-align: center;
}

.rp-article .rp-mast__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: 0.4rem 0.9rem;
  margin: 0 0 clamp(1.75rem, 3vw, 2.5rem);
  color: var(--dim);
  font-family: var(--font-label);
  font-size: var(--rp-t-label);
  font-weight: var(--rp-w-label);
  letter-spacing: var(--rp-tr-label);
  text-transform: uppercase;
}

/* the category is the one chromatic element in the masthead */
.rp-article .rp-mast__cat { color: var(--core); }
.rp-article .rp-mast__sep { color: var(--mid); font-weight: 400; }

.rp-article .rp-mast__title {
  max-width: var(--rp-mw-title);
  margin-inline: auto;
  color: var(--ink);
  font: var(--rp-w-title) var(--rp-t-title) / var(--rp-lh-title) var(--font-display);
  letter-spacing: var(--rp-tr-title);
  text-wrap: balance;   /* centred titles live or die on the rag */
}

/* -----------------------------------------------------------------------------
   14c. The reading grid.
   ----------------------------------------------------------------------------- */

.rp-read {
  padding-top: var(--rp-space-field);
  padding-bottom: var(--rp-space-field);
}

.rp-read__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.rp-read__flow {
  grid-column: 1 / -1;
  min-width: 0;
}

/* Uniform block rhythm through the article body. Before this the gaps between
   prose / figure / box came from three unrelated declarations (.rp-figure's
   2rem, .rp-box's 2rem, and nothing at all after a figure); one rule now owns
   the interval. (0,2,0) so it beats .rp-figure and .rp-box at (0,1,0). */
.rp-article .rp-read__flow > * + * {
  margin-top: var(--rp-space-block);
}

/* …but a stack of labelled boxes is one object, not three, so it keeps its
   tighter interval. Re-scoped to (0,3,0) so it still wins after the rule
   above. */
.rp-article .rp-box + .rp-box {
  margin-top: 1rem;
}

/* the track already enforces the measure; §1's own cap would double-clamp it
   (and clamp it wrong — see the `ch` note in 14a) */
.rp-article .rp-read__flow .prose-sw {
  max-width: none;
}

@media (min-width: 1000px) {
  .rp-read__grid {
    grid-template-columns: var(--rp-rail-w) minmax(0, 1fr) var(--rp-rail-w);
    column-gap: var(--rp-rail-gap);
  }
  .rp-read__flow { grid-column: 2; }
}

/* -----------------------------------------------------------------------------
   14d. Dek and epistemic status, now inside the reading field.

   Both used to sit in the masthead. The dek is five lines of continuous prose
   and the status note is three more: centring either would have violated the
   house law, and leaving them left-aligned inside a centred masthead would have
   made the masthead read as two conflicting grids. They belong below the rule.
   ----------------------------------------------------------------------------- */

.rp-article .rp-lede {
  max-width: min(52ch, 100%);
  color: var(--ink);
  font-family: var(--font-prose);
  font-size: var(--rp-t-lede);
  font-weight: var(--rp-w-lede);
  line-height: var(--rp-lh-lede);
  letter-spacing: var(--rp-tr-lede);
}

/* -----------------------------------------------------------------------------
   14e. Section dividers.

   The 2026-08-25 audit asked whether dividers are shown. They were not: across
   9,400px of article body the only horizontal rules in the document were the
   two figure frames, the box outlines and the implications panel's two edges.
   Section boundaries were carried by white space alone — and by 32px of it,
   which is 1.6× a paragraph gap.

   Every h2 in the reading flow now opens on a rule. --hair-strong, not --hair:
   the section rule has to out-rank the hairlines already used for box edges and
   table rows, or it reads as another box.
   ----------------------------------------------------------------------------- */

.rp-article .rp-read__flow .prose-sw > h2 {
  padding-top: 0.95em;
  border-top: 1px solid var(--hair-strong);
}

/* end matter gets the same treatment the panel already had: a closing rule */
.rp-article .rp-article-footer {
  margin-top: 2.75rem;
  padding-top: 2rem;
  border-top: 1px solid var(--hair);
}
.rp-article .rp-tags { margin-top: 0; }

/* anchor landing offsets for the index and the sidenote back-links */
.rp-article .rp-read__flow :is(h2, h3)[id] { scroll-margin-top: 2.5rem; }
.rp-article [id^="cite-"] { scroll-margin-top: 6rem; }

/* -----------------------------------------------------------------------------
   14f. Section index — the left rail.

   Hand-authored in the markup, not generated, so it is a working table of
   contents with JavaScript disabled. JS adds exactly one thing: the
   current-section marker. With JS off the rail is a plain, quiet list of
   anchors — inert and harmless, which is the requirement.

   Below 1000px it is display:none rather than reflowed to the top: a nine-item
   contents list stacked above a 12-minute article is furniture, not navigation,
   and the document outline is already reachable from the headings themselves.
   ----------------------------------------------------------------------------- */

.rp-index { display: none; }

@media (min-width: 1000px) {
  .rp-index {
    display: block;
    grid-column: 1;
    position: sticky;
    top: 2.5rem;
    align-self: start;
    max-height: calc(100vh - 5rem);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

.rp-article .rp-index__label {
  margin: 0 0 0.85rem;
  padding-left: 0.75rem;
  color: var(--dim);
  font-family: var(--font-label);
  font-size: var(--rp-t-label);
  font-weight: var(--rp-w-label);
  letter-spacing: var(--rp-tr-label);
  text-transform: uppercase;
}

.rp-article .rp-index__list { counter-reset: rp-idx; }
.rp-article .rp-index__list > li { counter-increment: rp-idx; }

.rp-article .rp-index__end {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--hair);
}

.rp-index a {
  display: block;
  padding: 0.34rem 0 0.34rem 0.75rem;
  border-left: 1px solid var(--hair);
  color: var(--dim);
  font-family: var(--font-label);
  font-size: calc(var(--rp-t-meta) - 0.5px);
  line-height: 1.35;
  letter-spacing: var(--rp-tr-meta);
  text-decoration: none;
  transition: color 120ms linear, border-color 120ms linear;
}

.rp-index__list > li > a::before {
  content: counter(rp-idx, decimal-leading-zero) "\2002";
  color: var(--mid);
  font-variant-numeric: tabular-nums;
}

.rp-index a:hover {
  color: var(--ink);
  border-left-color: var(--hair-strong);
}

/* the current section. A 1px edge in --core and the ink lifted to full
   strength — the accent MARKS, it never washes. */
.rp-index a[aria-current="true"] {
  color: var(--ink);
  border-left-color: var(--core);
}
.rp-index a[aria-current="true"]::before { color: var(--core); }

/* -----------------------------------------------------------------------------
   14g. Margin references — the right rail.

   MECHANISM, and what depends on what:

     · POSITIONING IS PURE CSS. Each note is a `float: right` with a negative
       right margin equal to (rail + gap). A right float is laid out at the top
       of the line box in which it is declared, which is exactly "top-aligned to
       its reference"; the negative margin collapses its margin box to zero
       effective width, so the line boxes of the paragraph are NOT shortened and
       the text runs full measure past it. `clear: right` stacks consecutive
       notes down the rail instead of over one another — several paragraphs here
       carry two or three. No script computes a single coordinate.

     · JS SUPPLIES CONTENT ONLY. The note text is cloned from the #ref-N entry
       at the foot, so there is one source of truth for every citation and
       nothing to keep in sync. Duplicating fourteen citations into the prose as
       markup would have been the alternative; it would also have to be done
       fourteen more times per paper, by hand, for five more papers.

     · WITH JAVASCRIPT OFF the page is exactly what it is today: a superscript
       [N] linking to the reference list, which is a readable inline reference
       and the required degradation. Nothing is orphaned; nothing moves.

   The injected note is aria-hidden. It is a verbatim duplicate of content the
   superscript already links to, and a screen reader should not read every
   citation twice. For the same reason it contains no focusable element — the
   real affordance stays on the <sup>.
   ----------------------------------------------------------------------------- */

.rp-note { display: none; }

@media (min-width: 1000px) {
  .rp-note {
    display: block;
    float: right;
    clear: right;
    width: var(--rp-rail-w);
    margin-right: calc(-1 * (var(--rp-rail-w) + var(--rp-rail-gap)));
    margin-top: 0.4em;
    margin-bottom: 1.35em;
    color: var(--dim);
    font-family: var(--font-prose);
    font-size: var(--rp-t-note);
    font-style: normal;
    font-weight: 400;
    line-height: var(--rp-lh-note);
    letter-spacing: normal;
    text-align: left;
    text-indent: 0;
  }
}

.rp-article .rp-note__num {
  margin-right: 0.35em;
  color: var(--core);
  font-family: var(--font-label);
  font-size: 0.94em;
  font-weight: 600;
  letter-spacing: var(--rp-tr-meta);
}

/* the narrow collapse: notes leave the paragraph and become a small block
   immediately after it, set off by a rule. Built and unbuilt by the same
   matchMedia listener, so nothing is left in the DOM at desktop widths. */
.rp-article .rp-notes {
  margin-top: 1.15em;
  padding-left: 0.9rem;
  border-left: 1px solid var(--hair-strong);
  color: var(--dim);
  font-family: var(--font-prose);
  font-size: var(--rp-t-note);
  line-height: var(--rp-lh-note);
}
.rp-article .rp-notes .rp-note {
  display: block;
  float: none;
  clear: none;
  width: auto;
  margin: 0;
}
.rp-article .rp-notes .rp-note + .rp-note { margin-top: 0.7em; }

/* landing state for a citation jump, and the back-link home. Both exist so the
   NARROW round trip is complete: tap [7] → the entry highlights → ↩ returns you
   to the sentence you left. */
.rp-article .rp-refs li:target {
  background: var(--sunk);
  outline: 6px solid var(--sunk);
  color: var(--ink-soft);
}

.rp-article .rp-refs__back {
  margin-left: 0.4em;
  color: var(--core);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.rp-article .rp-refs__back:hover { text-decoration: underline; }

/* -----------------------------------------------------------------------------
   14h. Type switcher — a review tool. THIS DOES NOT SHIP.

   Same idiom as the site mockup: [data-type] on <html>, an allow-list with a
   sane fallback, the choice held in localStorage. Set in the system UI face and
   never inheriting --font-label, so switching pairings does not make the
   control itself jump. Marked [data-review] so it greps out in one pass.
   ----------------------------------------------------------------------------- */

.rp-typeswitch {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 50;
  max-width: calc(100vw - 32px);
  background: var(--raised);
  border: 1px solid var(--hair-strong);
  border-radius: var(--radius);
  font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
  opacity: 0.72;
  transition: opacity 120ms linear;
}
.rp-typeswitch:hover,
.rp-typeswitch:focus-within { opacity: 1; }

.rp-article .rp-typeswitch__label,
.rp-typeswitch__label {
  margin: 0;
  padding: 6px 10px 5px;
  border-bottom: 1px solid var(--hair);
  color: var(--dim);
  font-family: inherit;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.18em;
  line-height: 1;
  text-transform: uppercase;
}

.rp-typeswitch__set { display: flex; flex-wrap: wrap; }

.rp-typeswitch button {
  appearance: none;
  margin: 0;
  padding: 8px 10px;
  border: 0;
  border-right: 1px solid var(--hair);
  background: transparent;
  color: var(--dim);
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.rp-typeswitch button:last-child { border-right: 0; }
.rp-typeswitch button:hover { color: var(--ink); background: var(--sunk); }
.rp-typeswitch button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--raised);
}

/* -----------------------------------------------------------------------------
   14i. Motion and print.
   ----------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .rp-index a,
  .rp-typeswitch {
    transition: none;
  }
}

@media print {
  .rp-typeswitch { display: none; }
  .rp-index { display: none; }
  .rp-note { display: none; }
  .rp-read__grid { display: block; }
}

/* =============================================================================
   PORTING THE READING FIELD TO THE OTHER FIVE PAPERS

   No CSS changes. Per paper, in the HTML only:

     1. <html data-type="record"> and swap the Google Fonts <link> for the
        four-pairing one (or drop both and keep Archivo — the :root dial in §0b
        is Archivo's, so an unattributed paper is unchanged).
     2. Replace the .rp-hero block with the .rp-mast block: keep the eyebrow's
        two facts as .rp-mast__cat / the publication number, keep <time>, keep
        the reading time, DELETE the author <span>. Wrap in
        .rp-mast > .rp-shell > .rp-mast__inner.rp-field.
     3. Move the lede <p> and the .rp-status <aside> out of the masthead and
        into the top of the reading flow; the lede takes class .rp-lede.
     4. Wrap the article-body section's contents in
        .rp-read > .rp-shell > .rp-read__grid.rp-field > .rp-read__flow, and
        put the hand-authored <nav class="rp-index"> ahead of the flow.
     5. Add an id to every h2 in the flow and list them in the index.
     6. Paste the two <script> blocks (head: type pre-paint; foot: sidenotes,
        index spy, switcher) verbatim — they are generic over .rp-cite-ref,
        #ref-N and .rp-index and contain nothing paper-specific.

   The sidenote script needs NO per-citation markup: it reads href="#ref-N" off
   the existing .rp-cite-ref links, which every paper already uses.
   ============================================================================= */
