/* ===========================================================================
   paper.css — a paper's own page.

   One idea, and the whole page is built on it: you come off the board and the
   paper is laid over it. The heading is slate and chalk, exactly the board you
   just left; then a sheet of warm stock slides up over it and stays, and the
   article is printed on that sheet — same two typefaces, opposite polarity.
   At the end the sheet runs out and the board is underneath again.

   Nothing here is specific to one article. What one article needs — its
   figures, its live diagrams — lives in assets/js/papers/<slug>.js and in its
   own rules at the end of its source page.
   =========================================================================== */

:root {
  /* --- the sheet -------------------------------------------------------
     Warm, never white: a page under a desk lamp, not a screen. */
  --paper:       #efe9dc;
  --paper-deep:  #e7e0d0;
  --paper-lift:  #f6f1e7;

  --ink:         #201f1b;
  --ink-soft:    #56524a;   /* 7.0:1 on the sheet */
  --ink-faint:   #6e685c;   /* 4.6:1 on the sheet — the floor for text */
  --ink-hair:    #c3bcab;   /* rules only, never text */

  --bronze:      #7a5c18;   /* the CV's ochre, printed. 5.2:1 */
  --bronze-lift: #b9922f;

  /* --- the physics, in the papers' own colours -------------------------
     Sampled from the figures themselves, so a live diagram and the plate
     beside it are drawn in the same two fields. */
  --field-up:    #ff2a2a;   /* B out of the page */
  --field-dn:    #5fbcd3;   /* B into the page  */
  --trace:       #d99f00;   /* the particle's track */

  --measure:     66ch;
  --gutter:      13rem;
}

/* ============================================================== the stage */
.stage { position: relative; }

/* ------------------------------------------------------------- the board */
.hero {
  position: sticky; inset-block-start: 0;
  min-block-size: 100svh;
  display: grid; align-content: center;
  padding-block: clamp(3rem, 10vh, 7rem) clamp(5rem, 12vh, 9rem);
  padding-inline: clamp(1.3rem, 5vw, 5rem);
  overflow: clip;
  background:
    radial-gradient(58% 40% at 26% 16%, rgb(214 226 218 / .075), transparent 66%),
    radial-gradient(46% 32% at 82% 52%, rgb(214 226 218 / .05), transparent 68%),
    radial-gradient(130% 104% at 48% 38%, transparent 56%, rgb(0 0 0 / .36) 100%),
    linear-gradient(170deg, var(--board-lift), var(--board) 44%, var(--board-deep));
}
.hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  opacity: .24; mix-blend-mode: overlay;
  background-image: var(--grain); background-size: 220px 220px;
}
.hero > * { position: relative; z-index: 1; }

.hero .inner {
  inline-size: min(100%, 62rem);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.4rem;
}

.hero .back {
  font-family: var(--sans); font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--chalk-faint); text-decoration: none;
  justify-self: start;
}
.hero .back:hover { color: var(--chalk-soft); }

/* The mark you clicked, drawn at size. On a wide screen it is on the board
   behind the title, the way it was before you clicked it — bigger, and
   further off. */
.hero .mark {
  inline-size: clamp(4.6rem, 9vw, 7rem); aspect-ratio: 1;
  color: var(--chalk-soft); opacity: .92;
  filter: url(#chalk-line);
}
.hero .mark svg { inline-size: 100%; block-size: 100%; }
@media (width >= 64rem) {
  .hero .inner { position: relative; }
  .hero .mark {
    position: absolute; inset-block-start: -1rem; inset-inline-end: 2%;
    inline-size: clamp(9rem, 19vw, 17rem);
    opacity: .3; color: var(--chalk);
  }
}

.hero .kicker {
  font-family: var(--sans); font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--chalk-faint);
  display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; align-items: baseline;
}
.hero h1 {
  margin: 0; font-weight: 400; line-height: 1.02;
  font-size: clamp(1.85rem, 4.6vw, 3.5rem);
  color: var(--chalk); max-inline-size: 22ch;
  filter: url(#chalk-text) drop-shadow(0 0 14px rgb(230 227 216 / .14));
}
.hero .sub {
  margin: 0; max-inline-size: 54ch; color: var(--chalk-soft);
  font-size: clamp(1rem, 1.5vw, 1.16rem); line-height: 1.55;
}
.hero .venue {
  margin: 0; font-family: var(--sans); font-size: .8rem;
  color: var(--chalk-faint); display: flex; flex-wrap: wrap; gap: .5rem .9rem;
  align-items: center;
}
.hero .venue b { color: var(--chalk-soft); font-weight: 400; }

.pill {
  font-family: var(--sans); font-size: .6rem; letter-spacing: .14em;
  text-transform: uppercase; padding: .28em .7em .24em;
  border: 1px solid var(--chalk-hair); border-radius: 100px;
  color: var(--chalk-soft); white-space: nowrap;
}
.pill.editors { border-color: var(--chalk-ochre); color: var(--chalk-ochre); }

/* the equation the board writes for this paper. Both blocks are sized from
   one length, so the gloss keeps its proportion to the equation at every
   screen width. */
.chalkwrite { display: block; color: var(--chalk-soft); margin-block-start: .6rem;
              --cw-block: min(100%, 30rem); }
.chalkwrite svg { display: block; overflow: visible; }
.chalkwrite .cw-math  { inline-size: var(--cw-block); }
.chalkwrite .cw-gloss { color: var(--chalk-faint); }
.chalkwrite path {
  fill: none; stroke: currentColor; stroke-width: 26;
  stroke-linecap: round; stroke-linejoin: round;
  vector-effect: non-scaling-stroke; stroke-width: 1.35px;
}
.chalkwrite .cw-gloss path { stroke-width: 1px; }
@supports (filter: url(#chalk-hand)) { .chalkwrite svg { filter: url(#chalk-hand); } }

.hero .scent {
  justify-self: start; margin-block-start: 1.2rem;
  font-family: var(--sans); font-size: .64rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--chalk-hair);
  display: flex; align-items: center; gap: .6rem;
}
.hero .scent::after {
  content: ''; inline-size: 1px; block-size: 2.2rem;
  background: linear-gradient(var(--chalk-hair), transparent);
}

/* ============================================== the sheet, over the board */
.sheet {
  position: relative; z-index: 2;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 -34px 70px -10px rgb(0 0 0 / .62), 0 -2px 0 rgb(255 255 255 / .16);
  padding-block: clamp(3rem, 8vh, 6rem) clamp(4rem, 10vh, 7rem);
  /* the sheet's own tooth, far quieter than the board's */
  background-image:
    radial-gradient(120% 60% at 50% 0%, rgb(255 255 255 / .5), transparent 60%),
    var(--grain);
  background-size: auto, 220px 220px;
  background-blend-mode: normal, multiply;
}
.sheet::before {           /* the torn top edge of a sheet laid down */
  content: ''; position: absolute; inset-inline: 0; inset-block-start: 0;
  block-size: 2px; background: linear-gradient(90deg,
    transparent, rgb(255 255 255 / .55) 12%, rgb(255 255 255 / .55) 88%, transparent);
}

/* the measure, and the two gutters that plates and margin notes break into */
.body {
  display: grid;
  grid-template-columns:
    [full-start] minmax(1.2rem, 1fr)
    [wide-start] minmax(0, var(--gutter))
    [main-start] min(var(--measure), 100% - 2.4rem) [main-end]
    minmax(0, var(--gutter)) [wide-end]
    minmax(1.2rem, 1fr) [full-end];
  row-gap: 0;
}
.body > * { grid-column: main; }
.body > .wide  { grid-column: wide; }
.body > .full  { grid-column: full; }

/* ----------------------------------------------------------- the writing */
.body p, .body ul, .body ol { margin-block: 0 1.15em; }
.body p { text-wrap: pretty; hyphens: auto; }
.body .lede {
  font-size: 1.16em; line-height: 1.55; color: var(--ink);
  margin-block-end: 1.6em;
}
.body .lede .open { font-variant-caps: all-small-caps; letter-spacing: .06em; }

.body h2 {
  counter-increment: sec;
  margin: 3.4rem 0 1.1rem; position: relative;
  font-family: var(--sans); font-weight: 700;
  font-size: .74rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--bronze);
}
.body h2::after {
  content: ''; display: block; block-size: 1px; margin-block-start: .8rem;
  background: var(--ink-hair);
}
.body h2::before {
  content: counter(sec, upper-roman);
  position: absolute; inset-inline-end: calc(100% + 1.4rem); inset-block-start: -.15em;
  font-family: var(--serif); font-size: 1.5rem; letter-spacing: 0;
  color: var(--ink-hair); text-transform: none;
}
.body { counter-reset: sec; }
@media (width < 62rem) { .body h2::before { display: none; } }

.body h3 {
  margin: 2rem 0 .6rem; font-weight: 700; font-size: 1.02em; color: var(--ink);
}

.body a { color: var(--ink); text-decoration-color: var(--bronze-lift);
          text-underline-offset: .18em; text-decoration-thickness: 1px; }
.body a:hover { color: var(--bronze); }

/* a remark in the margin, where a reader who wants it will find it and a
   reader who does not will not trip over it */
.note {
  font-family: var(--sans); font-size: .76rem; line-height: 1.5;
  color: var(--ink-soft); margin-block: .4em 1.2em;
  padding-inline-start: .8rem; border-inline-start: 2px solid var(--bronze-lift);
}
@media (width >= 62rem) {
  .note {
    float: inline-end; clear: inline-end;
    inline-size: calc(var(--gutter) - 2.2rem);
    margin-inline-end: calc(-1 * var(--gutter) + 1.2rem);
    margin-block: .35em 1.1em;
    border-inline-start: 0; padding-inline-start: 0;
    color: var(--ink-faint);
  }
  .note::before {
    content: ''; display: block; inline-size: 1.4rem; block-size: 1px;
    background: var(--bronze-lift); margin-block-end: .5rem;
  }
}

/* --------------------------------------------------------- mathematics */
.eq {
  display: block; overflow-x: auto; overflow-y: hidden;
  margin-block: 1.5em; text-align: center;
  padding-block: .2em; color: var(--ink);
}
.eq svg { max-inline-size: 100%; }
.im svg { max-inline-size: 100%; }
.im { white-space: nowrap; }

/* an equation with a tag, as it is numbered in the article */
.eqrow {
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: 1rem; margin-block: 1.5em;
}
.eqrow .eq { margin: 0; }
.eqrow .tag {
  font-family: var(--sans); font-size: .68rem; color: var(--ink-faint);
  white-space: nowrap;
}

/* ------------------------------------------------- for physicists, a box */
.tech {
  position: relative; margin-block: 2.2rem;
  padding: 1.5rem 1.5rem 1.1rem;
  border: 1px solid color-mix(in oklab, var(--bronze) 34%, transparent);
  background: color-mix(in oklab, var(--bronze) 5%, var(--paper-lift));
}
.tech > .lbl {
  position: absolute; inset-block-start: -.62em; inset-inline-start: 1.15rem;
  padding-inline: .55em;
  background: color-mix(in oklab, var(--bronze) 5%, var(--paper-lift));
  font-family: var(--sans); font-size: .61rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--bronze);
}
.tech > :is(p, .eq, .eqrow):last-child { margin-block-end: 0; }
.tech p { font-size: .95em; }
.tech .where, .turn .p .where {
  margin-block-start: 1rem; padding-block-start: .7rem;
  border-block-start: 1px solid color-mix(in oklab, var(--bronze) 22%, transparent);
  font-family: var(--sans); font-size: .66rem; letter-spacing: .04em;
  color: var(--ink-faint); text-align: end;
}

/* -------------------------------------------------------------- plates */
figure.plate { margin: 2.6rem 0; }
figure.plate img {
  display: block; inline-size: 100%; block-size: auto;
  /* laid on the sheet, not printed into it: a hairline and a little air */
  background: var(--paper-lift);
  border: 1px solid var(--ink-hair);
  padding: .5rem;
}
figure.plate img + img { margin-block-start: .6rem; }
figure.plate figcaption {
  margin-block-start: .9rem;
  font-family: var(--sans); font-size: .76rem; line-height: 1.55;
  color: var(--ink-soft); max-inline-size: 62ch;
}
figure.plate figcaption b { color: var(--ink); font-weight: 700; }
figure.plate figcaption .credit {
  display: block; margin-block-start: .35rem;
  font-size: .68rem; color: var(--ink-faint);
}

/* --------------------------------------------------- a live diagram */
.live {
  margin: 2.6rem 0;
  border: 1px solid var(--ink-hair);
  background: var(--paper-lift);
}
.live .canvas { display: block; inline-size: 100%; }
.live figcaption {
  padding: .9rem 1.1rem 1rem;
  border-block-start: 1px solid var(--ink-hair);
  font-family: var(--sans); font-size: .76rem; line-height: 1.55; color: var(--ink-soft);
}
.live figcaption b { color: var(--ink); font-weight: 700; }

.ctrl {
  display: flex; flex-wrap: wrap; gap: .8rem 1.6rem; align-items: center;
  padding: .8rem 1.1rem; border-block-start: 1px solid var(--ink-hair);
  font-family: var(--sans); font-size: .74rem; color: var(--ink-soft);
}
.ctrl label { display: flex; align-items: center; gap: .6rem; }
.ctrl output { color: var(--ink); font-variant-numeric: tabular-nums; min-inline-size: 4.2em; }
.ctrl input[type=range] { inline-size: clamp(7rem, 18vw, 13rem); accent-color: var(--bronze); }
.ctrl button {
  font: inherit; color: var(--ink); background: var(--paper);
  border: 1px solid var(--ink-hair); border-radius: 2px;
  padding: .35em .9em; cursor: pointer;
}
.ctrl button:hover { border-color: var(--bronze); color: var(--bronze); }
.ctrl .key { display: flex; align-items: center; gap: .4rem; }
.ctrl .key i {
  inline-size: .8rem; block-size: .8rem; border-radius: 2px; display: inline-block;
}
.ctrl .key.up i { background: color-mix(in oklab, var(--field-up) 62%, transparent); }
.ctrl .key.dn i { background: color-mix(in oklab, var(--field-dn) 72%, transparent); }

/* ------------------------------------------- the figure that is scrolled */
.scrolly { margin-block: 3rem; }
@media (width >= 60rem) {
  .scrolly {
    display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: 0 3rem; align-items: start;
  }
  .scrolly .stick {
    position: sticky; inset-block-start: max(2rem, calc(50svh - 16rem));
    grid-column: 1; grid-row: 1;
  }
  .scrolly .beats { grid-column: 2; grid-row: 1; }
  .scrolly .beat { min-block-size: 78svh; display: grid; align-content: center; }
}
@media (width < 60rem) {
  .scrolly .stick {
    position: sticky; inset-block-start: 0; z-index: 3;
    background: var(--paper); padding-block: .5rem .7rem;
    margin-inline: -1.2rem; padding-inline: 1.2rem;
    box-shadow: 0 .8rem .8rem -.8rem rgb(32 31 27 / .3);
  }
  .scrolly .beat { padding-block: 2.2rem; }
}
.scrolly .beat > :last-child { margin-block-end: 0; }
.scrolly .beat h3 {
  margin-block: 0 .5rem; font-family: var(--sans); font-size: .68rem;
  letter-spacing: .18em; text-transform: uppercase; color: var(--bronze);
}
.scrolly .beat { opacity: .34; transition: opacity .5s var(--ease-out); }
.scrolly .beat.on { opacity: 1; }

/* ------------------------------------------------------------- the coda */
.coda {
  position: relative; z-index: 2;
  background: var(--board); color: var(--chalk);
  padding-block: clamp(3rem, 8vh, 5.5rem);
  background-image:
    radial-gradient(80% 60% at 50% 0%, rgb(214 226 218 / .05), transparent 70%),
    var(--grain);
  background-size: auto, 220px 220px;
  box-shadow: 0 -1px 0 rgb(0 0 0 / .5);
}
.coda .body > * { grid-column: main; }
.coda h2 {
  color: var(--chalk-faint); margin-block-start: 0;
}
.coda h2::after { background: var(--chalk-hair); }
.coda h2::before { color: var(--chalk-hair); }
.coda a { color: var(--chalk); text-decoration-color: var(--chalk-hair); }
.coda a:hover { color: var(--chalk-ochre); }

.getit { display: flex; flex-wrap: wrap; gap: .7rem; margin-block: 1.2rem 1.6rem; }
.getit a {
  font-family: var(--sans); font-size: .74rem; letter-spacing: .06em;
  text-decoration: none; color: var(--chalk-soft);
  border: 1px solid var(--chalk-hair); border-radius: 2px;
  padding: .5em 1em;
}
.getit a:hover { color: var(--chalk-ochre); border-color: var(--chalk-ochre); }

.authors { font-size: .92rem; color: var(--chalk-soft); margin-block: 0 .4rem; }
.authors .me { color: var(--chalk); }
.venue-line { font-size: .85rem; color: var(--chalk-faint); margin-block: 0 1.4rem; }

.cite {
  margin: 0; padding: 1rem 1.1rem;
  border: 1px solid var(--chalk-hair);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .72rem; line-height: 1.6; color: var(--chalk-soft);
  white-space: pre-wrap; overflow-x: auto;
}
.cite-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; margin-block-end: .5rem;
}
.cite-head button {
  font-family: var(--sans); font-size: .66rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--chalk-faint);
  background: none; border: 0; cursor: pointer; padding: 0;
}
.cite-head button:hover { color: var(--chalk-ochre); }

/* ------------------------------------------------- where you are, on the board */
.map {
  position: fixed; inset-block-end: 1rem; inset-inline-end: 1rem; z-index: 30;
  inline-size: 9rem;
  border: 1px solid rgb(93 101 96 / .5); border-radius: 2px;
  background: rgb(11 14 13 / .84);
  backdrop-filter: blur(6px);
  padding: .45rem .5rem .5rem;
  transition: inline-size .45s var(--spring), background .3s;
}
.map:hover, .map:focus-within { inline-size: min(20rem, 44vw); background: rgb(11 14 13 / .96); }
.map svg { display: block; inline-size: 100%; aspect-ratio: 3 / 2; overflow: visible; }
.map .n { fill: var(--chalk-hair); }
.map .s { fill: var(--chalk-faint); cursor: pointer; }
.map .s:hover { fill: var(--chalk-ochre); }
.map .here { fill: var(--chalk-ochre); }
.map .lk { stroke: var(--chalk-hair); stroke-width: .5; opacity: .5; }
.map .cap {
  fill: var(--chalk-soft); font-family: var(--sans); font-size: 3.4px;
  opacity: 0; transition: opacity .3s;
}
.map:hover .cap, .map:focus-within .cap { opacity: 1; }
.map .ttl {
  fill: var(--chalk-faint); font-family: var(--sans); font-size: 3.2px;
  letter-spacing: .4px; text-transform: uppercase;
}
@media (width < 52rem) { .map { display: none; } }

/* ------------------------------------------------------------- neighbours */
.near { display: grid; gap: .1rem; margin-block: 1rem 0; }
.near a {
  display: grid; grid-template-columns: 2.4rem 1fr; gap: 1rem; align-items: center;
  padding: .8rem 0; border-block-start: 1px solid var(--chalk-hair);
  text-decoration: none; color: var(--chalk-soft);
}
.near a:last-child { border-block-end: 1px solid var(--chalk-hair); }
.near a:hover { color: var(--chalk); }
.near a:hover .g { color: var(--chalk-ochre); }
.near .g { color: var(--chalk-hair); inline-size: 2.4rem; aspect-ratio: 1; }
.near .g svg { inline-size: 100%; block-size: 100%; }
.near .t { font-size: .92rem; line-height: 1.35; }
.near .w { display: block; font-family: var(--sans); font-size: .68rem;
           color: var(--chalk-faint); margin-block-start: .2rem; }

/* ------------------------------------------------------------- reveal */
.rise { }
@supports ((animation-timeline: view()) and (animation-range: entry)) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes rise { from { opacity: 0; transform: translateY(1.1rem); }
                      to   { opacity: 1; transform: none; } }
    .sheet .rise, .coda .rise {
      animation: rise linear both;
      animation-timeline: view();
      animation-range: entry 6% cover 20%;
    }
  }
}
@supports not ((animation-timeline: view()) and (animation-range: entry)) {
  @media (prefers-reduced-motion: no-preference) {
    .sheet .rise, .coda .rise {
      opacity: 0; transform: translateY(1.1rem);
      transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
    }
    .sheet .rise.seen, .coda .rise.seen { opacity: 1; transform: none; }
  }
}

@media (prefers-reduced-motion: reduce) {
  .scrolly .beat { opacity: 1; }
  .map { transition: none; }
}

/* -------------------------------------------------------------- print */
@media print {
  .hero, .map, .ctrl, .scrolly .stick { display: none; }
  .sheet { box-shadow: none; }
  .coda { background: none; color: #000; }
  .body { display: block; max-inline-size: 40em; margin-inline: auto; }
  .note { float: none; inline-size: auto; margin: 0 0 1em; }
}

/* =========================================================== two registers
   Some papers say two different things to two different readers, and the
   honest layout is to run both and let the reader choose — the same idea as
   the CV's "read it as…". Every beat exists in both columns or it does not
   exist; that discipline is what keeps the alignment from lying.

   The choice rides in the URL (?read=physicist), so a link can be sent
   already set.
   =========================================================================== */
.duo { margin-block: 2.4rem 3rem; }

.duoctl {
  position: sticky; inset-block-start: 0; z-index: 4;
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  padding-block: .7rem .8rem; margin-block-end: .6rem;
  background: linear-gradient(var(--paper) 72%, transparent);
}
.duoctl .lbl {
  font-family: var(--sans); font-size: .62rem; letter-spacing: .2em;
  text-transform: uppercase; color: var(--ink-faint); margin-inline-end: .3rem;
}
.duoctl button {
  font-family: var(--sans); font-size: .72rem; color: var(--ink-soft);
  background: none; border: 1px solid var(--ink-hair); border-radius: 100px;
  padding: .3em .95em; cursor: pointer;
}
.duoctl button:hover { border-color: var(--bronze); color: var(--bronze); }
.duoctl button[aria-pressed="true"] {
  border-color: var(--bronze); background: color-mix(in oklab, var(--bronze) 12%, transparent);
  color: var(--ink);
}

.turn { padding-block-end: 1.6rem; }
.turn + .turn { border-block-start: 1px solid var(--ink-hair); padding-block-start: 1.6rem; }
.turn h3 {
  margin: 0 0 .55rem; font-family: var(--sans); font-weight: 700;
  font-size: .68rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--bronze);
}
.turn .r > :last-child, .turn .p > :last-child { margin-block-end: 0; }
.turn .p {
  font-size: .95em;
  border-inline-start: 2px solid color-mix(in oklab, var(--bronze) 40%, transparent);
  padding-inline-start: 1.1rem;
}
.turn .p .eq { margin-block: 1.1em; text-align: start; }

/* one register at a time */
.duo[data-read="reader"]    .p { display: none; }
.duo[data-read="physicist"] .r { display: none; }
.duo[data-read="physicist"] .p {
  border-inline-start: 0; padding-inline-start: 0;
  font-size: 1em;
}
.duo[data-read="physicist"] .turn::before {
  content: attr(data-t); display: block; margin-block-end: .55rem;
  font-family: var(--sans); font-weight: 700; font-size: .68rem;
  letter-spacing: .18em; text-transform: uppercase; color: var(--bronze);
}

/* both, side by side — but only where two columns of prose actually fit */
@media (width >= 74rem) {
  .duo[data-read="both"] .turn {
    display: grid; grid-template-columns: 1fr 1fr; gap: 0 3rem; align-items: start;
  }
  .duo[data-read="both"] .turn h3 { grid-column: 1 / -1; }
}
@media (width < 74rem) {
  .duo[data-read="both"] .turn .p { margin-block-start: 1.1rem; }
}

/* A claim standing on its own, before the paragraphs that argue it. Used
   where a paper is one long chain of assertions and the page should read
   like the chain. */
.claim {
  margin: 0 0 1.1em; font-size: 1.08em; line-height: 1.5; color: var(--ink);
  padding-inline-start: 1rem;
  border-inline-start: 2px solid var(--bronze-lift);
}

/* A short list of consequences, set as a ledger rather than bullets. */
.ledger { margin: 1.6rem 0; border-block-start: 1px solid var(--ink-hair); }
.ledger div {
  display: grid; grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
  gap: .3rem 1.6rem; padding: .8rem 0;
  border-block-end: 1px solid var(--ink-hair);
}
.ledger b {
  font-family: var(--sans); font-size: .74rem; font-weight: 700;
  letter-spacing: .04em; color: var(--bronze);
}
.ledger span { font-size: .95em; color: var(--ink-soft); }
@media (width < 40rem) { .ledger div { grid-template-columns: 1fr; } }

/* A plate that is white on black — a still from the board, or a clip drawn
   in chalk. It keeps its own polarity rather than being inverted, and the
   page gives it a slate mount so it reads as an inset rather than a hole. */
figure.plate.slate {
  background: var(--board); padding: 1rem;
  border: 1px solid var(--ink-hair);
}
figure.plate.slate :is(img, video) {
  border: 0; padding: 0; background: none; display: block;
  inline-size: 100%; block-size: auto;
}
figure.plate.slate figcaption {
  color: var(--chalk-soft); padding-inline: .2rem; margin-block-start: .8rem;
}
figure.plate.slate figcaption b { color: var(--chalk); }
figure.plate.slate figcaption .credit { color: var(--chalk-faint); }
figure.plate.slate .vidctl {
  display: flex; gap: .8rem; align-items: center; margin-block-start: .7rem;
  padding-inline: .2rem;
}
figure.plate.slate .vidctl button {
  font-family: var(--sans); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--chalk-faint);
  background: none; border: 1px solid var(--chalk-hair); border-radius: 2px;
  padding: .35em .9em; cursor: pointer;
}
figure.plate.slate .vidctl button:hover { color: var(--chalk-ochre); border-color: var(--chalk-ochre); }

/* -------------------------------------------------------------- the moves
   A manoeuvre in four states, laid across the page as a strip. Not a
   scrolly and not an animation: the whole sequence is visible at once, so
   the eye can go back a step, which is what a reader wants from a
   before-and-after. Below 46rem the strip becomes a column. */
.moves {
  margin: 2.6rem 0 2.2rem;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--ink-hair);
  border: 1px solid var(--ink-hair);
}
.moves > figure {
  margin: 0; padding: 1rem .9rem 1.1rem;
  background: var(--paper-lift);
  display: flex; flex-direction: column; gap: .7rem;
}
.moves > figure > svg { display: block; inline-size: 100%; block-size: auto; }
.moves .n {
  font-family: var(--sans); font-size: .64rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--bronze);
}
.moves figcaption {
  font-family: var(--sans); font-size: .74rem; line-height: 1.5;
  color: var(--ink-soft); margin-block-start: auto;
}
.moves figcaption b { color: var(--ink); font-weight: 700; }
.moves .cost {
  display: block; margin-block-start: .55em; color: var(--bronze);
  font-size: .95em; letter-spacing: .01em;
}
.moves .cost.free { color: var(--ink-faint); }
@media (width < 46rem) {
  .moves { grid-template-columns: 1fr; }
  .moves > figure {
    display: grid; grid-template-columns: 32% 1fr;
    grid-template-areas: "svg n" "svg cap";
    align-content: center; gap: .25rem .9rem;
  }
  .moves > figure > svg { grid-area: svg; align-self: center; }
  .moves .n { grid-area: n; align-self: end; }
  .moves figcaption { grid-area: cap; margin-block-start: 0; }
}

/* ---------------------------------------------------------------- the bill
   What a transformation left behind, itemised. The numeral hangs, so the
   rows read as a list of charges rather than as paragraphs. */
.bill { margin: 1.8rem 0 2.4rem; counter-reset: bill; }
.bill > div {
  counter-increment: bill;
  display: grid; grid-template-columns: 2.2rem 1fr; gap: 0 .9rem;
  padding-block: .95rem;
  border-block-start: 1px solid var(--ink-hair);
}
.bill > div:last-child { border-block-end: 1px solid var(--ink-hair); }
.bill > div::before {
  content: counter(bill);
  grid-column: 1; grid-row: 1 / span 2;
  font-family: var(--sans); font-size: .95rem; color: var(--bronze);
  padding-block-start: .05em; font-variant-numeric: tabular-nums;
}
/* both the lead and the body belong in the second column; without this the
   paragraph drops under the numeral and sets two words to a line */
.bill b { grid-column: 2; display: block; font-weight: 700; }
.bill p { grid-column: 2; margin: .25em 0 0; font-size: .95em; color: var(--ink-soft); }

/* A row of alternatives in a figure's controls: one of them is on. */
.ctrl .pick { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.ctrl button[aria-pressed="true"] {
  border-color: var(--bronze); color: var(--bronze);
  background: color-mix(in oklab, var(--bronze) 8%, var(--paper));
}

/* ------------------------------------------------------------- two numbers
   A page whose spine is a pair of quantities puts them both up front, once,
   at the same size, so the reader can carry them down the rest of it. */
.numbers {
  margin: 2.6rem 0 2.4rem;
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--ink-hair); border: 1px solid var(--ink-hair);
}
.numbers > div {
  background: var(--paper-lift); padding: 1.5rem 1.3rem 1.4rem;
  display: flex; flex-direction: column; gap: .55rem;
}
.numbers .tag {
  font-family: var(--sans); font-size: .64rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--bronze);
}
.numbers .eq { margin: .2rem 0 .3rem; text-align: start; font-size: 1.05em; }
.numbers b { font-weight: 700; }
.numbers p { margin: 0; font-size: .95em; color: var(--ink-soft); }
.numbers .kind {
  margin-block-start: auto; padding-block-start: .7rem;
  border-block-start: 1px solid var(--ink-hair);
  font-family: var(--sans); font-size: .72rem; color: var(--ink-faint);
}
@media (width < 44rem) { .numbers { grid-template-columns: 1fr; } }

/* A chalk line standing in for a chalk equation: a shade larger than a
   gloss, since it is carrying the heading on its own. */
.chalkwrite .cw-line { inline-size: min(100%, 34rem); }

/* ------------------------------------------------------------- a comparison
   Three states of one system, side by side. A table because that is what this
   is: rows that mean the same thing read across, and a reader who wants only
   one row can take it. Below 52rem it becomes a stack of small cards, one per
   state, because a four-column table on a phone is not a table. */
.compare {
  inline-size: 100%; margin: 2.2rem 0 2.6rem;
  border-collapse: collapse;
  font-size: .95em;
}
.compare th, .compare td {
  vertical-align: top; text-align: start;
  padding: .85rem .9rem;
  border-block-start: 1px solid var(--ink-hair);
}
.compare thead th {
  border-block-start: 0; padding-block-start: 0;
  font-family: var(--sans); font-size: .72rem; letter-spacing: .1em;
  font-weight: 700; color: var(--bronze); white-space: nowrap;
}
.compare tbody th {
  font-family: var(--sans); font-size: .74rem; font-weight: 700;
  color: var(--ink); inline-size: 8rem;
}
.compare td { inline-size: calc((100% - 8rem) / 3); }
.compare td { color: var(--ink-soft); }
.compare td:nth-child(3) { color: var(--ink); background: var(--paper-lift); }
.compare sup { font-size: .78em; }
@media (width < 52rem) {
  .compare, .compare tbody, .compare tr, .compare th, .compare td { display: block; }
  .compare thead { display: none; }
  .compare tr { border-block-start: 1px solid var(--ink-hair); padding-block: .5rem; }
  .compare th, .compare td { border: 0; padding: .25rem 0; inline-size: auto; }
  .compare tbody th {
    font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
    color: var(--bronze); padding-block-start: .8rem;
  }
  .compare td { background: none !important; padding-inline-start: 0; }
  .compare td::before {
    content: attr(data-when) ' \2014 ';
    font-family: var(--sans); font-size: .72rem; color: var(--ink-faint);
  }
}

/* --------------------------------------------------------------- a ladder
   A set of quantities that live decades apart, laid on a logarithmic rule so
   the distances between them are the point. Built out of rows rather than a
   drawing, so it reflows on a phone and prints. */
.ladder { margin: 2.2rem 0 2.6rem; padding: 0; list-style: none; }
.ladder li {
  display: grid; grid-template-columns: minmax(10rem, 15.5rem) 1fr auto;
  align-items: center; gap: 0 1rem;
  padding-block: .7rem;
  border-block-start: 1px solid var(--ink-hair);
}
.ladder li:last-child { border-block-end: 1px solid var(--ink-hair); }
.ladder .what { font-size: .95em; }
.ladder .rule { position: relative; block-size: 10px; }
.ladder .rule::before {
  content: ''; position: absolute; inset-block-start: 50%;
  inset-inline-start: 0; inline-size: 100%; block-size: 1px;
  background: var(--ink-hair);
}
.ladder .rule::after {
  content: ''; position: absolute; inset-block-start: 50%;
  inset-inline-start: 0; inline-size: calc(var(--f) * 100%); block-size: 3px;
  transform: translateY(-1px);
  background: var(--bronze); border-radius: 2px;
}
.ladder .how {
  font-family: var(--sans); font-size: .78rem; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ladder .gloss {
  grid-column: 1 / -1; margin: .3rem 0 0;
  font-family: var(--sans); font-size: .74rem; color: var(--ink-faint);
}
@media (width < 40rem) {
  .ladder li { grid-template-columns: 1fr auto; }
  .ladder .rule { grid-column: 1 / -1; order: 3; }
}

/* the equal-contribution mark, and anything else the author line has to say */
.authors .foot { font-size: .8em; color: var(--chalk-faint); white-space: nowrap; }
.authors sup { font-size: .7em; }

/* ---------------------------------------------------------------- the cases
   Three geometries, each with a picture and a verdict. A row apiece rather
   than a strip of cells, because the verdict is the point and it wants room
   to be read as a sentence. */
.cases { margin: 2.4rem 0 2.6rem; }
.cases > div {
  display: grid; grid-template-columns: 8.5rem 1fr; gap: 0 1.6rem;
  align-items: center;
  padding-block: 1.3rem;
  border-block-start: 1px solid var(--ink-hair);
}
.cases > div:last-child { border-block-end: 1px solid var(--ink-hair); }
.cases > div > svg { display: block; inline-size: 100%; block-size: auto; color: var(--ink-soft); }
.cases .g {
  display: block; font-family: var(--sans); font-size: .64rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--bronze);
  margin-block-end: .25rem;
}
.cases b { display: block; font-weight: 700; margin-block-end: .3rem; }
.cases p { margin: 0; font-size: .95em; color: var(--ink-soft); }
.cases .verdict {
  display: inline-block; margin-block-start: .7rem;
  font-family: var(--sans); font-size: .74rem; letter-spacing: .02em;
  padding: .3em .8em; border-radius: 2px;
  border: 1px solid var(--ink-hair); color: var(--ink);
}
.cases .verdict.no { border-color: var(--bronze); color: var(--bronze); }
@media (width < 44rem) {
  .cases > div { grid-template-columns: 5.5rem 1fr; gap: 0 1rem; }
}
