/* Research Instrument — foundations and tokens for the three-practice site.

   Status: source-owned, tested, and NOT yet wired to any public page. No
   document in the staged release links this sheet, and it is absent from
   release/public-release-policy.json includedAdditions, so it cannot deploy.
   The design lab under /design-lab/ is its only consumer today. When the
   homepage and practice pages are rebuilt they consume this file rather than
   restating any value in it.

   Every rule is scoped below .research-instrument. That is what makes it safe
   to ship the file into /assets/ next to three sheets that already own the
   current site: nothing here can reach a page that has not opted in.

   Three principles the tests hold to:

   1. One place decides a colour. Every colour below resolves to one of the
      nine tokens in the palette block. A hex literal anywhere else is a tenth
      colour the first time someone edits the ninth.
   2. Contrast is measured, not assumed, on BOTH surfaces (paper and
      paper-deep), because a signal that only clears the floor on the lighter
      one fails the moment it lands in an inset panel.
   3. Nothing animates outside prefers-reduced-motion: no-preference, so the
      reduced-motion pass finds the final state already on screen. */

/* The QUESTION face, self-hosted.

   One file, one declaration. It is the variable Newsreader, latin subset, so
   every weight and every optical size the site uses comes out of 129KB rather
   than out of four static cuts, and no page ever asks a third party for a
   font. Provenance, licence, digest and upstream are recorded in
   release/fonts.json and checked against these bytes by
   tests/self-hosted-fonts.test.mjs.

   font-display: swap because the fallback here is Georgia, which is a real
   serif on every machine that has it: showing the headline immediately in a
   near-enough face beats showing nothing while 129KB arrives. The two faces
   are close enough in width that the reflow is a nudge rather than a jump.

   Optical sizing is left to the browser. That axis is the reason to carry a
   variable font at all: the 54px headline gets the display cut and the 13px
   folio gets the text cut, from the same file, without a second request. */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/assets/fonts/newsreader-variable.woff2") format("woff2");
}

/* The other two roles, declared here as well.

   They were already self-hosted, by assets/pattern-shell.css, and it would
   have been tempting to leave them there. That would have been a page on one
   design system quietly depending on another design system's stylesheet for
   two of its three faces, and the first page to drop the shell would have
   rendered its whole body in the system sans with nothing failing anywhere.
   It is precisely what happened on the first build of this homepage: every
   word of EVIDENCE and SOURCE was a substitute, and the page still looked
   plausible.

   Both sheets may declare the same face against the same file. A duplicate
   @font-face for an identical source is one download and one entry in the
   font set, and the alternative is a cross-sheet dependency nothing states. */
@font-face {
  font-family: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/atkinson-400.woff2") format("woff2");
}

@font-face {
  font-family: "Atkinson Hyperlegible";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/atkinson-700.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/plex-mono-400.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/plex-mono-600.woff2") format("woff2");
}

.research-instrument {
  /* ---------------------------------------------------------------- */
  /* Palette. Nine colours, and nothing else.                          */
  /* ---------------------------------------------------------------- */
  /* Identity DNA is preserved from the current off-white / dark-ink /
     copper / teal site, but rebuilt: the neutral warms, the ink loses its
     blue cast, and a third practice signal joins. Ratios below are measured
     by tests/research-instrument-foundations.test.mjs, which recomputes
     them from these declarations rather than trusting this comment. */
  --ri-paper: #F3F0E9;
  --ri-paper-deep: #E6E1D7;
  --ri-ink: #1D1420;          /* 15.73:1 paper, 13.74:1 paper-deep */
  --ri-graphite: #68616A;     /*  5.26:1 paper,  4.60:1 paper-deep */
  --ri-rule: #C8C1B7;         /* linework only, never text          */

  /* Practice signals. Health and systems clear the 4.5:1 text floor on both
     surfaces and so serve as one value each. Business does not: copper at
     the weight the diagrams need is 3.76:1, which is a legitimate non-text
     mark and an illegal body colour. So business, and only business, is two
     tokens. This is the honest fix; darkening the mark to clear 4.5:1 would
     have flattened it into the ink and cost the practice its signal. */
  --ri-business-mark: #B5662D;  /* 3.76:1 paper, 3.29:1 deep — marks only */
  --ri-business-text: #8A4D0B;  /* 5.86:1 paper, 5.12:1 deep — text/links */
  --ri-health: #0B6D68;         /* 5.42:1 paper, 4.74:1 deep */
  --ri-systems: #504C9B;        /* 6.48:1 paper, 5.66:1 deep */

  /* ---------------------------------------------------------------- */
  /* Type. Three roles, because the research process has three voices.  */
  /* ---------------------------------------------------------------- */
  /* QUESTION is the editorial serif: it asks. EVIDENCE is the humanist
     sans: it reads. SOURCE is the mono: it cites. No face is used outside
     its role, which is what stops the display face becoming decoration.

     All three are self-hosted and none is fetched from a remote origin.
     Atkinson and Plex Mono were already self-hosted by the shell; Newsreader
     is declared above, in this file, because this sheet is the only consumer
     of the question role and a face declared where it is used cannot be
     orphaned by deleting the sheet that uses it. */
  --ri-question: "Newsreader", Georgia, "Times New Roman", serif;
  --ri-evidence: "Atkinson Hyperlegible", "Aptos", "Segoe UI", system-ui, sans-serif;
  --ri-source: "IBM Plex Mono", "SFMono-Regular", Menlo, Consolas, monospace;

  /* Fluid with real maximums. Body reaches 20px on a wide screen and never
     drops below 17px on a handset; metadata never goes below 12px. The H1
     stops at 54px, which is a headline rather than a viewport. */
  --ri-type-meta: clamp(12px, 0.7rem + 0.12vw, 13px);
  --ri-type-meta-line: 1.45;
  --ri-type-body: clamp(17px, 1rem + 0.28vw, 20px);
  --ri-type-body-line: 1.65;
  --ri-type-lead: clamp(19px, 1.08rem + 0.32vw, 22px);
  --ri-type-lead-line: 1.55;
  --ri-type-h3: clamp(20px, 1.15rem + 0.4vw, 24px);
  --ri-type-h2: clamp(26px, 1.35rem + 1.15vw, 36px);
  --ri-type-h1: clamp(34px, 1.9rem + 2.1vw, 54px);
  --ri-type-h1-line: 1.1;
  --ri-measure: 60ch;   /* a calmer column; still inside 55 to 72 */
  --ri-measure-narrow: 46ch;

  /* ---------------------------------------------------------------- */
  /* Grid and space. One 8px baseline, one frame, three column counts.  */
  /* ---------------------------------------------------------------- */
  --ri-frame: 1440px;
  --ri-gutter: clamp(20px, 4vw, 72px);
  --ri-gap: clamp(16px, 1.4vw, 24px);
  --ri-columns: 4;
  --ri-space-1: 8px;
  --ri-space-2: 16px;
  --ri-space-3: 24px;
  --ri-space-4: 40px;
  --ri-space-5: 64px;
  --ri-space-6: 96px;
  --ri-space-7: 144px;
  --ri-hairline: 1px;
  --ri-target: 44px;   /* the practical minimum for anything you can press */

  /* ---------------------------------------------------------------- */
  /* Motion. Two durations, because there are two kinds of change.      */
  /* ---------------------------------------------------------------- */
  --ri-motion-ui: 200ms;        /* small interface transitions   */
  --ri-motion-diagram: 480ms;   /* a diagram reorganising itself */
  --ri-ease: cubic-bezier(0.2, 0, 0, 1);

  /* Light scheme is the product. Without this, a device in dark mode
     restyles native form controls against the paper surface and the
     enquiry fields read as a second, unowned palette. */
  color-scheme: light;
  background: var(--ri-paper);
  color: var(--ri-ink);
  font-family: var(--ri-evidence);
  font-size: var(--ri-type-body);
  line-height: var(--ri-type-body-line);
  -webkit-font-smoothing: antialiased;
  /* Reflow, not shrinking. At 200% zoom on a 320px handset the layout
     viewport is 160px and a column inside two levels of padding is about
     50px wide, which is narrower than "counterparty" set at 20px. Without
     this, that one word pushes the whole document sideways and every
     paragraph on the page becomes a horizontal scroll.

     break-word rather than anywhere: it breaks a word only when the word
     alone cannot fit, so ordinary line breaking at every normal width is
     completely unchanged. */
  overflow-wrap: break-word;
}

.research-instrument *,
.research-instrument *::before,
.research-instrument *::after { box-sizing: border-box; }

/* Tablet and desktop change the column count and nothing else. A band that
   also restates the frame or the gutter is a second layout system. */
@media (min-width: 48rem) {
  .research-instrument { --ri-columns: 6; }
}

@media (min-width: 64rem) {
  .research-instrument { --ri-columns: 12; }
}

/* ================================================================== */
/* Practice scoping                                                    */
/* ================================================================== */
/* A practice sets two variables and inherits everything else. This is why
   the navigation does not become a rainbow: the signal is resolved once,
   here, and consumed by rules, markers and links rather than by surfaces. */

.research-instrument [data-ri-practice="business"] {
  --ri-signal: var(--ri-business-mark);
  --ri-signal-text: var(--ri-business-text);
}

.research-instrument [data-ri-practice="health"] {
  --ri-signal: var(--ri-health);
  --ri-signal-text: var(--ri-health);
}

.research-instrument [data-ri-practice="systems"] {
  --ri-signal: var(--ri-systems);
  --ri-signal-text: var(--ri-systems);
}

/* ================================================================== */
/* Foundation primitives                                               */
/* ================================================================== */

.research-instrument .ri-frame {
  width: 100%;
  max-width: var(--ri-frame);
  margin-inline: auto;
  padding-inline: var(--ri-gutter);
}

.research-instrument .ri-grid {
  display: grid;
  grid-template-columns: repeat(var(--ri-columns), minmax(0, 1fr));
  gap: var(--ri-gap);
}

/* Full width unless a consumer says otherwise, and this default is the whole
   reason mobile is designed rather than collapsed. Without it, a child that
   only declares its span inside a desktop media query gets one of the four
   handset columns: the hero rendered as a 70px ribbon of broken words with
   the H1 wrapping one syllable per line. Opting in to a span is a deliberate
   act at one breakpoint; opting out of being shredded should not have to be.
   A consumer that genuinely wants auto placement says so with grid-column:
   auto, which is one declaration and is visible where it happens. */
.research-instrument .ri-grid > * {
  grid-column: 1 / -1;
  min-width: 0;
}

.research-instrument .ri-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ri-space-2);
  min-width: 0;
  max-width: 100%;
}

.research-instrument .ri-rule {
  border: 0;
  border-top: var(--ri-hairline) solid var(--ri-rule);
  margin: 0;
}

/* Type roles as classes, so a document never picks a face by hand. */

.research-instrument .ri-question {
  font-family: var(--ri-question);
  font-weight: 400;
  font-size: var(--ri-type-h1);
  line-height: var(--ri-type-h1-line);
  letter-spacing: -0.015em;
  max-width: 18ch;
  margin: 0;
  hyphens: none;
  -webkit-hyphens: none;
}

.research-instrument .ri-heading {
  font-family: var(--ri-question);
  font-weight: 400;
  font-size: var(--ri-type-h2);
  line-height: 1.22;
  max-width: 22ch;
  margin: 0;
  hyphens: none;
  -webkit-hyphens: none;
}

.research-instrument .ri-subheading {
  font-family: var(--ri-evidence);
  font-weight: 700;
  font-size: var(--ri-type-h3);
  line-height: 1.3;
  margin: 0;
}

.research-instrument .ri-lead {
  font-size: var(--ri-type-lead);
  line-height: var(--ri-type-lead-line);
  max-width: var(--ri-measure);
  margin: 0;
}

.research-instrument .ri-body {
  font-size: var(--ri-type-body);
  line-height: var(--ri-type-body-line);
  max-width: var(--ri-measure);
  margin: 0;
}

/* Metadata is mono because it is a record, not because small-caps look
   technical. Tracking stays modest: 0.08em is legible at 12px, 0.2em is a
   decoration that costs the reader a word. */
.research-instrument .ri-source {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.06em;
  color: var(--ri-graphite);
  margin: 0;
}

.research-instrument .ri-source--label {
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

/* Rhythm, and it has to be declared AFTER the type roles rather than up with
   the other layout primitives. Every role above sets `margin: 0` at the same
   specificity as this selector, so when .ri-stack came first the later rule
   won and a stack of a lede plus two paragraphs rendered with no space
   between them at all. Later wins; that is the whole reason for the
   position. */
.research-instrument .ri-stack > * + * { margin-top: var(--ri-space-3); }

/* Links and actions. */

.research-instrument .ri-link {
  color: var(--ri-signal-text, var(--ri-ink));
  text-decoration: underline;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}

/* A link that is its own paragraph is a control, not a word in a sentence,
   and the viewport sweep found three of them at 21px tall. WCAG 2.2's inline
   exception covers the ones inside prose and does not cover these, so the
   standalone case gets the same 44px floor as a button. Kept as a modifier
   rather than applied to .ri-link, because padding every inline citation link
   to 44px would open the line spacing of every article body on the site. */
.research-instrument .ri-link--standalone {
  display: inline-flex;
  align-items: center;
  min-height: var(--ri-target);
}

.research-instrument .ri-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--ri-target);
  padding: var(--ri-space-1) var(--ri-space-3);
  font-family: var(--ri-evidence);
  font-size: var(--ri-type-body);
  font-weight: 700;
  text-decoration: none;
  border: var(--ri-hairline) solid var(--ri-ink);
  background: var(--ri-ink);
  color: var(--ri-paper);
}

.research-instrument .ri-action--secondary {
  background: transparent;
  color: var(--ri-ink);
  border-color: var(--ri-rule);
  font-weight: 400;
}

.research-instrument :focus-visible {
  outline: 2px solid var(--ri-ink);
  outline-offset: 3px;
}

/* ================================================================== */
/* Research primitives: the inquiry spine and its states               */
/* ================================================================== */
/* The spine is a list. That is the whole trick, and it is why the site is
   still comprehensible with CSS off, with JavaScript off and to a screen
   reader: question, then evidence, then a counterpoint, then a decision, in
   source order, each one carrying its own written state. */

.research-instrument .ri-spine {
  list-style: none;
  margin: 0;
  padding: 0 0 0 var(--ri-space-4);
  border-left: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-spine > li {
  position: relative;
  padding-block: var(--ri-space-2);
}

.research-instrument .ri-spine > li + li {
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

/* The marker is drawn from the practice signal and sits on the spine. It is
   decoration: the state it accompanies is always written out beside it. */
.research-instrument .ri-spine > li::before {
  content: "";
  position: absolute;
  left: calc((var(--ri-space-4) / -1) - 4px);
  top: calc(var(--ri-space-2) + 0.55em);
  width: 9px;
  height: 9px;
  background: var(--ri-signal, var(--ri-graphite));
}

.research-instrument .ri-spine > li[data-ri-node="question"]::before {
  background: var(--ri-ink);
}

/* A counterpoint is the one node drawn as an outline rather than a fill:
   shape carries it, so it survives greyscale and colour blindness. */
.research-instrument .ri-spine > li[data-ri-node="counterpoint"]::before {
  background: var(--ri-paper);
  border: 2px solid var(--ri-ink);
}

.research-instrument .ri-spine > li[data-ri-node="decision"]::before {
  width: 9px;
  height: 9px;
  background: var(--ri-ink);
  border-radius: 50%;
}

/* Evidence, verification and permission states. Never colour alone: every
   state prints its own name, and the tests check that the name is present in
   the markup rather than supplied by a stylesheet. */

/* inline-block rather than inline-flex. As a flex container its text became
   an anonymous flex item with min-width: auto, so "Mechanistically
   plausible" refused to break and carried a 143px box into a 120px column at
   200% zoom. There is nothing to lay out in a row here anyway: the chip is
   one label, and a label should wrap like a label. */
.research-instrument .ri-state {
  display: inline-block;
  /* anywhere, not break-word. A shrink-to-fit box is sized from its
     min-content width, and overflow-wrap: break-word does not reduce
     min-content: it only breaks after the box has already been made too
     wide. So the chip kept sizing itself to "Mechanistically" and overflowed
     its column at 200% zoom even with the inherited break-word in force.
     anywhere is what actually shortens min-content, and it is scoped to the
     chip, where breaking a long state name at extreme zoom is the correct
     outcome and reading it sideways is not. */
  overflow-wrap: anywhere;
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ri-ink);
  padding: 2px var(--ri-space-1);
  border: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-state[data-ri-state="established"],
.research-instrument .ri-state[data-ri-state="verified"],
.research-instrument .ri-state[data-ri-state="local"],
.research-instrument .ri-state[data-ri-state="controlled"] {
  border-color: var(--ri-health);
  border-left-width: 4px;
}

.research-instrument .ri-state[data-ri-state="plausible"],
.research-instrument .ri-state[data-ri-state="claimed"],
.research-instrument .ri-state[data-ri-state="selected"],
.research-instrument .ri-state[data-ri-state="read-only"] {
  border-color: var(--ri-business-mark);
  border-left-width: 4px;
}

.research-instrument .ri-state[data-ri-state="preliminary"],
.research-instrument .ri-state[data-ri-state="inferred"],
.research-instrument .ri-state[data-ri-state="approval-required"] {
  border-color: var(--ri-systems);
  border-left-width: 4px;
  border-left-style: dashed;
}

.research-instrument .ri-state[data-ri-state="anecdotal"],
.research-instrument .ri-state[data-ri-state="unknown"],
.research-instrument .ri-state[data-ri-state="off-by-default"],
.research-instrument .ri-state[data-ri-state="no-access"] {
  border-color: var(--ri-graphite);
  border-left-width: 4px;
  border-left-style: dotted;
  color: var(--ri-graphite);
}

/* The source margin. On a wide screen a source sits in the rail beside the
   sentence it supports; below that it becomes an inline note in flow. Both
   are the same element and the same text, so nothing is hover-only and
   nothing is lost on a handset. */

.research-instrument .ri-source-margin {
  display: block;
  margin-top: var(--ri-space-2);
  padding-left: var(--ri-space-2);
  border-left: 2px solid var(--ri-signal, var(--ri-rule));
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
  max-width: var(--ri-measure-narrow);
}

/* The Working Margin is an annotation in the reading order. It is a short
   horizontal note above the content on a handset, then a narrow rail beside
   it on a wide screen. The rail is grid placement, not an overlay, so the
   annotation remains visible when a reader zooms or disables motion. */
.research-instrument .ri-working-margin {
  display: block;
  margin-block: var(--ri-space-3);
  padding-block-start: var(--ri-space-2);
  border-block-start: var(--ri-hairline) solid var(--ri-signal, var(--ri-rule));
}

.research-instrument .ri-working-margin__label {
  color: var(--ri-signal-text, var(--ri-ink));
}

.research-instrument .ri-working-margin > .ri-body {
  margin-top: var(--ri-space-1);
  max-width: var(--ri-measure-narrow);
}

@media (min-width: 64rem) {
  .research-instrument .ri-working-margin {
    grid-column: 2;
    align-self: start;
    margin-block: 0;
    padding-block-start: 0;
    padding-inline-start: var(--ri-space-2);
    border-block-start: 0;
    border-inline-start: var(--ri-hairline) solid var(--ri-signal, var(--ri-rule));
  }
}

/* A dark editorial band is a surface change, not a second palette.
   Child inversion lives on descendants, not on this rule: a test holds
   that the band itself may only name ink and paper. */
.research-instrument .ri-editorial-band {
  padding-block: var(--ri-space-6);
  background: var(--ri-ink);
  color: var(--ri-paper);
  --ri-signal-text: var(--ri-paper);
}

/* Graphite on ink fails. Source labels, situation lines and the
   working-margin copy inherit paper so the band does not need a
   per-element inline colour. */
.research-instrument .ri-editorial-band .ri-source,
.research-instrument .ri-editorial-band .ri-hero__practice,
.research-instrument .ri-editorial-band .ri-hero__practice-situation {
  color: var(--ri-paper);
}

.research-instrument .ri-editorial-band .ri-action {
  background: var(--ri-paper);
  color: var(--ri-ink);
  border-color: var(--ri-paper);
}

.research-instrument .ri-editorial-band .ri-action--secondary {
  background: transparent;
  color: var(--ri-paper);
  border-color: var(--ri-paper);
}

/* Home wraps the band in .ri-hero; Arabic wraps the hero in the band.
   Either way the two paddings stacked, so the first screen opened with
   more empty ink than argument. */
.research-instrument .ri-hero:has(> .ri-editorial-band) {
  padding-block: 0;
}

.research-instrument .ri-editorial-band > .ri-hero,
.research-instrument .ri-editorial-band > .ri-section {
  padding-block: 0;
}

@media (min-width: 64rem) {
  .research-instrument .ri-annotated {
    display: grid;
    grid-template-columns: minmax(0, var(--ri-measure)) minmax(0, 22ch);
    gap: var(--ri-gap);
    align-items: start;
  }

  .research-instrument .ri-annotated .ri-source-margin {
    margin-top: 0;
    grid-column: 2;
  }
}

/* An inset panel is the paper-deep surface. It is a surface change and a
   hairline, never a card with a shadow and a radius. */
.research-instrument .ri-panel {
  background: var(--ri-paper-deep);
  border: var(--ri-hairline) solid var(--ri-rule);
  padding: var(--ri-space-3);
}

/* A panel may be an optional <details>. Its summary is a real control, so it
   receives the same 44px floor as every other action even when the source
   label itself is only one line high. */
/* The current destination is written into the shell, so the sheet shows
   it: a hairline underline in the ink the label already uses. */
.research-instrument .ri-nav__link[aria-current] {
  text-decoration: underline;
  text-underline-offset: 6px;
  text-decoration-thickness: 1px;
}

.research-instrument .ri-panel > summary {
  display: flex;
  align-items: center;
  gap: var(--ri-space-1);
  min-height: var(--ri-target);
  cursor: pointer;
  list-style: none;
  /* anywhere, not the sheet's usual break-word.
     This label is tracked uppercase, and letter-spacing is added after the
     last glyph of a line as well as between glyphs, so a line that exactly
     fits still ends about 3px wider than the space it was measured into. On
     /private-ai/ at 200% zoom on a 320px handset — a 160px layout viewport —
     that was the whole page scrolling sideways by 3px. break-word does not
     help, because it only breaks a word that cannot fit alone and every word
     here fits; anywhere also lowers the min-content width, which is the
     measurement that was wrong. Scoped to this one control, so no reading
     passage acquires mid-word breaks. */
  overflow-wrap: anywhere;
}

/* A collapsed panel that shows no control reads as an empty card, so the
   sheet draws the disclosure state itself: a mono plus that becomes a
   minus, and a visible keyboard focus. */
.research-instrument .ri-panel > summary::-webkit-details-marker { display: none; }

.research-instrument .ri-panel > summary::before {
  content: "+";
  font-family: var(--ri-source);
  font-size: var(--ri-type-body);
  line-height: 1;
  color: var(--ri-graphite);
}

.research-instrument .ri-panel[open] > summary::before { content: "\2212"; }

.research-instrument .ri-panel > summary:hover { text-decoration: underline; }

.research-instrument .ri-panel > summary:focus-visible {
  outline: 2px solid var(--ri-ink);
  outline-offset: -2px;
}

/* ================================================================== */
/* Motion                                                              */
/* ================================================================== */
/* Everything that moves lives inside this query and nowhere else. With
   reduced motion requested, the selectors below never match, so the final
   state is what renders on first paint. */

@media (prefers-reduced-motion: no-preference) {
  .research-instrument .ri-action,
  .research-instrument .ri-link,
  .research-instrument .ri-state {
    transition: color var(--ri-motion-ui) var(--ri-ease),
                background-color var(--ri-motion-ui) var(--ri-ease),
                border-color var(--ri-motion-ui) var(--ri-ease);
  }

  .research-instrument .ri-spine > li {
    transition: border-color var(--ri-motion-diagram) var(--ri-ease);
  }
}

/* ================================================================== */
/* Site chrome: skip link, header, navigation, mobile sheet, footer     */
/* ================================================================== */
/* One header for the whole site. It is a bar, not a hero: the wordmark
   and the positioning line on the left, the six direct routes on the
   right, and a single hairline underneath that becomes the first rule of
   the page. Nothing here is sticky. A fixed bar on a 667px handset spends
   14% of the reading area announcing where you already are. */

.research-instrument .ri-skip {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  min-height: var(--ri-target);
  padding: 0 var(--ri-space-3);
  background: var(--ri-ink);
  color: var(--ri-paper);
  text-decoration: none;
}

.research-instrument .ri-skip:focus,
.research-instrument .ri-skip:focus-visible {
  inset-inline-start: var(--ri-space-1);
  top: var(--ri-space-1);
}

.research-instrument .ri-header { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

/* Wraps, and the wordmark is allowed to shrink.

   A flex item's default min-width is auto, which is its min-content width,
   and the positioning line under the name is a long string of long words. At
   200% zoom on a 320px handset the layout viewport is 160px, the wordmark
   refused to go below about 110px, the menu control was pushed to a right
   edge of 201px and the whole page scrolled sideways by 49px. Wrapping is
   the correct reflow at that size: the control goes under the name rather
   than off the screen. WCAG 2.2 reflow is the requirement, and it is met by
   reflowing rather than by shrinking type. */
.research-instrument .ri-header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ri-space-2) var(--ri-space-3);
  padding-block: var(--ri-space-3);
}

/* The wordmark takes the slack and the control keeps its size. Without this
   the positioning line refused to wrap, the control was pushed onto a second
   row of its own and sat under the name looking like a mistake rather than a
   decision. */
.research-instrument .ri-header__inner > .ri-wordmark { flex: 1 1 12rem; min-width: 0; }
.research-instrument .ri-header__inner > .ri-menu { flex: 0 0 auto; }

/* The wordmark is two lines and both of them work. The name is the name;
   the line beneath it is the whole positioning statement, set in the source
   face at label size, so a reader who never scrolls still learns what this
   office is. A logo would have said less in the same space. */
.research-instrument .ri-wordmark {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  min-height: var(--ri-target);
  justify-content: center;
  text-decoration: none;
  color: var(--ri-ink);
}

.research-instrument .ri-wordmark__name {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.research-instrument .ri-wordmark__line {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

/* The menu is a <details>. That is a deliberate engineering choice and not
   a shortcut: it gives the disclosure a real name, a real expanded state, a
   real keyboard contract and a real close, in every browser, with no
   JavaScript on the page at all. A hand-rolled button plus a class toggle
   would have needed a script, and a script would have needed the whole
   no-JS story rewriting for the one control that must work when everything
   else fails. */
.research-instrument .ri-menu { position: relative; }

.research-instrument .ri-menu__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--ri-space-1);
  min-height: var(--ri-target);
  padding: 0 var(--ri-space-2);
  border: var(--ri-hairline) solid var(--ri-ink);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  list-style: none;
}

.research-instrument .ri-menu__toggle::-webkit-details-marker { display: none; }

/* Open and closed say different words, because "Menu" on an open sheet is
   the label of the thing you are already looking at rather than of the
   action available to you. */
.research-instrument .ri-menu__toggle .ri-menu__close { display: none; }
.research-instrument .ri-menu[open] .ri-menu__toggle .ri-menu__open { display: none; }
.research-instrument .ri-menu[open] .ri-menu__toggle .ri-menu__close { display: inline; }

.research-instrument .ri-menu[open] .ri-menu__toggle {
  background: var(--ri-ink);
  color: var(--ri-paper);
}

/* No backdrop. A scrim would make this panel look modal, and a modal that
   Escape does not close and that does not trap focus is worse than none:
   without script neither behaviour is available, and promising modality the
   control cannot deliver is the accessibility failure, not the missing
   scrim. So the sheet is opaque, bordered, and sits directly under the
   control that opened it, which is exactly what it is. */
.research-instrument .ri-menu__sheet {
  position: absolute;
  z-index: 6;
  top: calc(100% + var(--ri-space-2));
  right: 0;
  width: min(22rem, calc(100vw - (var(--ri-gutter) * 2)));
  padding: var(--ri-space-3);
  background: var(--ri-paper);
  border: var(--ri-hairline) solid var(--ri-ink);
}

.research-instrument .ri-nav { display: block; }

.research-instrument .ri-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* In the sheet each practice carries the one line that tells a reader
   whether it is theirs. That is the whole reason mobile navigation is a
   sheet and not a dropdown: six bare words would make the reader guess,
   and guessing is what the direct-naming decision exists to stop. */
.research-instrument .ri-nav__list > li + li {
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-nav__link {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: var(--ri-target);
  padding-block: var(--ri-space-1);
  text-decoration: none;
  color: var(--ri-ink);
  font-weight: 700;
}

.research-instrument .ri-nav__link:hover { text-decoration: underline; }

.research-instrument .ri-nav__situation {
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  font-weight: 400;
  color: var(--ri-graphite);
}

.research-instrument .ri-nav__mark {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: var(--ri-space-1);
  vertical-align: 0.05em;
  background: var(--ri-signal, var(--ri-graphite));
}

.research-instrument .ri-nav__action { margin-top: var(--ri-space-3); width: 100%; }

/* The language switch. Quiet on purpose: it is set in the source face at
   label size in the secondary text colour, so it reads as an instrument
   control beside the six routes rather than as a seventh route competing with
   them. It keeps the full target height, because a 13px word is exactly the
   control a thumb misses. */
.research-instrument .ri-nav__language {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Both axes, not just the height. The word is seven narrow glyphs and came
     out 28px wide at 320px, which clears no target floor at all: the height
     was right and the box was still too small to press. */
  min-height: var(--ri-target);
  min-width: var(--ri-target);
  margin-top: var(--ri-space-2);
  /* The one Arabic word in the English chrome, so it is set in the Arabic
     stack the Arabic pages already use rather than in the SOURCE face: IBM
     Plex Mono carries no Arabic, and asking for it means the browser
     substitutes something unchosen for the only word that has to be
     recognisable. Local names then a generic, so no English page acquires a
     font request for seven glyphs. */
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.06em;
  color: var(--ri-graphite);
  text-decoration: none;
}

.research-instrument .ri-nav__language:hover { text-decoration: underline; }

/* Above 56rem the sheet stops being a sheet: the six routes become the bar,
   the disclosure disappears, and the practice situations fold away because
   the page beneath them says the same thing at greater length.

   56rem, not 64rem. At 64rem the bar only arrived at 1024px, so every
   window narrower than that — a half-screen browser, a small laptop, and
   any desktop reader at 125% or 150% zoom, since zoom shrinks the layout
   viewport — was served a wordmark and the word Menu on a screen with room
   for the whole bar. Measured in Blink, Gecko and WebKit, the six routes and
   the action fit from 896px with the header no taller than it already is at
   1024px, and 768px is still the sheet. The one number decides where the
   navigation is visible on first paint, so it is set where the navigation
   actually fits rather than at the width the grid happens to change on. */
/* The disclosure has to open and stay open without anyone clicking it, and a
   closed <details> hides its own content. Engines do that hiding in two
   different places depending on age: older ones apply it to the direct
   children, newer ones to the ::details-content pseudo. Both are overridden,
   because getting this wrong on one engine means the entire desktop
   navigation is invisible and no test that reads markup would ever
   notice. */
@media (min-width: 56rem) {
  .research-instrument .ri-menu::details-content {
    content-visibility: visible;
    block-size: auto;
    opacity: 1;
  }

  .research-instrument .ri-menu > .ri-menu__sheet { display: block; }

  .research-instrument .ri-menu__toggle { display: none; }

  /* The wordmark stops growing once the navigation is a bar. Left growing,
     it claimed the whole first row and pushed six routes onto a second one,
     which is how the header reached 145px at 1440 and 205px at 1024. */
  .research-instrument .ri-header__inner > .ri-wordmark { flex: 0 0 auto; }
  .research-instrument .ri-header__inner > .ri-menu { flex: 1 1 auto; min-width: 0; }

  .research-instrument .ri-menu__sheet {
    position: static;
    width: auto;
    padding: 0;
    border: 0;
    background: transparent;
  }

  /* One row: the five routes and the action. The nav was a block, so the
     action was a block-level sibling of the list and dropped to a second
     line, which made the header 145px tall at 1440 and 205px at 1024, where
     it pushed the primary action off the first screen entirely. */
  /* space-2 between the routes, not space-3. The language switch added one
     more item to a row that was already exactly full at 896px, and the row
     broke into a third line: a 218px header on a 900px-wide window, where 158
     was already generous. Tightening the one gap by a step on the existing
     scale puts the routes, the action and the switch back on one row across
     Blink, Gecko and WebKit, from 896px up. */
  .research-instrument .ri-nav {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--ri-space-2);
  }

  .research-instrument .ri-nav__list {
    display: flex;
    align-items: center;
    gap: var(--ri-space-2);
  }

  .research-instrument .ri-nav__list > li + li { border-top: 0; }

  .research-instrument .ri-nav__situation { display: none; }

  .research-instrument .ri-nav__link { font-weight: 400; }

  .research-instrument .ri-nav__action { margin-top: 0; width: auto; }

  .research-instrument .ri-nav__language { margin-top: 0; }
}

/* space-5, not space-7. The closing section already ends with 96px of its
   own padding, so a 144px footer margin on top of it left roughly 240px of
   nothing between the last enquiry route and the first footer heading, which
   read as the page having finished twice. */
.research-instrument .ri-footer {
  border-top: var(--ri-hairline) solid var(--ri-rule);
  margin-top: var(--ri-space-5);
  padding-block: var(--ri-space-5) var(--ri-space-4);
}

.research-instrument .ri-footer__grid { row-gap: var(--ri-space-4); }

.research-instrument .ri-footer__list {
  list-style: none;
  margin: var(--ri-space-2) 0 0;
  padding: 0;
}

.research-instrument .ri-footer__list > li > a {
  display: inline-flex;
  align-items: center;
  min-height: var(--ri-target);
  color: var(--ri-ink);
  text-decoration: none;
}

.research-instrument .ri-footer__list > li > a.ri-footer__action {
  color: var(--ri-paper);
}

/* At desktop widths the enquiry action never wraps mid-label; at handset
   and zoomed widths it may, so a 320px viewport at 200% zoom reflows
   instead of overflowing. */
@media (min-width: 48rem) {
  .research-instrument .ri-footer__list > li > a.ri-footer__action { white-space: nowrap; }
}

.research-instrument .ri-footer__list > li > a:hover { text-decoration: underline; }

/* Privacy and Terms sit in the same list as the site routes. A hairline
   above the first legal address separates the pair without changing the
   byte-exact footer markup the shell contract holds. */
.research-instrument .ri-footer__list > li:has(> a[href$="privacy.html"]) {
  margin-top: var(--ri-space-2);
  padding-top: var(--ri-space-2);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

/* From 48rem the routes are a row, not a column.
   Nine short words were stacked one per line in a two-track column, which
   made the footer 718px tall at 1440 with the left two thirds of the frame
   empty and the whole of a reader's route list a vertical scan. It is the
   navigation anyone reaches at the foot of a 6,800px practice page, so it is
   worth the width the grid was already reserving for it. Same links, same
   type, same 44px targets; one axis changed. */
@media (min-width: 48rem) {
  .research-instrument .ri-footer__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: var(--ri-space-3);
  }

  /* In a row the separator has to turn with it: a border above one item in
     the middle of a line reads as a mistake rather than as a divider. */
  .research-instrument .ri-footer__list > li:has(> a[href$="privacy.html"]) {
    margin-top: 0;
    padding-top: 0;
    padding-inline-start: var(--ri-space-3);
    border-top: 0;
    border-inline-start: var(--ri-hairline) solid var(--ri-rule);
  }
}

.research-instrument .ri-footer__legal {
  margin-top: var(--ri-space-4);
  padding-top: var(--ri-space-3);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

/* 4 + 8. The note this replaces described three link columns filling
   6 + 2 + 2 + 2; there has been one column for some time, so span 2 left four
   of the twelve tracks empty and squeezed ten routes into 184px. The identity
   is two short lines and does not need six tracks. */
@media (min-width: 64rem) {
  .research-instrument .ri-footer__identity { grid-column: span 4; }
  .research-instrument .ri-footer__column { grid-column: span 8; }
  .research-instrument .ri-footer__legal { grid-column: 1 / -1; }
}

/* ================================================================== */
/* Page rhythm                                                          */
/* ================================================================== */
/* A section is separated by space and, where the argument turns, by one
   hairline. Sections are never boxes: a page of bordered blocks is the
   bento grid this system was chosen instead of. */

.research-instrument .ri-section { padding-block: var(--ri-space-6) var(--ri-space-7); }
.research-instrument .ri-section + .ri-section { border-top: var(--ri-hairline) solid var(--ri-rule); }
.research-instrument .ri-section__head { margin-bottom: var(--ri-space-5); }

.research-instrument .ri-section__head > .ri-heading + .ri-lead,
.research-instrument .ri-section__head > .ri-question + .ri-lead,
.research-instrument .ri-section__head > .ri-close__question + .ri-lead {
  margin-top: var(--ri-space-3);
  max-width: 52ch;
}

.research-instrument .ri-follow { margin-top: var(--ri-space-3); }

.research-instrument .ri-section__head .ri-cluster { margin-top: var(--ri-space-4); }

.research-instrument .ri-source--label + .ri-question,
.research-instrument .ri-source--label + .ri-heading {
  margin-top: var(--ri-space-2);
}

.research-instrument .ri-source--label + .ri-body,
.research-instrument .ri-source--label + .ri-account,
.research-instrument .ri-body + .ri-account {
  margin-top: var(--ri-space-2);
}

.research-instrument [data-output-block] > .ri-account:first-child { margin-top: 0; }

.research-instrument .ri-opening .ri-link { margin-top: var(--ri-space-3); }

.research-instrument .ri-body + details.ri-panel { margin-top: var(--ri-space-4); }

/* Practice pages share one method: a quiet signal rail on each section
   head, and a hairline between sections. The rail is the same mark the
   nav already uses. It is not a second numbering system. */
.research-instrument[data-ri-practice] .ri-section .ri-section__head {
  padding-inline-start: var(--ri-space-3);
  border-inline-start: 2px solid var(--ri-signal, var(--ri-rule));
}

/* 96px of section air is the desktop document rhythm. On a handset it
   stacked into long empty runs between short blocks, especially on the
   practice pages and the research register. The scale step below is still
   the system; it is not a new spacing language. */
@media (max-width: 47.99rem) {
  .research-instrument .ri-section { padding-block: var(--ri-space-5); }
  .research-instrument .ri-editorial-band { padding-block: var(--ri-space-5); }
  /* The practice rail is 24px of start padding. Combined with a 24px-padded
     enquiry action it overflowed a 160px 200%-zoom viewport by 12px. The
     same handset step already used for section air; not a new spacing
     language. */
  .research-instrument[data-ri-practice] .ri-section .ri-section__head {
    padding-inline-start: var(--ri-space-2);
  }
  .research-instrument .ri-action {
    padding-inline: var(--ri-space-2);
  }
}

/* The folio is a quiet section label, not a checklist. Sequential numbers
   made every page read as a procedure. The kicker remains, in the source
   face, so the page still has named parts. */
.research-instrument .ri-folio {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--ri-space-1) var(--ri-space-2);
  margin-bottom: var(--ri-space-3);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-folio::after { content: none; }

.research-instrument .ri-folio__number {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ================================================================== */
/* The hero: an argument beside a working canvas                        */
/* ================================================================== */
/* Seven columns of argument, a column of air, four columns of canvas. The
   air is the point. Equal halves are what made the previous hero read as a
   template, and a canvas pushed to the very edge reads as an illustration
   rather than as the thing being argued about. */

.research-instrument .ri-hero { padding-block: var(--ri-space-5) var(--ri-space-6); }

.research-instrument .ri-hero__eyebrow { margin-bottom: var(--ri-space-3); }

.research-instrument .ri-hero__question { max-width: 15ch; }

.research-instrument .ri-hero__lead { margin-top: var(--ri-space-3); max-width: 52ch; }

.research-instrument .ri-hero__actions { margin-top: var(--ri-space-4); }

.research-instrument .ri-hero__note { margin-top: var(--ri-space-3); }

.research-instrument .ri-hero__credential {
  margin-top: var(--ri-space-3);
  max-width: 46ch;
}

/* The three practices, in the first screen, in full. Rows on one rule, not
   three boxes: this is an index of what the office is, and the chapters
   below are where each one is argued. */
.research-instrument .ri-hero__practices {
  list-style: none;
  margin: var(--ri-space-4) 0 0;
  padding: 0;
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-hero__practices > li { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-hero__practice {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--ri-space-2);
  min-height: var(--ri-target);
  padding-block: var(--ri-space-1);
  text-decoration: none;
  color: var(--ri-ink);
}

.research-instrument .ri-hero__practice:hover .ri-hero__practice-name { text-decoration: underline; }

/* Shrinkable. At 0 0 auto the longest practice name, uppercased, was 305px
   wide inside a 280px column at 320px and pushed the page sideways by 5px. */
.research-instrument .ri-hero__practice-name {
  font-weight: 700;
  font-size: var(--ri-type-meta);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex: 0 1 auto;
  min-width: 0;
}

.research-instrument .ri-hero__practice-situation {
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
  flex: 1 1 16ch;
  min-width: 0;
}

@media (min-width: 64rem) {
  .research-instrument .ri-hero__argument { grid-column: 1 / span 7; }
  .research-instrument .ri-hero__canvas { grid-column: 9 / span 4; }

  /* The practice entrances fill the hero's right field at desktop instead
     of leaving it a dead area: aligned to the argument's first line, each
     entrance its own ruled row. Below this width they follow the argument
     in one column, exactly as before. */
  .research-instrument .ri-hero__canvas .ri-hero__practices {
    margin-top: var(--ri-space-2);
  }
  .research-instrument .ri-hero__canvas .ri-hero__practice {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding-block: var(--ri-space-2);
  }
  /* The situation line's 16ch flex-basis is a width in the row layout, but
     inside the column-direction canvas it would become a forced height and
     stretch every entrance to ~190px. Let content set the height here. */
  .research-instrument .ri-hero__canvas .ri-hero__practice-situation {
    flex: 0 1 auto;
  }
}

/* The canvas: the spine, doing the thing the site claims to do, on the page
   that claims it. It is an ordered list with a caption, so with CSS off it
   reads as four numbered steps and loses nothing at all. */
.research-instrument .ri-canvas {
  margin-top: var(--ri-space-4);
  padding: var(--ri-space-3);
  border: var(--ri-hairline) solid var(--ri-rule);
  background: var(--ri-paper-deep);
}

@media (min-width: 64rem) {
  .research-instrument .ri-canvas { margin-top: 0; }
}

.research-instrument .ri-canvas__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--ri-space-2);
  margin-bottom: var(--ri-space-3);
  padding-bottom: var(--ri-space-2);
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-canvas .ri-spine { padding-left: var(--ri-space-3); }
.research-instrument .ri-canvas .ri-spine > li::before { left: calc((var(--ri-space-3) / -1) - 4px); }

.research-instrument .ri-node__label {
  display: block;
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ri-graphite);
  margin-bottom: var(--ri-space-1);
}

.research-instrument .ri-node__body {
  margin: 0;
  font-size: var(--ri-type-body);
  line-height: 1.45;
}

.research-instrument .ri-node__body--question {
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.25;
}

/* ================================================================== */
/* Section 2: the index of what people bring                            */
/* ================================================================== */
/* Problems as an index, not a numbered procedure. The counter column was
   the same checklist feel as the folio numbers; the practice label still
   names the row in words. */
.research-instrument .ri-index {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .ri-index > li {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--ri-space-1) var(--ri-space-3);
  padding-block: var(--ri-space-4);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-index > li:last-child { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-index__quote {
  grid-column: 1;
  margin: 0;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.4;
  max-width: 46ch;
}

.research-instrument .ri-index__practice {
  display: block;
  grid-column: 1;
  margin-top: var(--ri-space-1);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ri-signal-text, var(--ri-graphite));
}

@media (min-width: 64rem) {
  .research-instrument .ri-index > li { grid-template-columns: minmax(0, 62ch) minmax(0, 1fr); }
  .research-instrument .ri-index__practice { grid-column: 2; margin-top: 0.35em; }
}

/* ================================================================== */
/* Section 3: the three practice chapters                               */
/* ================================================================== */
/* Each chapter is a brief with its own working artefact, and the three
   artefacts are different objects because the three practices do different
   work. Three identical boxes would have said the opposite. */

.research-instrument .ri-chapter { padding-block: var(--ri-space-5); }
.research-instrument .ri-chapter + .ri-chapter { border-top: var(--ri-hairline) solid var(--ri-rule); }

/* Homepage practice entrances are editorial rows, not interchangeable
   cards. The markup uses .ri-practice-rows; .ri-practice-doors was the
   unused three-column leftover and now aliases the same stacked rhythm
   so it cannot silently become a bento. */
.research-instrument .ri-practice-rows,
.research-instrument .ri-practice-doors {
  margin-top: var(--ri-space-4);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-practice-door {
  padding-block: var(--ri-space-5);
  padding-inline-start: var(--ri-space-3);
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
  border-inline-start: 2px solid var(--ri-signal, var(--ri-rule));
}

.research-instrument .ri-practice-door > * + * { margin-top: var(--ri-space-2); }

.research-instrument .ri-practice-door:hover {
  background: var(--ri-paper-deep);
}

.research-instrument .ri-practice-door:focus-within {
  outline: 2px solid var(--ri-ink);
  outline-offset: 3px;
}

.research-instrument .ri-chapter__mark {
  display: inline-block;
  width: var(--ri-space-4);
  height: 3px;
  margin-bottom: var(--ri-space-2);
  background: var(--ri-signal, var(--ri-ink));
}

.research-instrument .ri-chapter__brief > * + * { margin-top: var(--ri-space-3); }

.research-instrument .ri-chapter__artefact { margin-top: var(--ri-space-4); }

.research-instrument .ri-chapter__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .ri-chapter__list > li {
  padding-block: var(--ri-space-1);
  padding-left: var(--ri-space-3);
  border-left: 2px solid var(--ri-signal, var(--ri-rule));
}

.research-instrument .ri-chapter__list > li + li { margin-top: var(--ri-space-1); }

/* A boundary is not a source. It was set in the SOURCE face because it uses
   the same margin treatment, and four lines of tracked mono at 13px is hard
   reading for the one paragraph on each chapter a client most needs to
   understand. Same rail, same size, reading face. */
.research-instrument .ri-chapter__note {
  display: block;
  padding-left: var(--ri-space-2);
  border-left: 2px solid var(--ri-signal, var(--ri-rule));
  font-size: var(--ri-type-meta);
  line-height: 1.5;
  color: var(--ri-graphite);
  max-width: var(--ri-measure-narrow);
  /* No margin reset. The type roles all zero their margins and let
     .ri-chapter__brief > * + * do the spacing, and a `margin: 0` here would
     win on later-wins and jam the boundary note against the last line of the
     list above it, with its rule running straight into theirs. */
}

@media (min-width: 64rem) {
  /* grid-row is declared, not left to auto placement. Auto placement is
     sparse: it never moves the cursor backwards, so in the reversed chapter
     the argument was placed at column 8 of row 1 and the artefact, asking
     for column 1, was pushed to row 2. The result was a chapter with an
     empty left half and its artefact stranded 700px below the sentence that
     introduces it. */
  .research-instrument .ri-chapter__brief { grid-column: 1 / span 5; grid-row: 1; }
  .research-instrument .ri-chapter__artefact {
    grid-column: 7 / span 6;
    grid-row: 1;
    margin-top: 0;
  }
  /* The health chapter reverses the fields. Three chapters that all put the
     argument left and the artefact right is a template with three rows; the
     reversal is what makes the middle chapter read as its own thing. */
  .research-instrument .ri-chapter--reversed .ri-chapter__brief { grid-column: 8 / span 5; }
  .research-instrument .ri-chapter--reversed .ri-chapter__artefact { grid-column: 1 / span 6; }
}

/* Business: the comparison ledger. A real table, because a comparison with a
   verification state per row IS a table, and a div grid pretending to be one
   would lose the row and column relationships a screen reader needs. */
/* A three-column comparison with a verification state per row is genuinely a
   table, and it stays one: a screen reader needs the row and column
   relationships, and a grid of divs pretending to be a table throws them
   away. What a table cannot do is shrink below the width its content needs,
   and at 320px this one needed 301px inside a 280px column and pushed the
   whole page sideways by a pixel.

   So the table keeps its semantics and the container takes the strain. It is
   the WAI scrollable-region pattern: role="region", an accessible name, and
   tabindex="0" so a keyboard user can scroll it without a pointer. It is not
   a horizontal-scroll design; it is a floor. The table is width:100% and
   scrolls only when the viewport is narrower than its content can wrap to,
   which from 360px upwards it is not. */
.research-instrument .ri-ledger__scroll { overflow-x: auto; }

.research-instrument .ri-ledger {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--ri-type-body);
}

.research-instrument .ri-ledger caption {
  margin-bottom: var(--ri-space-2);
  text-align: left;
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-ledger th,
.research-instrument .ri-ledger td {
  padding: var(--ri-space-2) var(--ri-space-2) var(--ri-space-2) 0;
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
  text-align: left;
  vertical-align: top;
}

/* The status column takes exactly the width its labels need, and its labels
   never break. Left to the automatic table algorithm the column was squeezed
   to about 70px and every chip printed as "CLAIME / D", "VERIFI / ED",
   "UNKNOW / N": the one column whose whole job is to be read at a glance was
   the only one that could not be. When the viewport is genuinely too narrow
   for that, the scroll container above takes it, which is the correct
   trade: a state name is either legible or it is not, and half a word is
   not. */
.research-instrument .ri-ledger td:last-child,
.research-instrument .ri-ledger th:last-child {
  width: 1px;
  white-space: nowrap;
  padding-right: 0;
}

.research-instrument .ri-ledger thead th {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
  border-bottom-color: var(--ri-ink);
}

.research-instrument .ri-ledger tbody th {
  font-family: var(--ri-evidence);
  font-weight: 700;
  width: 34%;
}

/* Health: the evidence and mechanism map. One claim, the mechanism proposed
   for it, the state of the evidence, and what it would take to settle it.
   The fourth column is the one that makes it research rather than an
   opinion, so it is never dropped at handset width. */
.research-instrument .ri-map {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .ri-map > li {
  padding-block: var(--ri-space-3);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-map > li:last-child { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-map__claim {
  margin: 0 0 var(--ri-space-2);
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.3;
}

.research-instrument .ri-map__rows { margin: 0; }

.research-instrument .ri-map__rows > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
  padding-block: var(--ri-space-1);
}

.research-instrument .ri-map__rows dt {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-map__rows dd { margin: 0; }

@media (min-width: 48rem) {
  .research-instrument .ri-map__rows > div {
    grid-template-columns: 11rem minmax(0, 1fr);
    gap: var(--ri-space-2);
    align-items: baseline;
  }
}

/* Private AI: the permission boundary. Two lists and a written rule, not a
   picture. Inside the boundary is what the reference system actually does;
   outside it is what it deliberately cannot reach. Every item prints its own
   state, and the dashed border on the outside group survives greyscale. */
/* minmax(0, 1fr) rather than the implicit default. A grid item's automatic
   minimum is its min-content width, so a single-column grid silently refuses
   to go narrower than its longest unbreakable line. Three of these were the
   whole of the remaining 200%-zoom overflow. */
.research-instrument .ri-boundary {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--ri-space-3);
}

.research-instrument .ri-boundary__group {
  padding: var(--ri-space-3);
  border: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-boundary__group--outside {
  border-style: dashed;
  background: var(--ri-paper-deep);
}

.research-instrument .ri-boundary__title {
  margin: 0 0 var(--ri-space-2);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-boundary__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .ri-boundary__list > li + li {
  margin-top: var(--ri-space-2);
  padding-top: var(--ri-space-2);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-boundary__name { display: block; font-weight: 700; }

.research-instrument .ri-boundary__note {
  display: block;
  margin-top: 2px;
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
}

.research-instrument .ri-boundary__state { margin-top: var(--ri-space-1); }

@media (min-width: 48rem) {
  .research-instrument .ri-boundary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ================================================================== */
/* Section 4: one method                                                */
/* ================================================================== */
/* Five steps on one horizontal rule at desktop and one vertical rule at
   handset. It is the same ordered list either way, and the numbers are
   content rather than pseudo-decoration, because a method whose steps a
   screen reader cannot count is not a method a reader can check. */

.research-instrument .ri-method {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}

.research-instrument .ri-method > li {
  padding-block: var(--ri-space-3);
  padding-left: var(--ri-space-3);
  border-left: 2px solid var(--ri-rule);
}

.research-instrument .ri-method > li[data-ri-node="decision"] { border-left-color: var(--ri-ink); }

.research-instrument .ri-method__step {
  display: block;
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-method__name {
  display: block;
  margin-top: var(--ri-space-1);
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.25;
}

.research-instrument .ri-method__body { margin-top: var(--ri-space-1); }

@media (min-width: 64rem) {
  .research-instrument .ri-method {
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: var(--ri-gap);
  }

  .research-instrument .ri-method > li {
    padding-left: 0;
    padding-top: var(--ri-space-3);
    border-left: 0;
    border-top: 2px solid var(--ri-rule);
  }

  .research-instrument .ri-method > li[data-ri-node="decision"] {
    border-left-color: var(--ri-rule);
    border-top-color: var(--ri-ink);
  }
}

/* ================================================================== */
/* Sections 5 and 6: selected inquiries and proof of method             */
/* ================================================================== */

.research-instrument .ri-inquiry {
  padding-block: var(--ri-space-4);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-inquiry__question {
  margin: var(--ri-space-1) 0 0;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.3;
  max-width: 46ch;
}

.research-instrument .ri-inquiry__rows { margin: var(--ri-space-3) 0 0; }

.research-instrument .ri-inquiry__rows > div { padding-block: var(--ri-space-1); }

.research-instrument .ri-inquiry__rows dt {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-inquiry__rows dd { margin: 0; }

@media (min-width: 64rem) {
  .research-instrument .ri-inquiry { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--ri-gap); }
  .research-instrument .ri-inquiry__rows { margin-top: 0; }
  .research-instrument .ri-inquiry__rows > div { display: grid; grid-template-columns: 10rem minmax(0, 1fr); gap: var(--ri-space-2); align-items: baseline; }
}

.research-instrument .ri-specimen {
  padding: var(--ri-space-3);
  border: var(--ri-hairline) solid var(--ri-rule);
  background: var(--ri-paper-deep);
}

.research-instrument .ri-specimen + .ri-specimen { margin-top: var(--ri-space-3); }

.research-instrument .ri-specimen__title {
  margin: 0 0 var(--ri-space-2);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .ri-specimen__list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: ri-specimen;
}

.research-instrument .ri-specimen__list > li {
  counter-increment: ri-specimen;
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: var(--ri-space-2);
  padding-block: var(--ri-space-1);
}

.research-instrument .ri-specimen__list > li + li { border-top: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-specimen__list > li::before {
  content: counter(ri-specimen, decimal-leading-zero);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: 1.9;
  color: var(--ri-graphite);
}

/* The label key is its own list, not the numbered specimen list wearing a
   reset. It was built by borrowing .ri-specimen__list and cancelling its
   counter, which left every row inside a 2rem / 1fr grid: the state chip
   took the wide track and the sentence beside it was pushed into the 2rem
   one, where it printed one or two characters per line for eleven lines.
   Two different lists were needed, so there are two. */
.research-instrument .ri-labels {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .ri-labels > li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--ri-space-1) var(--ri-space-2);
  padding-block: var(--ri-space-2);
}

.research-instrument .ri-labels > li + li { border-top: var(--ri-hairline) solid var(--ri-rule); }

/* Shrinkable, so the chip can break at 200% zoom rather than carrying an
   86px box into a 70px column and taking the page sideways with it. */
.research-instrument .ri-labels > li > .ri-state { flex: 0 1 auto; min-width: 0; }

.research-instrument .ri-labels > li > .ri-body { flex: 1 1 14ch; min-width: 0; }

@media (min-width: 64rem) {
  .research-instrument .ri-specimens { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ri-gap); align-items: start; }
  .research-instrument .ri-specimen + .ri-specimen { margin-top: 0; }
}

/* ================================================================== */
/* Section 7: the research index                                        */
/* ================================================================== */
/* Rows, not cards. Title, area, reviewed date, evidence state, one abstract
   line. The whole row is not the link: the title is, so a reader tabbing
   through hears the title rather than the abstract read back at them. */

.research-instrument .ri-research {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .ri-research > li {
  padding-block: var(--ri-space-3);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-research > li:last-child { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-research__title {
  margin: 0;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.3;
}

.research-instrument .ri-research__title a {
  display: inline-flex;
  align-items: center;
  min-height: var(--ri-target);
  color: var(--ri-ink);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}

.research-instrument .ri-research__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ri-space-2);
  margin-top: var(--ri-space-1);
}

.research-instrument .ri-research__abstract { margin-top: var(--ri-space-2); max-width: 72ch; }

@media (min-width: 64rem) {
  .research-instrument .ri-research > li { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--ri-gap); align-items: start; }
  .research-instrument .ri-research__abstract { margin-top: 0; }
}

/* ================================================================== */
/* Sections 8 and 9: accountability and the final question              */
/* ================================================================== */

/* About sits as two fields on one row: the heading holds the left, the
   account holds the right. Set as a span-6 with an offset it produced a
   heading alone at the top, a vertical hole beneath it, and an indented
   column of text with the whole right half of the page empty. The
   accountability list then runs under the prose in the same field, because
   it is the same argument continued. */
.research-instrument .ri-account {
  list-style: none;
  margin: var(--ri-space-4) 0 0;
  padding: 0;
}

.research-instrument .ri-account > li {
  padding-block: var(--ri-space-3);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-account > li:last-child { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-account__name {
  display: block;
  font-weight: 700;
}

.research-instrument .ri-account__body { margin-top: var(--ri-space-1); }

@media (min-width: 64rem) {
  .research-instrument .ri-about__head { grid-column: 1 / span 4; grid-row: 1; }
  .research-instrument .ri-about__body { grid-column: 6 / span 7; grid-row: 1; }
  .research-instrument .ri-account { grid-column: 6 / span 7; grid-row: 2; margin-top: var(--ri-space-4); }
}

/* The principal beside the close: the one human moment on the homepage,
   next to the sentence that is literally about him. The same editorial
   crop the About page uses; on a handset it sits between the sentence and
   the action at a restrained width. */
.research-instrument .ri-grid figure.ri-close__portrait {
  margin: var(--ri-space-2) 0 0;
  grid-column: 1 / -1;
}

.research-instrument figure.ri-close__portrait img {
  display: block;
  width: min(220px, 100%);
  height: 275px;
  object-fit: cover;
  object-position: 50% 22%;
  border: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument figure.ri-close__portrait figcaption {
  margin-top: var(--ri-space-1);
  max-width: 28ch;
}

@media (min-width: 64rem) {
  .research-instrument .ri-grid figure.ri-close__portrait {
    grid-column: 9 / span 3;
    grid-row: 1 / span 3;
    margin: 0;
    align-self: start;
  }
}

.research-instrument .ri-close__question {
  max-width: 20ch;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h1);
  line-height: var(--ri-type-h1-line);
  letter-spacing: -0.015em;
  margin: 0;
  hyphens: none;
  -webkit-hyphens: none;
}

.research-instrument .ri-routes {
  list-style: none;
  margin: var(--ri-space-4) 0 0;
  padding: 0;
}

.research-instrument .ri-routes > li {
  padding-block: var(--ri-space-3);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-routes > li:last-child { border-bottom: var(--ri-hairline) solid var(--ri-rule); }

.research-instrument .ri-routes__name {
  display: block;
  font-weight: 700;
  color: var(--ri-signal-text, var(--ri-ink));
}

.research-instrument .ri-routes__body { margin-top: var(--ri-space-1); }

.research-instrument .ri-routes__action { margin-top: var(--ri-space-2); }

@media (min-width: 64rem) {
  .research-instrument .ri-routes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ri-gap); }
  .research-instrument .ri-routes > li:last-child { border-bottom: 0; }
}

/* ================================================================== */
/* Column spans used across sections                                    */
/* ================================================================== */
/* Declared in one place rather than beside each section, because a span is
   a property of the grid and not of the content that happens to sit in it. */

@media (min-width: 64rem) {
  .research-instrument .ri-span-4 { grid-column: span 4; }
  .research-instrument .ri-span-5 { grid-column: span 5; }
  .research-instrument .ri-span-6 { grid-column: span 6; }
  .research-instrument .ri-span-7 { grid-column: span 7; }
  .research-instrument .ri-span-8 { grid-column: span 8; }
  .research-instrument .ri-offset-1 { grid-column: 2 / span 6; }
}

/* ================================================================== */
/* The one animated sequence                                            */
/* ================================================================== */
/* The hero spine settles once, on load: the four nodes arrive in order over
   a total of 640ms and then nothing on the site moves again. Only opacity
   and transform are animated, so layout is final at first paint and CLS is
   zero. With reduced motion requested this block never matches and the
   settled spine is simply what renders. */

@media (prefers-reduced-motion: no-preference) {
  .research-instrument .ri-canvas .ri-spine > li {
    animation: ri-settle var(--ri-motion-diagram) var(--ri-ease) both;
  }

  .research-instrument .ri-canvas .ri-spine > li:nth-child(2) { animation-delay: 80ms; }
  .research-instrument .ri-canvas .ri-spine > li:nth-child(3) { animation-delay: 160ms; }
  .research-instrument .ri-canvas .ri-spine > li:nth-child(4) { animation-delay: 240ms; }

  @keyframes ri-settle {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }
}

/* ================================================================== */
/* The business practice page                                          */
/* ================================================================== */
/* /business/ is the first practice page on this system. Almost all of it
   is drawn by the primitives above: the problems are an .ri-index, the
   comparison is an .ri-ledger, the four steps are an .ri-method, the
   outputs and the boundaries are .ri-account lists, and the engagement is
   an .ri-panel. What is added here is the small amount that has no
   primitive yet, plus scoped rules for two shared components whose markup
   this route must not change.

   The Project Note and the enquiry form keep their existing markup, byte
   for byte, because tools/lib/artefacts.mjs renders the note for two
   routes and the form is a live Netlify form whose field names, labels and
   receipt are a deployed contract. Restyling them here rather than
   rewriting them is what lets the page change system without the form
   changing at all. */

.research-instrument .ri-opening {
  padding: var(--ri-space-3);
  border: var(--ri-hairline) solid var(--ri-rule);
  background: var(--ri-paper-deep);
}

.research-instrument .ri-opening__question {
  margin: var(--ri-space-2) 0 0;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.3;
}

.research-instrument .ri-opening__situation { margin-top: var(--ri-space-3); }

/* Who the work is for, as rows on one rule. Not three columns of icons: it
   is a list of situations, and a list should look like one. */
.research-instrument .ri-audience {
  list-style: none;
  margin: var(--ri-space-3) 0 0;
  padding: 0;
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .ri-audience > li {
  padding-block: var(--ri-space-2);
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
}

/* The decision the ledger arrives at. It sits under the table, in the
   reading face at reading size, because it is the one line in that section
   a reader is meant to leave with. */
.research-instrument .ri-decision { margin-top: var(--ri-space-3); }

.research-instrument .ri-decision__label {
  display: block;
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ri-graphite);
  margin-bottom: var(--ri-space-1);
}

.research-instrument .ri-decision__body {
  margin: 0;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.3;
}

/* Four steps, not five. The .ri-method grid is declared for the five-step
   homepage method; a four-step process on five tracks leaves one empty
   track and reads as a step somebody forgot to write. */
@media (min-width: 64rem) {
  .research-instrument .ri-method--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ------------------------------------------------------------------ */
/* The Project Note, on this system                                    */
/* ------------------------------------------------------------------ */
/* Five parts, each labelled in the source face, on the inset surface. The
   issue crosses the whole note at desktop and the four parts below it pair
   up, so the note reads as a document rather than as five stacked rows. */

.research-instrument .note {
  padding: var(--ri-space-3);
  border: var(--ri-hairline) solid var(--ri-rule);
  background: var(--ri-paper-deep);
}

.research-instrument .note__disclosure {
  margin: 0 0 var(--ri-space-3);
  padding-bottom: var(--ri-space-2);
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
}

.research-instrument .note__part { padding-block: var(--ri-space-2); }

.research-instrument .note__label {
  display: block;
  margin-bottom: var(--ri-space-1);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument .note__issue {
  margin: 0;
  font-family: var(--ri-question);
  font-size: var(--ri-type-h3);
  line-height: 1.3;
}

.research-instrument .note__body { margin: 0; }

.research-instrument .note__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.research-instrument .note__list li {
  padding-block: var(--ri-space-1);
  padding-left: var(--ri-space-3);
  border-left: 2px solid var(--ri-signal, var(--ri-rule));
}

.research-instrument .note__list li + li { margin-top: var(--ri-space-1); }

@media (min-width: 64rem) {
  .research-instrument .note {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--ri-gap);
    padding: var(--ri-space-4);
  }

  .research-instrument .note__disclosure { grid-column: 1 / -1; }
  .research-instrument .note__part[data-note-part="issue"] { grid-column: 1 / -1; }
}

/* ------------------------------------------------------------------ */
/* The enquiry form, on this system                                    */
/* ------------------------------------------------------------------ */
/* One column, generous targets, and every control visibly bordered on the
   paper surface. Nothing here is a placeholder standing in for a label:
   the labels are real, they are above their controls, and they stay on
   screen while the field is being filled. */

.research-instrument .enquiry {
  margin-top: var(--ri-space-4);
  max-width: var(--ri-measure);
}

.research-instrument .enquiry__field { margin-bottom: var(--ri-space-3); }

.research-instrument .enquiry__field label {
  display: block;
  margin-bottom: var(--ri-space-1);
  font-weight: 700;
}

.research-instrument .enquiry input[type="text"],
.research-instrument .enquiry input[type="email"],
.research-instrument .enquiry textarea {
  display: block;
  width: 100%;
  min-height: var(--ri-target);
  padding: var(--ri-space-1) var(--ri-space-2);
  border: var(--ri-hairline) solid var(--ri-ink);
  background: var(--ri-paper);
  color: var(--ri-ink);
  color-scheme: light;
  accent-color: var(--ri-ink);
  font-family: var(--ri-evidence);
  font-size: var(--ri-type-body);
  line-height: var(--ri-type-body-line);
}

.research-instrument .enquiry textarea { resize: vertical; }

.research-instrument .enquiry__field .practice-note {
  display: block;
  margin-top: var(--ri-space-1);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
}

/* The checkbox keeps its own hit area and the label sits beside it, so the
   whole line is one target rather than a 13px square next to some text. */
.research-instrument .enquiry__consent {
  display: flex;
  align-items: flex-start;
  gap: var(--ri-space-2);
  margin-bottom: var(--ri-space-3);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
}

.research-instrument .enquiry__consent input {
  flex: 0 0 auto;
  width: var(--ri-space-3);
  height: var(--ri-space-3);
  margin-top: 2px;
  accent-color: var(--ri-ink);
  color-scheme: light;
}

/* The consent glyph is 24px square by design, and a 24px square is not a
   target. What a pointer actually operates here is the union of the glyph
   and the label bound to it by `for`, so the label carries the floor.

   `min-height` is the whole fix and it needs the block box to land on:
   the label is a flex item, so it is blockified and the floor applies, but
   the declaration is spelled out because an inline label would silently
   ignore it. At 390px the sentence wrapped to two lines — 35px against the
   24px box, a 35px union — and that is the width this failed at. The floor
   is not lowered anywhere and no selector is exempted; the target is simply
   made large enough to be one. Held by the journey gate's 44px rule at
   every swept width, and stated as data in
   tests/journey-target-size.test.mjs. */
.research-instrument .enquiry__consent label {
  display: block;
  min-width: 0;
  min-height: var(--ri-target);
  margin-bottom: 0;
}

.research-instrument .enquiry__consent a { color: var(--ri-signal-text, var(--ri-ink)); }

.research-instrument .enquiry__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--ri-target);
  padding: var(--ri-space-1) var(--ri-space-3);
  border: var(--ri-hairline) solid var(--ri-ink);
  background: var(--ri-ink);
  color: var(--ri-paper);
  font-family: var(--ri-evidence);
  font-size: var(--ri-type-body);
  font-weight: 700;
  cursor: pointer;
}

.research-instrument .enquiry__hint {
  margin-top: var(--ri-space-2);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-graphite);
  max-width: var(--ri-measure-narrow);
}

/* Empty until a browser or a later enhancement writes into it. Hidden
   when empty so the form does not open with a blank error slot; when it
   has text it is a panel, not a colour-only warning. */
.research-instrument .enquiry__errors:empty { display: none; }

.research-instrument .enquiry__errors:not(:empty) {
  margin-bottom: var(--ri-space-3);
  padding: var(--ri-space-2);
  border: var(--ri-hairline) solid var(--ri-rule);
  border-inline-start: 2px solid var(--ri-ink);
  background: var(--ri-paper-deep);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  color: var(--ri-ink);
}

/* The receipt: one short document, no navigation of its own beyond the
   shared chrome, and nothing on it that suggests anything was booked. */
.research-instrument .receipt__list {
  list-style: none;
  margin: var(--ri-space-3) 0 0;
  padding: 0;
}

.research-instrument .receipt__list > li {
  padding-block: var(--ri-space-2);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .receipt__list > li:last-child {
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument .receipt__continue {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--ri-space-1);
  margin-top: var(--ri-space-4);
}

@media (min-width: 48rem) {
  .research-instrument .receipt__continue {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ri-space-2);
  }
}

/* ------------------------------------------------------------------ */
/* The Arabic front door                                               */
/* ------------------------------------------------------------------ */
/* /arabic.html carries the system natively right-to-left. Grid and flex
   mirror themselves under dir="rtl"; what cannot mirror by itself is
   written here. Arabic takes Noto Naskh (the same local face the
   preserved Arabic articles load), more leading than Latin, and neither
   uppercase nor letter-spacing, which break joined script. The nav
   anchors on this page are classless — an audit in
   tests/arabic-contact.test.mjs holds their exact bytes — so the link
   treatment is carried by the list. */
.research-instrument[data-ri-arabic] {
  /* Naskh glyphs are wider than Latin. 42ch of Arabic is a reading
     column; 64ch of Naskh is a flipped English measure and the line
     outruns the eye. */
  --ri-measure: 42ch;
  --ri-measure-narrow: 32ch;
  --ri-type-body-line: 1.82;
  --ri-type-lead-line: 1.7;
}

.research-instrument[data-ri-arabic],
.research-instrument[data-ri-arabic] .ri-question,
.research-instrument[data-ri-arabic] .ri-heading,
.research-instrument[data-ri-arabic] .ri-source,
.research-instrument[data-ri-arabic] .ri-action {
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
}

.research-instrument[data-ri-arabic] .ri-body,
.research-instrument[data-ri-arabic] .ri-lead {
  line-height: 1.82;
  max-width: var(--ri-measure);
}

/* Arabic display sizes carry their marks inside the line box. */
.research-instrument[data-ri-arabic] .ri-question { line-height: 1.45; }

.research-instrument[data-ri-arabic] .ri-source,
.research-instrument[data-ri-arabic] .ri-wordmark__line,
.research-instrument[data-ri-arabic] .ri-hero__practice-name {
  letter-spacing: 0;
  text-transform: none;
}

.research-instrument[data-ri-arabic] .ri-nav__list a {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: var(--ri-target);
  padding-block: var(--ri-space-1);
  text-decoration: none;
  color: var(--ri-ink);
  font-weight: 700;
}

.research-instrument[data-ri-arabic] .ri-nav__list a[aria-current] {
  text-decoration: underline;
  text-underline-offset: 6px;
  text-decoration-thickness: 1px;
}

.research-instrument[data-ri-arabic] .ri-nav__list a.ri-action {
  color: var(--ri-paper);
  text-decoration: none;
}

/* The sheet opens from the toggle's start edge: under RTL the toggle sits
   at the visual left, so the sheet anchors left and grows toward the
   page. */
.research-instrument[data-ri-arabic] .ri-menu__sheet {
  right: auto;
  left: 0;
}

/* Parked left, the skip link is scrollable overflow under RTL — the page
   gained 9999px of horizontal scroll. Parked at the inline start it is
   unreachable overflow in both directions. Focus must also clear the
   Latin `left` rule, or the link appears on the physical left while the
   rest of the chrome reads from the right. */
.research-instrument[data-ri-arabic] .ri-skip {
  left: auto;
  right: auto;
  inset-inline-start: -9999px;
}

.research-instrument[data-ri-arabic] .ri-skip:focus,
.research-instrument[data-ri-arabic] .ri-skip:focus-visible {
  left: auto;
  right: auto;
  inset-inline-start: var(--ri-space-1);
  top: var(--ri-space-1);
}

/* The practice mark leads its label from the reading side. */
.research-instrument[data-ri-arabic] .ri-nav__mark {
  margin-right: 0;
  margin-inline-end: var(--ri-space-1);
}

@media (min-width: 64rem) {
  .research-instrument[data-ri-arabic] .ri-nav__list a { font-weight: 400; }
  .research-instrument[data-ri-arabic] .ri-nav__list a.ri-action { font-weight: 700; }
}

/* The Arabic front door's doors stack at every width: the row layout's
   16ch flex-basis squeezes Arabic into ragged half-columns on a phone. */
.research-instrument[data-ri-arabic] .ri-hero__practice {
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

.research-instrument[data-ri-arabic] .ri-hero__practice-situation { flex: 0 1 auto; }

/* The Arabic menu sheet is a full-width reading column on a phone, so
   the destinations keep a real row each rather than packing into a
   dense Latin-width list. Paired with the bar breakpoint above: this is the
   band where the navigation is still a sheet, so it moves with it. */
@media (max-width: 55.99rem) {
  .research-instrument[data-ri-arabic] .ri-nav__list a {
    min-height: 52px;
    padding-block: var(--ri-space-2);
  }
}

.research-instrument .ri-editorial-note {
  display: block;
  margin-top: var(--ri-space-3);
  padding: var(--ri-space-2);
  border: var(--ri-hairline) solid var(--ri-rule);
  border-inline-start: 2px solid var(--ri-ink);
  background: var(--ri-paper-deep);
  color: var(--ri-ink);
  max-width: 64ch;
}

/* The citation bar and its inset follow the reading direction. */
.research-instrument[data-ri-arabic] .ri-source-margin {
  padding-left: 0;
  border-left: 0;
  padding-inline-start: var(--ri-space-2);
  border-inline-start: 2px solid var(--ri-signal, var(--ri-rule));
}

/* Arabic carries no tracking anywhere in the wordmark. */
.research-instrument[data-ri-arabic] .ri-wordmark__name,
.research-instrument[data-ri-arabic] .ri-wordmark__line {
  letter-spacing: 0;
  word-spacing: normal;
  text-transform: none;
}

/* Joined script has no italic. Emphasis is weight, never a synthetic slant. */
.research-instrument[data-ri-arabic] em,
.research-instrument[data-ri-arabic] i {
  font-style: normal;
  font-weight: 600;
}

/* Index labels and folio words are Arabic; their Latin tracking would
   open the joins. Numerals stay isolated so a remaining LTR run does
   not split. Sequential 01 / 02 numbering is a checklist; Arabic pages
   keep named parts only. */
.research-instrument[data-ri-arabic] .ri-index__practice,
.research-instrument[data-ri-arabic] .ri-folio,
.research-instrument[data-ri-arabic] .ri-node__label,
.research-instrument[data-ri-arabic] .ri-account__name,
.research-instrument[data-ri-arabic] .ri-specimen__title,
.research-instrument[data-ri-arabic] .ri-working-margin__label {
  letter-spacing: 0;
  text-transform: none;
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
}

.research-instrument[data-ri-arabic] .ri-folio {
  margin-bottom: var(--ri-space-3);
}

.research-instrument[data-ri-arabic] .ri-folio::after { content: none; }

.research-instrument[data-ri-arabic] .ri-folio__number {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.research-instrument[data-ri-arabic] .ri-index {
  counter-reset: none;
}

.research-instrument[data-ri-arabic] .ri-index > li {
  counter-increment: none;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--ri-space-1) var(--ri-space-3);
  padding-block: var(--ri-space-4);
}

.research-instrument[data-ri-arabic] .ri-index > li::before { content: none; }

.research-instrument[data-ri-arabic] .ri-index__quote,
.research-instrument[data-ri-arabic] .ri-index__practice {
  grid-column: 1;
}

.research-instrument[data-ri-arabic] .ri-index__quote {
  line-height: 1.55;
  max-width: var(--ri-measure);
}

@media (min-width: 64rem) {
  .research-instrument[data-ri-arabic] .ri-index > li {
    grid-template-columns: minmax(0, var(--ri-measure)) minmax(0, 1fr);
  }
  .research-instrument[data-ri-arabic] .ri-index__practice {
    grid-column: 2;
    margin-top: 0.35em;
  }
}

.research-instrument[data-ri-arabic] [dir="ltr"] {
  unicode-bidi: isolate;
  direction: ltr;
}

.research-instrument[data-ri-arabic] time {
  white-space: nowrap;
}

.research-instrument[data-ri-arabic] .ri-index__quote,
.research-instrument[data-ri-arabic] .ri-subheading,
.research-instrument[data-ri-arabic] .ri-close__question {
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
  letter-spacing: 0;
}

/* Practice doors are editorial rows with a start-edge signal, never a
   three-column bento. The shared sheet still has the unused three-column
   leftover; Arabic must not inherit it. */
.research-instrument[data-ri-arabic] .ri-practice-rows,
.research-instrument[data-ri-arabic] .ri-practice-doors {
  display: block;
}

.research-instrument[data-ri-arabic] .ri-practice-door {
  padding-block: var(--ri-space-5);
  padding-inline-start: var(--ri-space-3);
  border-inline-start: 2px solid var(--ri-signal, var(--ri-rule));
  border-inline-end: 0;
  border-right: 0;
}

@media (min-width: 64rem) {
  .research-instrument[data-ri-arabic] .ri-practice-door,
  .research-instrument[data-ri-arabic] .ri-practice-door:first-child,
  .research-instrument[data-ri-arabic] .ri-practice-door:last-child {
    padding-inline-start: var(--ri-space-3);
    padding-inline-end: 0;
    border-inline-end: 0;
    border-right: 0;
  }
}

.research-instrument[data-ri-arabic] .ri-footer,
.research-instrument[data-ri-arabic] .ri-footer__grid,
.research-instrument[data-ri-arabic] .ri-footer__legal {
  text-align: start;
}

.research-instrument[data-ri-arabic] .ri-menu__toggle,
.research-instrument[data-ri-arabic] .ri-nav,
.research-instrument[data-ri-arabic] .ri-header__inner {
  text-align: start;
}

/* Evidence-map and boundary cells already use logical edges in the
   shared sheet; Arabic still needs the state labels to drop tracking. */
.research-instrument[data-ri-arabic] .ri-evidence-map__state,
.research-instrument[data-ri-arabic] .ri-boundary__title,
.research-instrument[data-ri-arabic] .ri-boundary__name,
.research-instrument[data-ri-arabic] .ri-state {
  letter-spacing: 0;
  text-transform: none;
}

.research-instrument[data-ri-arabic] .ri-state[lang="en"] {
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-family: var(--ri-source);
}

/* A long Arabic phrase wraps at spaces, never mid-glyph. */
.research-instrument[data-ri-arabic] h1,
.research-instrument[data-ri-arabic] h2,
.research-instrument[data-ri-arabic] h3,
.research-instrument[data-ri-arabic] h4,
.research-instrument[data-ri-arabic] p,
.research-instrument[data-ri-arabic] li {
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

.research-instrument[data-ri-arabic] {
  overflow-x: clip;
}

html:has(.research-instrument[data-ri-arabic]) {
  overflow-x: clip;
}

.research-instrument[data-ri-arabic] .ri-portrait img,
.research-instrument[data-ri-arabic] .ri-close__portrait img {
  display: block;
  width: min(280px, 100%);
  height: auto;
  border: var(--ri-hairline) solid var(--ri-rule);
}

@media (min-width: 64rem) {
  .research-instrument[data-ri-arabic] .ri-close__portrait,
  .research-instrument[data-ri-arabic] .ri-portrait {
    justify-self: start;
  }
}

/* Generous document air. Naskh needs more leading and more section
   pause than Latin; this is still the system scale, not a second grid. */
.research-instrument[data-ri-arabic] .ri-section {
  padding-block: var(--ri-space-6) var(--ri-space-7);
}

.research-instrument[data-ri-arabic] .ri-section__head {
  margin-bottom: var(--ri-space-5);
}

.research-instrument[data-ri-arabic] .ri-section__head > * + * {
  margin-top: var(--ri-space-3);
}

.research-instrument[data-ri-arabic] .ri-section__head > .ri-folio { margin-top: 0; }

.research-instrument[data-ri-arabic] .ri-follow { margin-top: var(--ri-space-3); }

.research-instrument[data-ri-arabic] .ri-section__head .ri-cluster {
  margin-top: var(--ri-space-4);
}

.research-instrument[data-ri-arabic] .ri-hero__question { max-width: 20ch; }
.research-instrument[data-ri-arabic] .ri-heading { max-width: 22ch; }
.research-instrument[data-ri-arabic] .ri-question { max-width: 20ch; }

.research-instrument[data-ri-arabic] .ri-hero__credential {
  margin-top: var(--ri-space-3);
  max-width: 46ch;
}

/* Home wraps the band in .ri-hero; Arabic wraps the hero in the band.
   Collapse the stacked paddings so the first screen is argument, not
   empty ink. Child inversion lives here so the markup needs no inline
   colour — the same move as the parallel V2.3 polish, scoped to Arabic. */
.research-instrument[data-ri-arabic] .ri-editorial-band {
  --ri-signal-text: var(--ri-paper);
}

.research-instrument[data-ri-arabic] .ri-editorial-band .ri-source,
.research-instrument[data-ri-arabic] .ri-editorial-band .ri-hero__practice,
.research-instrument[data-ri-arabic] .ri-editorial-band .ri-hero__practice-situation {
  color: var(--ri-paper);
}

.research-instrument[data-ri-arabic] .ri-editorial-band .ri-action {
  background: var(--ri-paper);
  color: var(--ri-ink);
  border-color: var(--ri-paper);
}

.research-instrument[data-ri-arabic] .ri-editorial-band .ri-action--secondary {
  background: transparent;
  color: var(--ri-paper);
  border-color: var(--ri-paper);
}

.research-instrument[data-ri-arabic] .ri-hero:has(> .ri-editorial-band),
.research-instrument[data-ri-arabic] .ri-editorial-band > .ri-hero,
.research-instrument[data-ri-arabic] .ri-editorial-band > .ri-section {
  padding-block: 0;
}

.research-instrument[data-ri-arabic][data-ri-practice] .ri-section .ri-section__head {
  padding-inline-start: var(--ri-space-3);
  border-inline-start: 2px solid var(--ri-signal, var(--ri-rule));
}

@media (max-width: 47.99rem) {
  .research-instrument[data-ri-arabic] .ri-section { padding-block: var(--ri-space-5); }
  .research-instrument[data-ri-arabic] .ri-editorial-band { padding-block: var(--ri-space-5); }
}

/* Dual-script identity stamp. Latin lives in main, never in chrome,
   so the Arabic header/footer audit still holds one English switch. */
.research-instrument[data-ri-arabic] .ri-provenance-band {
  padding-block: var(--ri-space-3) 0;
}

.research-instrument[data-ri-arabic] .site-provenance {
  margin: 0;
  padding-bottom: var(--ri-space-3);
  border-bottom: var(--ri-hairline) solid var(--ri-rule);
  max-width: var(--ri-measure);
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
  font-size: var(--ri-type-meta);
  line-height: 1.7;
  color: var(--ri-graphite);
  letter-spacing: 0;
  text-transform: none;
}

.research-instrument[data-ri-arabic] .site-provenance__kind {
  display: block;
  margin-top: var(--ri-space-1);
}

/* The five moves are a reading column with a start-edge rail, not a
   flipped five-column Latin grid. Naskh cannot sit in five 12ch cells. */
.research-instrument[data-ri-arabic] .ri-method {
  max-width: var(--ri-measure);
  grid-template-columns: minmax(0, 1fr);
}

.research-instrument[data-ri-arabic] .ri-method > li {
  padding-left: 0;
  border-left: 0;
  padding-inline-start: var(--ri-space-3);
  border-inline-start: 2px solid var(--ri-rule);
}

.research-instrument[data-ri-arabic] .ri-method > li[data-ri-node="decision"] {
  border-left-color: transparent;
  border-inline-start-color: var(--ri-ink);
}

.research-instrument[data-ri-arabic] .ri-method__step {
  letter-spacing: 0;
  text-transform: none;
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
}

.research-instrument[data-ri-arabic] .ri-method__name {
  font-family: "Noto Naskh Arabic", "Geeza Pro", serif;
  letter-spacing: 0;
}

@media (min-width: 64rem) {
  .research-instrument[data-ri-arabic] .ri-method {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    max-width: var(--ri-measure);
  }

  .research-instrument[data-ri-arabic] .ri-method > li {
    padding-left: 0;
    padding-top: var(--ri-space-3);
    border-left: 0;
    border-top: 0;
    padding-inline-start: var(--ri-space-3);
    border-inline-start: 2px solid var(--ri-rule);
  }

  .research-instrument[data-ri-arabic] .ri-method > li[data-ri-node="decision"] {
    border-left-color: transparent;
    border-top-color: transparent;
    border-inline-start-color: var(--ri-ink);
  }
}

.research-instrument[data-ri-arabic] .ri-panel .ri-body,
.research-instrument[data-ri-arabic] .ri-panel .ri-source-margin {
  margin-top: var(--ri-space-2);
}

.research-instrument[data-ri-arabic][data-ri-methods] .ri-methods-open {
  padding-block: var(--ri-space-4) var(--ri-space-5);
}

.research-instrument[data-ri-arabic][data-ri-methods] .ri-methods-open .ri-section__head {
  margin-bottom: var(--ri-space-3);
}

.research-instrument[data-ri-arabic][data-ri-methods] .ri-methods-open .ri-method {
  margin-top: var(--ri-space-3);
}

/* ------------------------------------------------------------------ */
/* The legal pair                                                      */
/* ------------------------------------------------------------------ */
/* /privacy.html and /terms.html keep their wording byte for byte; the
   sheet owns their presentation. The container classes are the pages'
   own, styled here in the system's voice: one reading column, Newsreader
   headings over hairline rules, and links in ink. */
.research-instrument[data-ri-legal] .container {
  max-width: 680px;
  padding-block: var(--ri-space-4) var(--ri-space-6);
}

.research-instrument[data-ri-legal] .back {
  display: inline-flex;
  align-items: center;
  min-height: var(--ri-target);
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ri-graphite);
  text-decoration: none;
}

.research-instrument[data-ri-legal] .back:hover { text-decoration: underline; }

.research-instrument[data-ri-legal] h1 {
  font-family: var(--ri-question);
  font-weight: 400;
  font-size: var(--ri-type-h2);
  line-height: 1.2;
  margin-top: var(--ri-space-2);
}

.research-instrument[data-ri-legal] .updated {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  color: var(--ri-graphite);
  margin: var(--ri-space-1) 0 var(--ri-space-4);
}

.research-instrument[data-ri-legal] h2 {
  font-family: var(--ri-question);
  font-weight: 400;
  font-size: calc(var(--ri-type-body) * 1.35);
  line-height: 1.25;
  margin: var(--ri-space-4) 0 var(--ri-space-1);
  padding-top: var(--ri-space-3);
  border-top: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument[data-ri-legal] p,
.research-instrument[data-ri-legal] li {
  max-width: 62ch;
  font-size: var(--ri-type-body);
  line-height: var(--ri-type-body-line);
}

.research-instrument[data-ri-legal] p + p { margin-top: var(--ri-space-1) }

.research-instrument[data-ri-legal] ul {
  margin: var(--ri-space-1) 0 var(--ri-space-2);
  padding-left: 20px;
}

.research-instrument[data-ri-legal] li { margin-top: 6px; }

.research-instrument[data-ri-legal] a {
  color: var(--ri-signal-text, var(--ri-ink));
  text-underline-offset: 2px;
}

/* The legal chrome's nav anchors are classless — a boundary test holds
   their exact bytes — so the link treatment is carried by the lists. */
.research-instrument[data-ri-legal] .ri-nav__list a {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: var(--ri-target);
  padding-block: var(--ri-space-1);
  text-decoration: none;
  color: var(--ri-ink);
  font-weight: 700;
}

@media (min-width: 64rem) {
  .research-instrument[data-ri-legal] .ri-nav__list a { font-weight: 400; }
}

/* ================================================================== */
/* Homepage breadth release                                            */
/* ================================================================== */
/* Every rule below is scoped to .research-instrument[data-ri-home],
   which only the English homepage body carries. Nothing here can reach
   a practice page, the Arabic front door, or any other consumer of the
   shared hero hooks. */

.research-instrument[data-ri-home] .ri-hero__question {
  font-size: clamp(40px, 2.4rem + 2.6vw, 64px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

.research-instrument[data-ri-home] .ri-hero__practice-caption {
  display: block;
  flex: 1 1 100%;
  min-width: 0;
  font-family: var(--ri-source);
  font-size: 12px;
  font-weight: 400;
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.research-instrument[data-ri-home] .ri-editorial-band .ri-hero__practice-caption {
  color: var(--ri-paper);
}

.research-instrument[data-ri-home] .ri-hero__practice-situation {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}

.research-instrument[data-ri-home] .ri-hero__practices .ri-practice-door {
  padding: 0;
  border-bottom: 0;
  border-inline-start: 0;
}

.research-instrument[data-ri-home] .ri-hero__practices .ri-practice-door > * + * {
  margin-top: 0;
}

.research-instrument[data-ri-home] .ri-hero__practices .ri-practice-door:hover {
  background: transparent;
}

.research-instrument[data-ri-home] .ri-hero__practices .ri-practice-door:focus-within {
  outline: none;
}

.research-instrument[data-ri-home] .ri-hero__practice:hover {
  background-color: color-mix(in srgb, var(--ri-paper) 12%, transparent);
}

@media (prefers-reduced-motion: no-preference) {
  .research-instrument[data-ri-home] .ri-hero__practice {
    transition: color var(--ri-motion-ui) var(--ri-ease),
                background-color var(--ri-motion-ui) var(--ri-ease),
                border-color var(--ri-motion-ui) var(--ri-ease);
  }
}

.research-instrument[data-ri-home] .ri-hero__register {
  min-inline-size: 0;
  max-inline-size: 100%;
  margin-block-start: var(--ri-space-4);
}

.research-instrument[data-ri-home] .ri-hero__register-list {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 0;
  list-style: none;
  margin: 0;
  padding-block: 0.375rem;
  padding-inline: 0;
  min-inline-size: 0;
  max-inline-size: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x proximity;
  scroll-padding-inline-start: 0.75rem;
  scroll-padding-inline-end: 30%;
  border-block-start: var(--ri-hairline) solid var(--ri-rule);
  border-block-end: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument[data-ri-home] .ri-hero__register-list > li {
  flex: 0 0 78%;
  min-inline-size: 0;
  scroll-snap-align: start;
  scroll-margin-inline: 0.75rem;
  border-inline-end: var(--ri-hairline) solid var(--ri-rule);
}

@media (min-width: 48rem) {
  .research-instrument[data-ri-home] .ri-hero__register-list > li {
    flex: 0 0 44%;
  }
}

@media (min-width: 90rem) {
  .research-instrument[data-ri-home] .ri-hero__register-list > li {
    flex: 0 0 36%;
  }
}

.research-instrument[data-ri-home] .ri-hero__register-link {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--ri-space-1);
  min-height: var(--ri-target);
  min-inline-size: 0;
  padding-block: var(--ri-space-2);
  padding-inline: var(--ri-space-2);
  text-decoration: none;
  color: inherit;
}

.research-instrument[data-ri-home] .ri-hero__register-link:focus-visible {
  outline-offset: -3px;
}

.research-instrument[data-ri-home] .ri-hero__register-index {
  font-family: var(--ri-source);
  font-size: 12px;
  font-weight: 400;
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.research-instrument[data-ri-home] .ri-hero__register-body {
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  max-inline-size: 36ch;
}

.research-instrument[data-ri-home] .ri-editorial-band .ri-hero__register-link,
.research-instrument[data-ri-home] .ri-editorial-band .ri-hero__register-index,
.research-instrument[data-ri-home] .ri-editorial-band .ri-hero__register-body {
  color: var(--ri-paper);
}

@media (prefers-reduced-motion: no-preference) {
  .research-instrument[data-ri-home] .ri-hero__register-link {
    transition: color var(--ri-motion-ui) var(--ri-ease),
                background-color var(--ri-motion-ui) var(--ri-ease),
                border-color var(--ri-motion-ui) var(--ri-ease);
  }
}

.research-instrument[data-ri-home] .ri-hero__register-link:hover {
  background-color: color-mix(in srgb, var(--ri-paper) 12%, transparent);
}

.research-instrument[data-ri-home] .ri-proof {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--ri-gap);
}

.research-instrument[data-ri-home] .ri-proof > * { min-width: 0; }

@media (min-width: 64rem) {
  .research-instrument[data-ri-home] .ri-proof {
    grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
    column-gap: clamp(40px, 6vw, 96px);
    align-items: start;
  }
}

@media (min-width: 90rem) {
  .research-instrument[data-ri-home] .ri-proof {
    grid-template-columns: minmax(0, 1fr);
  }
}

.research-instrument[data-ri-home] .ri-proof .ri-canvas {
  margin-top: 0;
  background: var(--ri-paper);
  border: var(--ri-hairline) solid var(--ri-rule);
  border-inline-start: 2px solid var(--ri-business-mark);
  padding: var(--ri-space-4);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--ri-ink) 8%, transparent);
}

@media (max-width: 48rem) {
  .research-instrument[data-ri-home] .ri-proof .ri-canvas { padding: var(--ri-space-3); }
}

.research-instrument[data-ri-home] .ri-proof__intro {
  display: flex;
  flex-direction: column;
  gap: var(--ri-space-2);
  padding-block-end: var(--ri-space-3);
  border-block-end: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument[data-ri-home] .ri-proof__intro .ri-heading {
  max-width: 22ch;
}

.research-instrument[data-ri-home] .ri-proof__intro .ri-lead {
  max-width: 58ch;
}

.research-instrument[data-ri-home] .ri-proof__register {
  margin: 0;
  overflow-x: visible;
}

.research-instrument[data-ri-home] .ri-proof__register-head {
  display: none;
}

.research-instrument[data-ri-home] .ri-proof__register-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-x: visible;
}

.research-instrument[data-ri-home] .ri-proof__register-list > li {
  margin: 0;
  padding-block: var(--ri-space-3);
  border-block-end: var(--ri-hairline) solid var(--ri-rule);
}

.research-instrument[data-ri-home] .ri-proof__register-list > li:last-child {
  border-block-end: 0;
}

.research-instrument[data-ri-home] .ri-proof__lane {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--ri-ink);
  margin: 0 0 var(--ri-space-2);
}

.research-instrument[data-ri-home] .ri-proof__index {
  font-family: var(--ri-source);
  font-variant-numeric: tabular-nums;
}

.research-instrument[data-ri-home] .ri-proof__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--ri-space-2);
  min-width: 0;
}

.research-instrument[data-ri-home] .ri-proof__cell {
  min-width: 0;
}

.research-instrument[data-ri-home] .ri-proof__cell[data-ri-col="work"] {
  padding-inline-start: var(--ri-space-2);
  border-inline-start: 2px solid var(--ri-rule);
}

.research-instrument[data-ri-home] .ri-proof__cell[data-ri-col="return"] {
  padding-inline-start: var(--ri-space-2);
  border-inline-start: 2px solid var(--ri-business-mark);
}

.research-instrument[data-ri-home] .ri-proof__col {
  font-family: var(--ri-source);
  font-size: var(--ri-type-meta);
  line-height: var(--ri-type-meta-line);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ri-graphite);
}

.research-instrument[data-ri-home] .ri-proof__cell .ri-body {
  margin-top: var(--ri-space-1);
  max-width: 46ch;
  overflow-wrap: break-word;
}

.research-instrument[data-ri-home] .ri-proof__mark {
  display: none;
}

.research-instrument[data-ri-home] .ri-proof__boundary {
  margin-block-start: var(--ri-space-2);
}

.research-instrument[data-ri-home] .ri-proof__exit {
  margin: var(--ri-space-3) 0 0;
}

.research-instrument[data-ri-home] .ri-proof__exit .ri-link {
  min-height: var(--ri-target);
}

.research-instrument[data-ri-home] .ri-proof__support .ri-source--label {
  margin: 0;
}

.research-instrument[data-ri-home] .ri-proof__facts {
  list-style: none;
  margin: var(--ri-space-2) 0 0;
  padding: 0;
}

.research-instrument[data-ri-home] .ri-proof__facts > li {
  margin: 0;
  padding-block: var(--ri-space-2);
  border-block-start: var(--ri-hairline) solid var(--ri-rule);
  max-width: 44ch;
}

@media (min-width: 90rem) {
  .research-instrument[data-ri-home] .ri-proof__register-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 16px minmax(0, 1fr) 16px minmax(0, 1fr);
    column-gap: var(--ri-space-2);
    align-items: center;
    padding-block: var(--ri-space-2);
    margin-block-start: var(--ri-space-2);
    border-block-end: var(--ri-hairline) solid var(--ri-rule);
  }

  .research-instrument[data-ri-home] .ri-proof__row {
    grid-template-columns: minmax(0, 1fr) 16px minmax(0, 1fr) 16px minmax(0, 1fr);
    align-items: start;
    column-gap: var(--ri-space-2);
  }

  .research-instrument[data-ri-home] .ri-proof__cell[data-ri-col="work"],
  .research-instrument[data-ri-home] .ri-proof__cell[data-ri-col="return"] {
    padding-inline-start: 0;
    border-inline-start: 0;
  }

  .research-instrument[data-ri-home] .ri-proof__cell .ri-proof__col {
    display: none;
  }

  .research-instrument[data-ri-home] .ri-proof__cell .ri-body {
    margin-top: 0;
  }

  .research-instrument[data-ri-home] .ri-proof__mark {
    display: block;
    align-self: center;
    width: 100%;
    height: var(--ri-hairline);
    background: var(--ri-rule);
    position: relative;
  }

  .research-instrument[data-ri-home] .ri-proof__mark::after {
    content: "";
    position: absolute;
    inset-inline-end: 0;
    top: 50%;
    width: 5px;
    height: 5px;
    margin-top: -2px;
    background: var(--ri-business-mark);
  }
}

.research-instrument[data-ri-home] .ri-footer { margin-top: 0; }

@media (max-width: 30rem) {
  .research-instrument[data-ri-home] .ri-editorial-band { padding-block: var(--ri-space-3) var(--ri-space-5); }
  .research-instrument[data-ri-home] .ri-hero__lead { margin-top: var(--ri-space-2); }
  .research-instrument[data-ri-home] .ri-hero__actions { margin-top: var(--ri-space-2); }
  .research-instrument[data-ri-home] .ri-hero__practices { margin-top: var(--ri-space-1); }
  .research-instrument[data-ri-home] .ri-hero__practice-caption { line-height: 1; }
}
