/* =============================================================================
   site.css — THE SHELL. The masthead, the four strata, the datum bars, the
   register of publications and the colophon: everything the site pages
   (/ and /research) are made of.

   WHERE THIS CAME FROM. It is the inline <style> of
   mockups/direction-b-institution.html — the approved design — lifted out of
   that file and made into a real stylesheet, with the authored reasoning kept
   because it is the record of why the non-obvious parts are the way they are.
   The register of publications is direction-c-research.html's §4, which is the
   same file's index view.

   Two files sit under this one and this file declares neither of the things
   they own:

     identity/tokens.css   every colour, the two grounds and the dark register,
                           the accent and its three permissions, the type
                           spine, --shell / --gutter / --radius / --hairline
                           and the shared type scale.
     research/research.css the paper pattern library (.rp-*). NOT loaded by a
                           shell page — a shell page is not an article.

   Same law as research.css: NO colour and NO font-family is declared literally
   here. Every value is a var() into the token substrate, and build/test.mjs
   asserts it by stripping the comments and looking for a hex.

   NO MONOSPACE. Standing house rule.

   -----------------------------------------------------------------------------
   THE SHELL GRAMMAR, in four moves. Everything below is one of them:

     1. THE GROUND RUNS THE PAGE.  It is not a margin. It runs full width above
        and below every plate, and it is what you see between strata.
     2. A DATUM BAR OPENS EACH STRATUM.  Full-bleed, two hairlines, carrying an
        index and a label: `01 ——————— Our claims`. It belongs to the binding,
        not to the document, so it sits on bare ground.
     3. A PLATE IS DRAWN BY ITS TWO VERTICAL HAIRLINES.  Not by a fill and not
        by a shadow — the plate is the same colour as the ground and it is the
        two rules down its sides that make it a surface. Inganci carried three
        switchable constructions of this (a registered plate, a line drawing, a
        floated card); The Pingback ships the line drawing and only that.
     4. THE COLOPHON SIGNS THE HOUSE.  Wordmark, one line of signature, the
        channels, and a rule with the copyright under it.

   THE FOUR STRATA, and they are a spine rather than four positions:

        01  Our claims        what the institution asserts
        02  Our grounds       what entitles it to assert them
        03  The instruments   what it makes
        04  Our channels      where to find it

   -----------------------------------------------------------------------------
   STRIPPED IN THE PORT, and each was Inganci's or SCOUTSWING's rather than
   this institution's:

     .nav-cta         a filled block in the masthead carrying the SCOUTSWING
                      wordmark out to the product. There is no sibling product
                      to leave for here, and the CTA was styled for that one
                      locked all-caps name specifically. Gone, along with
                      .nav-cta-text and its narrow-screen full-width variant.
     the three-ground construction switch (cool / white / grey) and its six
                      aliases. One construction now, stated directly.
     the [data-type] pairing block. The type question is closed and both faces
                      live in identity/tokens.css, where a typeface belongs.
     .register / .register-head / .register-body / .opening-grid, the
                      two-column title plate with a spine rule. Direction B's
                      opening is an h1 on the ground with the prose set against
                      a rule in the right-hand track; the spine survives as
                      .prose's own left border.
     the honest-blank register and its Pending chip. Nothing on a surface here
                      is drawn as absent, forthcoming or in build.
   ============================================================================= */

/* ============================================================================
   §1  THE SHELL'S OWN DIAL — roles, not literals. Sizes come from tokens.css
   because they are the institution's voice; the weights, tracking and leading
   are dialled here because a masthead and a paper are different objects.

   Two laws hold whatever the face, because they belong to the institution and
   not to the drawing: the display register is SENTENCE CASE, and the wordmark
   and micro-labels are CAPS.
   ========================================================================= */

:root {
  --w-display:   600;
  --tr-display:  -0.032em;
  --lh-display:  0.98;

  --w-section:   600;
  --tr-section:  -0.018em;
  --lh-section:  1.16;

  --tr-sub:      -0.012em;
  --lh-prose:    1.52;
  --lh-body:     1.6;

  --w-semi:      600;
  --w-bold:      600;
  --w-label:     500;
  --w-mark:      700;

  --track-link:  0.06em;

  /* the drawn arrows' stroke, in viewBox units of 16. A TYPE token, not a
     geometry one: the arrow has to hold the stem weight of the label beside
     it. 1.6 renders ~1.1px at an 11px label. */
  --arrow-w:     1.6;

  --spine:       clamp(22px, 2.4vw, 34px);
}

/* ============================================================================
   §2  RESET AND SHELL
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-prose);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 280ms ease, color 280ms ease;
}

h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; }
a { color: inherit; }

main { flex: 1 0 auto; }

/* -- the two containers, and they are the whole layout -----------------------
   .hold  content sitting directly on the GROUND (masthead, datum bars, the
          colophon's interior)
   .plate content on a SURFACE — and the surface is drawn by its two vertical
          hairlines rather than by a fill, which is why .plate takes no
          background at all. */
.hold {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.plate {
  max-width: var(--shell);
  margin-inline: auto;
  padding: clamp(44px, 5.4vw, 80px) var(--gutter) clamp(52px, 6.4vw, 96px);
  border-left: var(--hairline) solid var(--hair);
  border-right: var(--hairline) solid var(--hair);
}

/* the micro-register, and it is one class because it is one voice */
.lab {
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: var(--w-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--dim);
  line-height: 1;
}

/* THE FOCUS RING. There was none — `:focus-visible` appeared once on the live
   site and only to REMOVE an outline, so the page had no keyboard indicator at
   all. Gold is legal here and it is the clearest case in the whole system: a
   ring is a RULE, and --warrant's 3.10:1 clears WCAG 1.4.11's 3:1 floor for
   non-text UI components. The a11y fix and the accent system are one edit.

   Inside a dark region tokens.css re-points --warrant at --band-warrant, so
   the ring lifts with the ground and no second rule is needed. .nav-panel is
   the one dark surface that is not a `.band`, so it re-points locally. */
:focus-visible {
  outline: 2px solid var(--warrant);
  outline-offset: 3px;
}

.skip {
  position: absolute; left: 12px; top: -80px; z-index: 60;
  background: var(--ink); color: var(--ground);
  font-family: var(--font-label); font-size: var(--t-label);
  font-weight: var(--w-label); letter-spacing: var(--track-label);
  text-transform: uppercase;
  padding: 10px 14px; text-decoration: none; border-radius: var(--radius);
  transition: top 120ms linear;
}
.skip:focus { top: 12px; }

/* -- drawn arrows -----------------------------------------------------------
   Not a typographic arrow anywhere on this site. U+2197 and U+2192 were probed
   against every face in the type audit and NOT ONE carries either glyph: every
   arrow was falling through to whatever the system offered — a symbol font on
   macOS, colour emoji on iPhone. A variation selector cannot fix it, because
   there is no glyph in the family to select the presentation of.

   So they are drawn, from one sprite emitted into every page. `stroke-width`
   is set HERE and not as a presentation attribute on the path: an attribute
   would beat inheritance and freeze the weight; declared in CSS it inherits
   through the <use> shadow tree and stays a type token. */
.a,
.arrow {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: -0.15em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--arrow-w);
}

/* ============================================================================
   §3  THE DATUM BARS — full-bleed, carrying an index and a label.
   ========================================================================= */

.datum {
  border-top: var(--hairline) solid var(--hair-strong);
  border-bottom: var(--hairline) solid var(--hair-strong);
  padding: 9px 0;
}
.datum .hold {
  display: flex;
  align-items: center;
  gap: 16px;
}
.datum .idx {
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ink);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.datum .run {
  flex: 1;
  height: var(--hairline);
  background: var(--hair);
}

/* THE GOLD ON THE DATUMS IS SPENT HERE, ONCE, and it is a RULE — it marks the
   top of the record. On all four bars it would be wallpaper; on one it is a
   mark. The gradient is a hard stop rather than a fade: this is a rule that
   changes colour at a measured point, not a decoration that trails off. */
.datum[data-warrant] .run {
  background: linear-gradient(to right, var(--warrant) 0 84px, var(--hair) 84px);
}

/* ============================================================================
   §4  THE MASTHEAD

   Pixar's nav, and the borrowed move is precise: FILMS and TECHNOLOGY as
   peers, each dropdown listing that arm's own work. Publications and
   Technology are the same two peers here, and the nav states the reciprocity
   structurally before a word of copy argues it.
   ========================================================================= */

.masthead {
  position: relative;
  z-index: 40;
}
.masthead .hold {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 24px;
  padding-bottom: 24px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  text-decoration: none;
  color: inherit;
}
.mark {
  width: var(--mark-size);
  height: auto;
  fill: var(--ink);
}
/* the weight-contrast lockup the publication already sets: a light article
   against a bold name. It is the publication's signature, and the institution
   keeps it rather than inventing a second one. */
.wordmark {
  font-family: var(--font-mark);
  font-size: 19px;
  font-weight: var(--w-mark);
  letter-spacing: var(--tr-mark);
  line-height: 1;
}
.wordmark .the {
  font-weight: 300;
  color: var(--ink-soft);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 4px;
}
.nav-item { position: relative; }
.nav-trigger,
.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 13px;
  cursor: pointer;
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: var(--w-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  line-height: 1;
}
.nav-trigger .caret {
  width: 7px; height: 7px;
  stroke: currentColor; stroke-width: 1.7; fill: none;
  opacity: 0.5;
  transition: transform 160ms ease;
}
.nav-trigger[aria-expanded="true"] .caret { transform: rotate(180deg); opacity: 1; }

/* the hover rule, and gold's second placement in the shell. It is drawn UNDER
   the label rather than on it: the characters stay --ink. */
.nav-trigger::after,
.nav-link::after {
  content: "";
  position: absolute;
  left: 13px; right: 13px; bottom: 4px;
  height: var(--hairline);
  background: var(--warrant);
  transform: scaleX(0);
  transition: transform 180ms ease;
}
.nav-trigger:hover::after,
.nav-link:hover::after,
.nav-link[aria-current]::after,
.nav-trigger[aria-expanded="true"]::after { transform: scaleX(1); }

/* Pixar's panel: a dark slab dropped below the item, all-caps, generously
   leaded. It lists what exists and nothing else — no thesis row, because
   naming a thesis page before the work exists announces an absence.

   --band, not --ink. --ink inverts with the register, so a dark-register page
   would render this panel near-WHITE with --on-band-dim text on it. The panel
   is a place, the way the band is, and it holds its ground in both registers.
   Re-pointing the accent locally is what lets the focus ring inside it lift
   without a second selector. */
.nav-panel {
  --warrant: var(--band-warrant);
  --warrant-text: var(--band-warrant);
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 238px;
  background: var(--band);
  padding: 18px 22px 20px;
  box-shadow: 0 10px 30px color-mix(in srgb, var(--band) 18%, transparent);
}
.nav-panel[hidden] { display: none; }
.nav-panel ul { display: grid; gap: 13px; }
.nav-panel a {
  display: block;
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: var(--w-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--on-band-dim);
  text-decoration: none;
  transition: color 140ms ease;
}
.nav-panel a:hover,
.nav-panel a:focus-visible { color: var(--on-band); }

/* the outbound tick. It is the whole reason a nav item may leave the domain:
   it is not silent. */
.nav-panel .ext {
  width: 8px; height: 8px;
  stroke: currentColor; stroke-width: 1.7; fill: none;
  display: inline-block; vertical-align: baseline;
  margin-left: 5px; opacity: 0.7;
}

/* -- the narrow-screen toggle -----------------------------------------------
   A hairline ring rather than a filled block: the masthead has no filled
   object left in it, and the toggle should not become the first one.

   Hidden at every width by default. Only [data-menu] plus the narrow media
   query bring it in, which is what keeps the no-JavaScript path honest —
   absent the attribute the nav renders as an open list and nothing is behind a
   control that cannot be operated. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;                 /* the 44px touch target, not a coincidence */
  height: 44px;
  margin-left: auto;
  padding: 0;
  border: var(--hairline) solid var(--hair-strong);
  border-radius: 999px;
  color: var(--ink);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Two bars that become a cross. One element and its ::before/::after, animated
   on the button's OWN aria-expanded — so the DOM state and the drawn state
   cannot disagree, which they can when an icon is swapped by script. */
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 17px;
  height: 1.5px;
  background: currentColor;
  transition: transform 180ms ease, opacity 120ms ease;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before,
.nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle__bars::before { top: -5px; }
.nav-toggle__bars::after  { top:  5px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: translateY(-5px) rotate(-45deg); }

/* ============================================================================
   §5  STRATUM 01 — OUR CLAIMS
   ========================================================================= */

h1 {
  font-family: var(--font-display);
  font-size: var(--t-display);
  font-weight: var(--w-display);
  letter-spacing: var(--tr-display);
  line-height: var(--lh-display);
  color: var(--ink);
  max-width: 15ch;
}

.opening-body {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: clamp(32px, 5vw, 72px);
  margin-top: clamp(48px, 6vw, 88px);
  align-items: start;
}

/* the spine. The paragraphs hang off a rule the way every stratum hangs off
   its datum, so 01 is set IN the register rather than above it. */
.prose {
  border-left: var(--hairline) solid var(--hair-strong);
  padding-left: var(--spine);
  max-width: var(--measure);
}
.prose p {
  margin: 0 0 1.15em;
  font-size: calc(var(--t-lede) * 1.14);
  line-height: var(--lh-prose);
  color: var(--ink-soft);
}
/* the closing paragraph takes --ink where the ones above take --ink-soft: the
   mission is the line the block is built to land on. */
.prose p:last-child { margin-bottom: 0; color: var(--ink); }
.prose strong { font-weight: var(--w-bold); color: var(--ink); }
.prose a {
  text-decoration: none;
  border-bottom: var(--hairline) solid var(--hair-strong);
  padding-bottom: 1px;
  transition: border-color 120ms linear;
}
.prose a:hover { border-bottom-color: var(--warrant); }

/* ============================================================================
   §6  STRATUM 02 — OUR GROUNDS

   Full-bleed dark, a centred thesis, peripheral questions on hairlines. One
   difference from the reference, and it is the improvement: THE FIELD IS THE
   SUBSTRATE THE QUESTIONS ARE SUSPENDED IN, rather than flat black behind a
   constellation of pictures. The drawing is a LINK GRAPH — questions joined by
   hairlines — which is the mark's own logic and the word's literal meaning.

   The band is dark in BOTH registers. It is not a theme surface; it is a
   place. tokens.css re-points the accent inside it, so gold here is the lifted
   value and may — uniquely — touch a letterform.
   ========================================================================= */

.band {
  position: relative;
  background: var(--band);
  color: var(--on-band);
  overflow: hidden;
  isolation: isolate;
}
.band canvas,
.band .band-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* the fallback IS the design when WebGL2 is missing, not a blank. Mixed from
   --on-band into --band rather than written as two literals, so it moves with
   the band if the band ever moves. */
.band .band-fallback {
  background:
    radial-gradient(120% 90% at 22% 18%,
      color-mix(in srgb, var(--on-band) 7%, var(--band)) 0%, transparent 58%),
    radial-gradient(100% 80% at 82% 74%,
      color-mix(in srgb, var(--on-band) 4%, var(--band)) 0%, transparent 60%),
    var(--band);
}
.band-inner {
  position: relative;
  z-index: 3;
  min-height: clamp(560px, 72vh, 760px);
  display: grid;
  place-items: center;
  padding: clamp(56px, 7vw, 96px) var(--gutter);
}
/* the field holds the constellation to a measure. Without it the questions
   track the viewport and, past ~1600px, strand themselves at the edges with a
   dead middle. The plates are held; so is this. */
.band-field {
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 1440px;
  z-index: 1;
  pointer-events: none;
}
.band-field a { pointer-events: auto; }
.band-graph { position: absolute; inset: 0; }
/* a hair stronger than --on-band-hair: these lines cross a moving halftone
   field, not a flat ground, and 0.16 disappears into it. */
.band-graph line {
  stroke: color-mix(in srgb, var(--on-band) 24%, transparent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.q {
  position: absolute;
  z-index: 2;
  /* EXPLICIT width, not max-width. These are placed with `left:%` and pulled
     back by translate(-100%) — but the transform is visual only, so a node at
     left:93% is LAID OUT in the remaining 7% and a max-width can never widen
     it. One question was wrapping to six lines because of exactly this. */
  width: 26ch;
  max-width: 34vw;
  font-family: var(--font-prose);
  font-size: clamp(16px, 1.32vw, 20px);
  line-height: 1.36;
  color: var(--on-band-q);
  display: flex;
  align-items: baseline;
  gap: 9px;
}
.q .node,
.q-list .node {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--on-band-q);
  flex: none;
  transform: translateY(-3px);
}
.q.right { flex-direction: row-reverse; text-align: right; }
.q-b { display: block; text-decoration: none; color: inherit; }
.q-t { display: block; }
/* the wall label. Small, dim, and the whole point. */
.q-c {
  display: inline-block;
  margin-top: 5px;
  font-family: var(--font-label);
  font-size: 9.5px;
  font-weight: var(--w-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* A BAND TOKEN, not --dim or --mid. The band is always #101010, but --dim and
     --mid follow the REGISTER — so either one is legible here in light and then
     collapses when the page is switched to dark (--mid drops to 3.57:1, --dim to
     ~3.1:1) while the ground underneath has not moved at all. --on-band-dim is
     scoped to the band and is 5.79:1 in both registers. */
  color: var(--on-band-dim);
  border-bottom: var(--hairline) solid transparent;
  padding-bottom: 1px;
  transition: color 150ms ease, border-color 150ms ease;
}
/* gold's one appearance in the band, and it is BEHAVIOUR rather than
   decoration. On this ground the lifted value measures 7.90:1, so here — and
   only here — it is allowed to touch the letters. It still does not: it is the
   underline that takes it. */
a.q-b:hover .q-t {
  color: var(--on-band);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--band-warrant);
}
a.q-b:hover .q-c { color: var(--on-band); border-bottom-color: var(--on-band-hair); }
.q-list .q-b { flex: 1; }
.q-list .q-c { margin-top: 4px; }

.band-centre {
  position: relative;
  z-index: 3;
  text-align: center;
  /* NOT `ch` — this box inherits the body size while its h2 sets 42px, so a ch
     measure here clamps the thesis to a third of its intended width. */
  max-width: min(660px, 84vw);
  padding: clamp(22px, 3vw, 40px) clamp(24px, 3vw, 44px);
}
/* a scrim, so the thesis holds against whatever the field is doing under it */
.band-centre::before {
  content: "";
  position: absolute;
  inset: -14% -22%;
  z-index: -1;
  background: radial-gradient(60% 58% at 50% 50%,
    color-mix(in srgb, var(--band) 94%, transparent) 0%,
    color-mix(in srgb, var(--band) 78%, transparent) 46%,
    transparent 78%);
}
.band-centre h2 {
  margin: 0 0 14px;
  font-family: var(--font-prose);
  font-weight: 400;
  font-size: clamp(26px, 3.1vw, 42px);
  line-height: 1.14;
  letter-spacing: -0.012em;
  color: var(--on-band);
  text-wrap: balance;   /* it was breaking to a two-word last line */
}
.band-centre p {
  margin: 0 auto 22px;
  max-width: 44ch;
  font-size: clamp(14.5px, 1.12vw, 16.5px);
  line-height: 1.55;
  color: var(--on-band-dim);
  text-wrap: balance;
}
.band-centre .pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px;
  border: var(--hairline) solid var(--on-band-hair);
  border-radius: 100px;
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: var(--w-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--on-band);
  text-decoration: none;
  transition: border-color 180ms ease, background-color 180ms ease;
}
.band-centre .pill:hover {
  border-color: color-mix(in srgb, var(--on-band) 45%, transparent);
  background: color-mix(in srgb, var(--on-band) 5%, transparent);
}

/* the stacked read, for narrow and for print */
.q-list {
  display: none;
  position: relative;
  z-index: 2;
  margin: 40px 0 0;
  width: 100%;
  max-width: 34ch;
}
.q-list li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 11px 0;
  border-top: var(--hairline) solid var(--on-band-hair);
  font-family: var(--font-prose);
  font-size: 17px;
  line-height: 1.36;
  color: var(--on-band-q);
}

/* ============================================================================
   §7  STRATUM 03 — THE INSTRUMENTS

   Each arm is the other's proving ground, and it is STATED BY STRUCTURE rather
   than by a lead paragraph: two peers, each showing its own work.

   CONSEQUENCE, AND IT IS A RULE. "Instruments" means everything the institution
   makes, a paper included — so the word may appear exactly ONCE on the page.
   Each arm therefore names the FORMS its work takes and never repeats its own
   heading back at itself.
   ========================================================================= */

/* ⚠ THE DIVIDER IS A RULE CENTRED IN THE GRID GAP, NOT PADDING ON THE SECOND
   ARM. Padding is taken out of that arm's own 1fr track, so with padding the
   second arm was ~72px narrower than the first — and nothing revealed it while
   one arm held a single full-width card. The moment both arms went two-up, the
   two "identical" cards measured 268px and 231px. With two equal tracks,
   left:50% lands exactly in the centre of the gap and the arms are peers in
   fact as well as in argument. Do not reintroduce the padding. */
.arms {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 5vw, 76px);
}
.arms::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  width: var(--hairline);
  background: var(--hair-strong);
}

/* NOT `font: inherit` — that resets font-family and drops .lab
   26px, MATCHING `.cards` BELOW, so the arm keeps ONE internal interval:
   label · 26 · cards · 26 · links. It was 18px when a caption sat between the
   label and the cards and carried its own 14px; with the caption gone 18px
   read tight against the grid, and any other value would put two intervals
   inside a three-part stack. */
.arm h2 { margin: 0 0 26px; }

/* TWO-UP, fixed. `auto-fill` sized a single card by its minimum and left it a
   thumbnail in a 500px column; this holds the same geometry at one card or
   four, and it is identical in both arms — the arms are peers, so the cards
   are. */
.cards {
  margin: 0 0 26px;
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.card a { display: block; text-decoration: none; color: inherit; }
.card-art {
  display: block;
  aspect-ratio: 5 / 4;
  margin-bottom: 11px;
  border: var(--hairline) solid var(--hair-strong);
  background: var(--band);
  overflow: hidden;
  position: relative;
  transition: border-color 140ms linear;
}
.card-art canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.card-title {
  display: block;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: var(--w-semi);
  letter-spacing: var(--tr-sub);
  line-height: 1.25;
  color: var(--ink);
}
/* the reset sets `svg { display: block }`, which drops an inline arrow onto its
   own line. Everywhere else the arrow is a flex item so it never showed; this
   title is the one place it is genuinely inline, so it needs saying. */
.card-title .a,
.card-title .arrow { display: inline-block; vertical-align: baseline; width: 11px; height: 11px; }
.card-meta {
  display: block;
  margin-top: 5px;
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: var(--w-label);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
/* the card FACE is symmetric; the meta line is not, and should not be. A paper
   has a number, an instrument has a sentence. */
.card-meta.desc {
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--t-small);
  font-family: var(--font-prose);
  color: var(--ink-soft);
}
.card a:hover .card-title {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--warrant);
}
.card a:hover .card-art { border-color: var(--ink); }

.arm-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  margin: 0;
  font-family: var(--font-label);
  font-size: var(--t-small);
}
.arm-more a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  text-decoration: none;
  color: var(--ink);
  font-weight: var(--w-label);
  letter-spacing: var(--track-link);
  border-bottom: var(--hairline) solid var(--hair-strong);
  padding-bottom: 3px;
  transition: border-color 120ms linear;
}
.arm-more a:hover { border-bottom-color: var(--warrant); }
.arm-more .sep { color: var(--dim); }
.arm-more .a,
.arm-more .arrow { width: 12px; height: 12px; }

/* ============================================================================
   §8  THE REGISTER  ( /research )

   Rows, newest first, flat. No year headers, no kind sections, no tag facets,
   no search, and NO INTRODUCTORY PARAGRAPH — a register is a ledger, and it
   earns its authority by being complete and dull. Anything written above it is
   the institution explaining itself instead of showing its work.
   ========================================================================= */

.reg-head {
  font-family: var(--font-display);
  font-size: clamp(38px, 5.2vw, 68px);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  margin: 0 0 clamp(30px, 4vw, 52px);
  max-width: none;
}

.reg { border-top: var(--hairline) solid var(--hair-strong); }
.reg li { border-bottom: var(--hairline) solid var(--hair); }
.reg a {
  display: grid;
  grid-template-columns: 92px 132px minmax(0, 1fr) 22px;
  gap: 0 26px;
  align-items: baseline;
  padding: 22px 0;
  text-decoration: none;
  color: inherit;
  transition: background-color 120ms linear;
}
.reg a:hover { background: var(--raised); }
.reg .r-date,
.reg .r-id {
  font-family: var(--font-label);
  font-size: var(--t-label);
  font-weight: var(--w-label);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* the ID is the durable handle, so it holds ink where the date does not */
.reg .r-id { color: var(--ink-soft); font-weight: var(--w-semi); }
.reg .r-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(18px, 1.6vw, 21px);
  font-weight: var(--w-semi);
  letter-spacing: -0.016em;
  line-height: 1.24;
  color: var(--ink);
  max-width: none;
}
.reg a:hover .r-title {
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--warrant);
}
.reg .r-dek {
  margin: 7px 0 0;
  font-size: 16.5px;
  line-height: 1.5;
  color: var(--dim);
  max-width: 62ch;
}
.reg .r-go { justify-self: end; align-self: center; }
.reg .r-go .a,
.reg .r-go .arrow {
  width: 13px; height: 13px;
  opacity: 0.45;
  transition: opacity 150ms ease, transform 140ms cubic-bezier(.2,.6,.2,1);
}
.reg a:hover .r-go .a,
.reg a:hover .r-go .arrow { opacity: 1; transform: translateX(3px); }
/* forthcoming rows are dimmed, never labelled — nothing announces an absence,
   so a paper that is not yet published simply has no date to show. */
.reg .r-date.none { color: var(--dim); }

/* ============================================================================
   §9  STRATUM 04 — OUR CHANNELS

   No contact and no arms column — and no heading either: the datum names the
   section, so a "Channels" h2 under it is the same word twice in the same face
   forty pixels apart.
   ========================================================================= */

.colophon-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
}
.colophon .wordmark { font-size: 16px; display: inline-block; }
/* THE HOUSE SIGNS ITSELF. A bare copyright line naming a holding company is
   what a CHILD's surface does, and this is not one — it is the root. The
   mastheads that keep their own name here keep the article with it, which is
   the same rule as everywhere else on the page: the article lives in the
   masthead and dies where machines parse it. */
.colophon .sig {
  margin: 14px 0 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--dim);
  max-width: 34ch;
}
.col ul { display: grid; gap: 11px; }
.col a {
  font-family: var(--font-label);
  font-size: var(--t-small);
  color: var(--ink-soft);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-bottom: var(--hairline) solid transparent;
  transition: color 120ms linear, border-color 120ms linear;
}
.col a:hover { color: var(--ink); border-bottom-color: var(--warrant); }
.col .ico {
  width: 13px; height: 13px;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  opacity: 0.72;
  flex: none;
}
.col .ico.solid { fill: currentColor; stroke: none; }

.rule-out {
  border-top: var(--hairline) solid var(--hair);
  margin-top: clamp(44px, 5vw, 72px);
  padding-top: 20px;
}

/* ============================================================================
   §10  NARROW
   ========================================================================= */

@media (max-width: 980px) {
  .opening-body { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .prose { border-left: 0; padding-left: 0; }
  h1 { max-width: none; }
  .arms { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .arms::before { display: none; }   /* the divider turns horizontal below */
  .arm + .arm { border-top: var(--hairline) solid var(--hair-strong); padding-top: 44px; }
}

@media (max-width: 860px) {
  /* the constellation cannot hold at this width — it becomes a list, and the
     graph and the absolute nodes go away rather than overlapping the thesis */
  .q, .band-graph { display: none; }
  .q-list { display: block; }
  .band-inner { place-items: start center; }
  .band-centre { text-align: left; padding-left: 0; padding-right: 0; }
  .band-centre::before { display: none; }
  .site-nav { gap: 0; }
  .nav-trigger, .nav-link { padding: 10px 9px; }
  .nav-panel { left: auto; right: 0; }
}

@media (max-width: 820px) {
  .reg a { grid-template-columns: minmax(0, 1fr) 22px; gap: 0 18px; }
  .reg .r-date, .reg .r-id { grid-column: 1; display: inline; margin-right: 12px; }
  .reg .r-title { grid-column: 1; margin-top: 8px; }
  .reg .r-dek { grid-column: 1; }
  .reg .r-go { grid-row: 1; grid-column: 2; }
}

@media (max-width: 720px) {
  /* NARROW: the nav goes behind a toggle. Stacked full-width rows ate the whole
     first screen on a phone — the wordmark and the rows pushed the h1 below the
     fold, so the page opened on its own navigation. The rows were right; being
     always-on was not.

     `[data-menu]` is set by script. Absent — JavaScript off, or before the
     script runs — none of these rules apply, the button stays hidden and the
     nav renders as the open list. */
  [data-menu] .nav-toggle { display: inline-flex; }
  [data-menu="closed"] .site-nav { display: none; }

  .masthead .hold { flex-wrap: wrap; gap: 14px; }
  .site-nav {
    display: block;
    width: 100%;
    border-top: var(--hairline) solid var(--hair);
  }
  .nav-item + .nav-item,
  .site-nav > .nav-link { border-top: var(--hairline) solid var(--hair); }
  .nav-trigger, .nav-link {
    display: flex;
    width: 100%;
    justify-content: space-between;
    padding: 16px 0;
  }
  .nav-trigger::after, .nav-link::after { left: 0; right: 0; bottom: 8px; }
  .nav-panel { position: static; min-width: 0; margin-bottom: 12px; }

  .cards { grid-template-columns: minmax(0, 1fr); }
  .colophon-grid { grid-template-columns: minmax(0, 1fr); gap: 36px; }
}

@media (max-width: 420px) {
  .reg .r-id { display: block; margin-right: 0; }
}

/* ============================================================================
   §11  REDUCED MOTION

   Everything that moves on a shell page is an affordance nudge — a row tint, a
   rule wiping in under a nav item, an arrow sliding 3px under the cursor, the
   skip link dropping into view. None of it carries meaning the still state
   does not, so under `reduce` all of it simply stops.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  body,
  .skip,
  .nav-trigger::after, .nav-link::after, .nav-trigger .caret,
  .nav-panel a,
  .prose a,
  .arm-more a,
  .card-art,
  .reg a, .reg .r-go .a, .reg .r-go .arrow,
  .q-c,
  .band-centre .pill,
  .col a,
  .nav-toggle__bars,
  .nav-toggle__bars::before,
  .nav-toggle__bars::after {
    transition: none;
  }
  .reg a:hover .r-go .a,
  .reg a:hover .r-go .arrow { transform: none; }
}
