@property --drawn {
  syntax: "<percentage>";
  inherits: true;
  initial-value: 100%;
}
/* Each face comes as a Latin file and an extended Latin one, which is only fetched for a letter that needs it. */
@font-face {
  font-family: "Public Sans";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/public-sans-400.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Public Sans";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/public-sans-400-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Public Sans";
  font-weight: 700;
  font-display: swap;
  src: url("fonts/public-sans-700.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Public Sans";
  font-weight: 700;
  font-display: swap;
  src: url("fonts/public-sans-700-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Libre Caslon Text";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/caslon-400.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Libre Caslon Text";
  font-weight: 400;
  font-display: swap;
  src: url("fonts/caslon-400-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Libre Caslon Text";
  font-weight: 700;
  font-display: swap;
  src: url("fonts/caslon-700.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Libre Caslon Text";
  font-weight: 700;
  font-display: swap;
  src: url("fonts/caslon-700-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
:root {
  --sheet: #fdfdfb;
  --ink: #121212;
  --soft: #555552;
  --rule: #121212;
  --faint: #d6d6d1;
  --wash: #f1f1ec;
  --lost: #c4161c;
  --on-ink: #fdfdfb;
  --serif: "Libre Caslon Text", "Iowan Old Style", Georgia, serif;
  --sans: "Public Sans", "Helvetica Neue", Arial, sans-serif;
  --measure: 62ch;
  --page: clamp(1240px, 84vw, 2200px);
  --out: cubic-bezier(0.16, 1, 0.3, 1);
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --sheet: #131312;
    --ink: #ecebe4;
    --soft: #a9a8a0;
    --rule: #ecebe4;
    --faint: #3a3a37;
    --wash: #1d1d1b;
    --lost: #ff6b6b;
    --on-ink: #131312;
    color-scheme: dark;
  }
}
* {
  box-sizing: border-box;
}
html {
  background: var(--sheet);
  scroll-behavior: smooth;
  scrollbar-color: var(--soft) var(--sheet);
}
body {
  margin: 0;
  color: var(--ink);
  background: var(--sheet);
  font: 18px / 1.6 var(--serif);
  font-variant-numeric: lining-nums;
  caret-color: var(--lost);
}
/* The page's own type is on its way for the first moments of a first visit. Text set in a stand-in face wraps
   differently and would be seen to move when the real one lands, so a script in the head keeps the page unseen
   until then, and what draws itself in on load waits as well. */
.untyped body {
  visibility: hidden;
}
.untyped * {
  animation-play-state: paused !important;
}
::selection {
  background: var(--ink);
  color: var(--on-ink);
}
a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover {
  text-decoration-color: var(--lost);
}
:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}
.skip {
  position: absolute;
  left: 16px;
  top: -60px;
  background: var(--ink);
  color: var(--on-ink);
  min-height: 44px;
  padding: 13px 14px;
  font: 700 15px var(--sans);
  z-index: 10;
}
.skip:focus {
  top: 12px;
}

/* Running head */
.running {
  display: flex;
  align-items: baseline;
  gap: 24px;
  padding: 18px max(16px, calc((100vw - var(--page)) / 2));
  border-bottom: 2px solid var(--rule);
  border-image: linear-gradient(to right, var(--rule) var(--drawn), transparent 0) 1;
  font: 15px var(--sans);
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--sheet);
  animation: rule 1.1s var(--out) both;
}
@keyframes rule {
  from {
    --drawn: 0%;
  }
}
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}
@keyframes wipe {
  from {
    clip-path: inset(0 0 100% 0);
  }
  to {
    clip-path: inset(0);
  }
}
.running b {
  font: 700 22px var(--sans);
  letter-spacing: -0.01em;
}
.running nav {
  display: flex;
  gap: 4px;
  margin-left: auto;
}
.running nav a {
  text-decoration: none;
  padding: 10px 10px;
  /* 24px of line and 20px of padding make the 44px target. As a flex box it would underline its numeral too. */
  line-height: 24px;
  display: inline-block;
  white-space: nowrap;
}
.running nav a:hover {
  text-decoration: underline;
}
.num {
  /* A box of its own, so the current link's underline runs under the name and not the numeral. */
  display: inline-block;
  margin-right: 6px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--soft);
}
.running nav a[aria-current] {
  text-decoration: underline 2px;
  text-underline-offset: 7px;
}
[aria-current] > .num {
  color: var(--ink);
}
.running > span {
  color: var(--soft);
}

main {
  max-width: var(--page);
  margin: 0 auto;
  padding: 40px 16px 96px;
}

/* Opening: title and abstract beside Figure 1 */
.opening {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 8fr);
  gap: 56px;
  align-items: start;
}
h1 {
  font: 700 clamp(32px, 3.4vw, 44px) / 1.12 var(--serif);
  letter-spacing: -0.015em;
  margin: 0 0 18px;
  text-wrap: balance;
}
.author {
  font: 16px var(--sans);
  margin: 0 0 28px;
}
.abstract-head {
  font: 700 13px var(--sans);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  border-top: 1px solid var(--rule);
  padding-top: 16px;
  margin: 0 0 10px;
}
.abstract {
  margin: 0 0 28px;
  max-width: var(--measure);
  text-wrap: pretty;
}
.front > * {
  animation: rise 0.6s var(--out) both;
}
.front > :nth-child(2) {
  animation-delay: 60ms;
}
.front > :nth-child(3) {
  animation-delay: 120ms;
}
.front > :nth-child(4) {
  animation-delay: 180ms;
}
.front > :nth-child(5) {
  animation-delay: 240ms;
}
.action {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}
.cost {
  font: 14px var(--sans);
  color: var(--soft);
}

/* Controls */
button,
select,
input,
textarea {
  font: 15px var(--sans);
  color: var(--ink);
}
button {
  min-height: 44px;
  padding: 10px 16px;
  border: 2px solid var(--ink);
  background: var(--sheet);
  cursor: pointer;
  font-weight: 700;
  transition:
    background-color 0.15s ease-out,
    color 0.15s ease-out;
}
button:hover:not(:disabled) {
  background: var(--wash);
}
button:active:not(:disabled) {
  transform: translateY(1px);
}
button.go {
  background: var(--ink);
  color: var(--on-ink);
}
button.go:hover:not(:disabled) {
  background: var(--ink);
  box-shadow: 0 3px 0 -1px var(--lost);
}
button:disabled {
  border-style: dashed;
  color: var(--soft);
  border-color: var(--soft);
  cursor: not-allowed;
}
textarea,
select,
input[type="text"] {
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  border-radius: 0;
  padding: 10px 12px;
  min-height: 44px;
}
textarea {
  width: 100%;
  min-height: 72px;
  resize: vertical;
  font-size: 16px;
}
input[type="text"] {
  width: 100%;
  font-size: 16px;
}
select {
  appearance: none;
  border-width: 2px;
  padding-right: 40px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(135deg, var(--ink) 50%, transparent 50%);
  background-position:
    right 20px center,
    right 14px center;
  background-size: 6px 6px;
  background-repeat: no-repeat;
  cursor: pointer;
}
select:hover {
  background-color: var(--wash);
}
input[type="range"] {
  accent-color: var(--ink);
  width: 200px;
  min-height: 44px;
  margin: 0;
}
label.f {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font: 14px var(--sans);
  color: var(--soft);
}
label.f output {
  color: var(--ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 18px;
  align-items: flex-end;
}
.grow {
  flex: 1 1 280px;
}
#r-form {
  margin-bottom: 8px;
}

/* Figures */
.fig {
  margin: 0;
  min-width: 0;
}
figcaption {
  font: 15px / 1.5 var(--sans);
  margin-top: 14px;
  max-width: 72ch;
  text-wrap: pretty;
  transition: opacity 0.5s ease-out 0.4s;
}
/* Room for the longest thing Figure 1 says under itself, so the readout stays put when the line changes. */
#figure-1 figcaption {
  min-height: 3lh;
  font-variant-numeric: tabular-nums;
}
.sheet {
  border-top: 2px solid var(--rule);
  border-bottom: 2px solid var(--rule);
  padding: 18px 0 16px;
}
/* A figure's heavy rules are ruled across it from the left when it first comes into view. */
.sheet,
.split,
canvas {
  border-image: linear-gradient(to right, var(--rule) var(--drawn), transparent 0) 1;
}
.fig {
  transition: --drawn 1.1s var(--out);
}
.fig.unruled {
  --drawn: 0%;
}
#figure-1 {
  animation: rule 1.1s var(--out) 0.15s both;
}
.fig.unruled :is(.callouts li, figcaption) {
  opacity: 0;
}
.fig :is(svg.grid, .lens) {
  /* Only filled backwards, as a clip left on afterwards would cut off the focus outline. */
  animation: wipe 0.8s var(--out) 0.2s backwards;
}
.fig.unruled :is(svg.grid, .lens) {
  animation-play-state: paused;
}
.models {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font: 14px var(--sans);
  color: var(--soft);
  margin-bottom: 12px;
}
.models b {
  color: var(--ink);
}
.out {
  font: 19px / 2.2 var(--sans);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  min-height: 2.2em;
}
/* The box is as tall as the tallest of the unseen copies in its room, which is the whole run laid out ahead. */
.out-box,
.room {
  display: grid;
}
.out-box > *,
.room > * {
  grid-area: 1 / 1;
  min-width: 0;
}
.room {
  visibility: hidden;
}
.out span {
  padding: 3px 1px;
  outline: 1.5px solid transparent;
  outline-offset: -1px;
  transition:
    opacity 0.14s ease-out,
    outline-color 0.14s ease-out,
    color 0.14s ease-out;
  @starting-style {
    opacity: 0;
  }
}
.out .guess {
  outline-style: dashed;
  outline-color: var(--ink);
}
.out .kept {
  outline-color: var(--ink);
}
.out .miss {
  outline: 2px dashed var(--lost);
  color: var(--lost);
  text-decoration: line-through;
}
.out .own {
  font-weight: 700;
}
.out .w {
  font-weight: inherit;
  padding: 3px 0;
  transition: background-size 0.3s var(--out);
}
/* The rule goes under the word and not the space before it, which would leave a stub where a line breaks. */
.out .own .w {
  background: linear-gradient(var(--ink), var(--ink)) no-repeat 0 100% / 100% 3px;
  @starting-style {
    background-size: 0 3px;
  }
}
#figure-1 :is(.out-box, .race, .callouts),
#figure-1 > :not(.sheet),
.opening ~ * {
  transition: opacity 0.3s ease-out;
}
/* Every figure takes its size from a file the page has to fetch, so what would be pushed down waits unseen and
   never shows in one place and then in another. Under Figure 1's box that is until its run is known, and after
   the opening it is until all four figures are laid out. With scripts off nothing waits. If a script fails and
   never sizes them, it all shows itself after 8 seconds, and that has to hold with reduced motion too. */
@media (scripting: enabled) {
  #figure-1.unsized :is(.race, .callouts),
  #figure-1.unsized > :not(.sheet),
  .opening.unsized ~ * {
    opacity: 0;
    animation: late 0.01s 8s forwards !important;
  }
  /* The rule under the sheet would be seen dropping as well, so it is left off until then. */
  #figure-1.unsized .sheet {
    border-image-width: 1 1 0;
  }
}
@keyframes late {
  to {
    opacity: 1;
  }
}
/* The last run waits, dimmed, while a new one is worked out. */
#figure-1.stale :is(.out-box, .race, .readout) {
  opacity: 0.3;
}
.out .gone {
  opacity: 0;
}
/* A token is laid out before it is written and only shown then, so that no word is ever seen to move. */
.out .wait {
  opacity: 0;
  visibility: hidden;
}
.out .wait .w {
  background-size: 0 3px;
}
/* The guesses the big model turns down, in a layer over the text. */
.out.over {
  pointer-events: none;
  user-select: none;
}
.out .after {
  color: var(--soft);
}
.q-out {
  min-height: 0;
  font-size: 17px;
}
.q-say {
  margin: 16px 0 4px;
  font: 15px / 1.5 var(--sans);
  min-height: 2lh;
}
.table-wrap {
  overflow-x: auto;
  margin-top: 18px;
}
.runs {
  width: 100%;
  border-collapse: collapse;
  font: 14px var(--sans);
  font-variant-numeric: tabular-nums;
}
.runs th {
  font-weight: 400;
  color: var(--soft);
  text-align: right;
  padding: 6px 0 8px 16px;
  border-bottom: 1px solid var(--rule);
  vertical-align: bottom;
}
.runs td {
  text-align: right;
  padding: 4px 0 4px 16px;
  border-bottom: 1px solid var(--faint);
}
.runs th:first-child,
.runs td:first-child {
  text-align: left;
  padding-left: 0;
}
.runs button {
  white-space: nowrap;
}
.lens-split {
  grid-template-columns: minmax(0, 1fr) 190px;
  margin-top: 16px;
}
.lens-wrap {
  overflow-x: auto;
}
.lens {
  display: grid;
  grid-template-columns: 28px repeat(var(--cols), minmax(52px, 1fr));
  gap: 2px;
  font: 12px var(--sans);
}
.lens > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: pre;
  line-height: 18px;
  padding: 0 4px;
}
.l-head {
  font-weight: 700;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--rule);
}
.l-layer {
  color: var(--soft);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.l-cell {
  outline: 1px solid var(--faint);
  outline-offset: -1px;
  cursor: default;
}
.l-cell.on {
  color: var(--sheet);
}
.l-cell[aria-current] {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}
.l-top {
  list-style: none;
  padding: 0;
  margin: 0;
  font: 14px var(--sans);
  font-variant-numeric: tabular-nums;
}
.l-top li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  margin-bottom: 10px;
}
.l-tok {
  font-weight: 700;
  white-space: pre;
  overflow: hidden;
  text-overflow: ellipsis;
}
.l-bar {
  grid-column: 1 / -1;
  height: 6px;
  background: var(--ink);
  transform-origin: left;
  transition: transform 0.3s var(--out);
}
#l-where {
  min-height: 2lh;
}
.k.ring-box {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}
.callouts {
  list-style: none;
  padding: 0;
  margin: 14px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  font: 14px var(--sans);
}
.callouts li {
  transition: opacity 0.5s ease-out 0.4s;
  display: grid;
  grid-template-columns: auto auto 1fr;
  align-items: baseline;
}
.callouts b {
  font-weight: 700;
  margin-right: 6px;
  font-variant-numeric: tabular-nums;
}
.k {
  display: inline-block;
  width: 22px;
  height: 14px;
  margin-right: 8px;
  vertical-align: -2px;
}
.k.guess {
  border: 1.5px dashed var(--ink);
}
.k.kept {
  border: 1.5px solid var(--ink);
}
.k.miss {
  border: 2px dashed var(--lost);
}
.k.own {
  border-bottom: 3px solid var(--ink);
}
.k.pick {
  background: var(--ink);
}
.k.shared {
  background: radial-gradient(circle, var(--sheet) 0 2.5px, var(--ink) 3px);
}
.k.heat {
  background: var(--faint);
}
.k.dot {
  background: radial-gradient(circle, var(--ink) 0 3px, transparent 3.5px);
}
.k.tick {
  background: linear-gradient(var(--ink), var(--ink)) center / 10px 2px no-repeat;
}
.k.err {
  background: linear-gradient(var(--lost), var(--lost)) center / 2px 100% no-repeat;
}
.k.level {
  border-top: 1px solid var(--faint);
  border-bottom: 1px solid var(--faint);
}
.bar {
  height: 2px;
  margin-top: 10px;
  background: var(--faint);
  overflow: hidden;
}
.bar i {
  display: block;
  height: 100%;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.25s ease-out;
}
.race {
  margin-top: 18px;
  font: 14px var(--sans);
}
.lane {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  margin-top: 10px;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}
.lane span {
  color: var(--ink);
}
.lane .bar {
  grid-column: 1 / -1;
  height: 8px;
  margin-top: 0;
}
.alone {
  border-top: 1px solid var(--faint);
  padding-top: 12px;
  margin-bottom: 18px;
}
.alone .models {
  margin: 0 0 4px;
}
.lane-text {
  margin: 0;
  font: 16px / 1.6 var(--sans);
  white-space: pre-wrap;
  color: var(--ink);
}
/* Every word is laid out from the start and only shown when its token is done, so the text never reflows. */
.lane-text span {
  opacity: 0;
  transition: opacity 0.18s ease-out;
}
.lane-text span.on {
  opacity: 1;
}
.race-note {
  margin: 12px 0 0;
  color: var(--soft);
  max-width: 72ch;
  opacity: 0;
  transition: opacity 0.4s ease-out;
}
.race-note.on {
  opacity: 1;
}

/* Readout */
.readout {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  column-gap: 24px;
  margin: 18px 0 0;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
canvas {
  width: 100%;
  /* The height its script draws it at. Left to its attributes it would start much taller and drop on the first drawing. */
  height: 320px;
  display: block;
  border-top: 2px solid var(--rule);
  border-bottom: 2px solid var(--rule);
}
canvas + .readout,
.readout + canvas,
.bar + .readout {
  margin-top: 0;
  border-top: 0;
}
.readout > div {
  padding: 10px 0 12px;
}
.readout dt {
  font: 13px var(--sans);
  color: var(--soft);
}
.readout dd {
  margin: 2px 0 0;
  font: 700 26px / 1.2 var(--sans);
  font-variant-numeric: tabular-nums;
}
.readout .hist-cell {
  grid-column: span 2;
}
.hist {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  height: 60px;
  padding-bottom: 20px;
}
.hist div {
  flex: 1;
  /* as wide as one of the recorded run's four, so the live run's single bar does not fill the cell */
  max-width: calc((100% - 18px) / 4);
  height: 36px;
  position: relative;
}
/* The bar is always full height and scaled down to its share, so a change repaints it and lays nothing out. */
.hist div::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ink);
  transform: scaleY(max(var(--kept, 0), 0.055));
  transform-origin: bottom;
  transition: transform 0.2s var(--out);
}
.hist div::after {
  content: attr(data-l);
  position: absolute;
  bottom: -18px;
  left: 0;
  right: 0;
  text-align: center;
  font: 12px var(--sans);
  color: var(--soft);
}
details.controls {
  margin-top: 16px;
  border-bottom: 1px solid var(--faint);
}
details.controls summary {
  font: 700 15px var(--sans);
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
}
details.controls {
  interpolate-size: allow-keywords;
}
details.controls::details-content {
  block-size: 0;
  overflow-y: clip;
  transition:
    block-size 0.35s var(--out),
    content-visibility 0.35s allow-discrete;
}
details.controls[open]::details-content {
  block-size: auto;
}
details.controls > .row {
  margin: 8px 0 18px;
}
details.controls > .cost {
  margin: 8px 0 18px;
  line-height: 1.5;
}

/* Parts after the opening */
.part {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 9fr);
  gap: 56px;
  margin-top: 112px;
  scroll-margin-top: 96px;
  align-items: start;
}
.opening {
  scroll-margin-top: 96px;
}
.part h2 {
  font: 700 30px / 1.15 var(--serif);
  letter-spacing: -0.01em;
  margin: 0 0 14px;
  text-wrap: balance;
}
.part p {
  margin: 0 0 16px;
  max-width: var(--measure);
  text-wrap: pretty;
}
.side-note {
  font: 15px / 1.55 var(--sans);
  color: var(--soft);
}
.chips {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.chip {
  font-weight: 400;
  border-width: 1.5px;
}
button.chip[aria-pressed="true"] {
  background: var(--ink);
  color: var(--on-ink);
}
.times {
  margin-left: 8px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.times::after {
  content: "\00d7";
  font-weight: 400;
}
.toks {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 16px 0;
}
.tok {
  min-height: 36px;
  min-width: 28px;
  padding: 4px 9px;
  font-weight: 400;
  border-width: 1px;
  border-color: var(--faint);
  white-space: pre;
}
/* The current token changes colour and never size, as a wider one would push the rest of the row along. */
button.tok[aria-current="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--on-ink);
}
.tok.partial {
  border-style: dashed;
  color: var(--soft);
}
button.tok.partial[aria-current="true"] {
  background: var(--soft);
  border-color: var(--soft);
  color: var(--on-ink);
}
#r-cur.partial {
  color: var(--soft);
}
@media (pointer: coarse) {
  .tok {
    min-height: 44px;
    min-width: 44px;
  }
}
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  gap: 24px;
  border-top: 2px solid var(--rule);
  border-bottom: 2px solid var(--rule);
  padding: 16px 0;
}
svg.grid {
  width: 100%;
  height: auto;
  display: block;
}
.side-actions {
  gap: 8px;
}
.side p {
  margin: 0 0 14px;
  font: 15px / 1.5 var(--sans);
}
#r-share {
  min-height: 3lh;
}
.big {
  font: 700 34px / 1.1 var(--sans);
  overflow-wrap: anywhere;
}
.controls-row {
  margin-bottom: 16px;
}
.tip {
  position: fixed;
  pointer-events: none;
  background: var(--sheet);
  border: 1.5px solid var(--ink);
  padding: 6px 10px;
  font: 14px var(--sans);
  opacity: 0;
  transition: opacity 0.1s ease-out;
  z-index: 5;
}
footer {
  margin-top: 112px;
  padding-top: 16px;
  border-top: 2px solid var(--rule);
  font: 15px var(--sans);
  color: var(--soft);
}
footer a:any-link {
  color: var(--ink);
}

@media (max-width: 960px) {
  .opening,
  .part {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .part {
    margin-top: 80px;
  }
}
@media (max-width: 600px) {
  body {
    font-size: 17px;
  }
  .running {
    flex-wrap: wrap;
    gap: 0 16px;
    padding-top: 10px;
    padding-bottom: 6px;
  }
  .running > span {
    display: none;
  }
  .running {
    position: static;
  }
  .running nav {
    margin-left: 0;
    width: 100%;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0;
  }
  .num {
    margin-right: 4px;
  }
  .part,
  .opening {
    scroll-margin-top: 24px;
  }
  #figure-1 figcaption {
    min-height: 5lh;
  }
  #r-share {
    min-height: 2lh;
  }
  #l-where {
    min-height: 0;
  }
  .running nav a {
    padding: 10px 6px;
  }
  .running nav a:first-child {
    padding-left: 0;
  }
  .running nav a:last-child {
    padding-right: 0;
  }
  .split {
    grid-template-columns: 1fr;
  }
  .readout .hist-cell,
  #s-fast-cell {
    grid-column: 1 / -1;
  }
  .models {
    flex-direction: column;
    gap: 2px;
  }
  input[type="range"] {
    width: 100%;
  }
  .row > label.f:not(.grow) {
    flex: 1 1 140px;
  }
}
@media (pointer: coarse) {
  .lens > span {
    line-height: 26px;
  }
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after,
  details.controls::details-content {
    animation: none !important;
    transition: none !important;
  }
}
svg .g-label {
  fill: var(--soft);
  font-family: var(--sans);
  font-size: var(--label, 22px);
  font-variant-numeric: tabular-nums;
}
svg .g-cell {
  fill: none;
  stroke: var(--faint);
  stroke-width: 1;
}
svg .g-heat,
svg .g-pick {
  fill: var(--ink);
}
/* A token's picks come up layer after layer, the order the forward pass makes them in. */
svg .g-pick,
svg .g-ring {
  transition: opacity 0.18s ease-out calc(var(--l) * 8ms);
}
svg .g-heat {
  transition: fill-opacity 0.4s ease-out;
}
svg .g-ring {
  fill: var(--sheet);
}
svg .g-focus .g-cell {
  stroke: var(--ink);
  stroke-width: 2.5;
}
