/* Neural Atlas — centered dithered specimen, docking into a reading rail */

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/IBMPlexMono-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/IBMPlexMono-500.woff2") format("woff2");
}
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/InstrumentSerif-400.woff2") format("woff2");
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/InstrumentSerif-400i.woff2") format("woff2");
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("assets/fonts/SpaceGrotesk-300.woff2") format("woff2");
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/SpaceGrotesk-400.woff2") format("woff2");
}
@font-face {
  font-family: "Space Grotesk";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("assets/fonts/SpaceGrotesk-500.woff2") format("woff2");
}
/* Candidate faces for the type pass. Each ships as a single variable file, so
   one request covers every weight the page asks for. Switch between them with
   ?font=<key> — see the --face block below for the keys. */
/* Benne — the face situational-awareness.ai sets its whole site in. It ships a
   single 400 cut, so the bold headings there are synthesised by the browser;
   this page does the same rather than substituting a different bold serif. */
@font-face {
  font-family: "Benne";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/Benne-400.woff2") format("woff2");
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/Geist-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/Inter-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/IBMPlexSans-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/Manrope-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/PublicSans-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Work Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/WorkSans-var.woff2") format("woff2-variations");
}
@font-face {
  font-family: "Figtree";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("assets/fonts/Figtree-var.woff2") format("woff2-variations");
}

:root {
  --paper: #f2f2f0;
  --ink: #1c1c19;
  --ink-2: #55554f;
  --ink-3: #8f8f88;
  /* The stack the other sites run on, copied rather than approximated, so the
     atlas reads as part of the same set. One face drives the whole page: the
     serif/sans/mono split still carries every size, weight, and letter-spacing
     decision, so splitting them again means editing only these three lines. */
  --face: "Century Gothic", CenturyGothic, "URW Gothic", AppleGothic,
    ui-rounded, "Avenir Next", Avenir, system-ui, sans-serif;
  --serif: var(--face);
  --sans: var(--face);
  --mono: var(--face);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --chrome-x: clamp(20px, 3vw, 44px);
  /* Left rail: roughly the left quarter, with the specimen docked in its top. */
  --rail-w: clamp(268px, 28vw, 380px);
  --rail-well-h: clamp(196px, 27vh, 268px);
  --article-w: min(700px, calc(100% - var(--rail-w) - var(--chrome-x) * 2));
}

/* Century Gothic's tuning, taken from the other sites rather than invented
   here: bold headings pulled tight, body set open and a touch loose. Scoped so
   the ?font= candidates below keep their own. */
:root[data-font="benne"] {
  --face: "Benne", "Iowan Old Style", Georgia, serif;
}
:root:not([data-font]) .headline,
:root:not([data-font]) .article-title,
:root:not([data-font]) .references-title {
  font-weight: 700;
  letter-spacing: -0.024em;
}
:root:not([data-font]) .article .reader-body p {
  letter-spacing: 0.005em;
  line-height: 1.72;
}

/* Type candidates. ?font=<key> stamps data-font on <html>; everything else in
   the sheet reads through --face and follows. */
:root[data-font="geist"] { --face: "Geist"; }
:root[data-font="inter"] { --face: "Inter"; }
:root[data-font="plex"] { --face: "IBM Plex Sans"; }
:root[data-font="manrope"] { --face: "Manrope"; }
:root[data-font="public"] { --face: "Public Sans"; }
:root[data-font="work"] { --face: "Work Sans"; }
:root[data-font="figtree"] { --face: "Figtree"; }
:root[data-font="grotesk"] { --face: "Space Grotesk"; }

* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  min-height: 100%;
}

body {
  margin: 0;
  overflow-x: hidden;
  overflow-y: auto;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--ink);
  color: var(--paper);
}

button,
a {
  color: inherit;
  font: inherit;
}

button:focus-visible,
a:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 3px;
}

/* ------------------------------------------------------------------ */
/* Loading veil                                                       */
/* ------------------------------------------------------------------ */

.veil {
  position: fixed;
  z-index: 100;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper);
  opacity: 1;
  transition: opacity 0.55s ease, visibility 0.55s;
}

body[data-model-state="ready"] .veil {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.veil-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.veil-mark {
  width: 7px;
  height: 7px;
  border: 1px solid var(--ink-2);
  transform: rotate(45deg);
  animation: veil-pulse 1.1s ease-in-out infinite;
}

body[data-model-state="error"] .veil-mark {
  animation: none;
  background: var(--ink-3);
}

/* No-WebGL fallback: drop the veil, keep the editorial content readable */
body[data-model-state="fallback"] .veil {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

body[data-model-state="fallback"] #scene,
body[data-model-state="fallback"] .rail {
  display: none;
}

@keyframes veil-pulse {
  0%,
  100% {
    opacity: 0.25;
  }
  50% {
    opacity: 1;
  }
}

/* ------------------------------------------------------------------ */
/* Stage                                                              */
/* ------------------------------------------------------------------ */

/* Fixed layer holding the specimen. Pointer events are off by default so the
   page scrolls freely; the hero state switches them on for orbiting. */
.specimen {
  position: fixed;
  z-index: 25;
  inset: 0;
  pointer-events: none;
  /* The numbers are plain text now that they are labels rather than buttons, so
     a drag across the specimen would otherwise select them and invert them
     mid-turn. The article below keeps its own selection. */
  -webkit-user-select: none;
  user-select: none;
}

.specimen.interactive {
  cursor: grab;
  pointer-events: auto;
  touch-action: none;
}

.specimen.interactive.dragging {
  cursor: grabbing;
}

.dock-grab {
  position: absolute;
  z-index: 18;
  top: 0;
  left: 0;
  width: var(--rail-w);
  height: var(--rail-well-h);
  pointer-events: none;
}

.specimen.docked .dock-grab {
  cursor: grab;
  pointer-events: auto;
  touch-action: none;
}

.specimen.docked.dragging .dock-grab {
  cursor: grabbing;
}

#scene {
  position: absolute;
  z-index: 5;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  outline: none;
  touch-action: none;
}

/* ------------------------------------------------------------------ */
/* Headline — single line, top centre, clear of both readers          */
/* ------------------------------------------------------------------ */

.headline {
  position: absolute;
  z-index: 20;
  top: clamp(20px, 2.8vh, 34px);
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(22px, 1.85vw, 30px);
  font-weight: 400;
  letter-spacing: -0.018em;
  line-height: 1.15;
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
}

/* The reveal choreography also translates the headline, so the centring
   transform has to be restated at both ends of that transition. */
.headline.reveal-item {
  transform: translateX(-50%) translateY(16px);
}

.headline em {
  font-style: italic;
}

/* Reveal choreography */
.reveal-item {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s ease, transform 0.85s var(--ease-out);
}

body[data-model-state="ready"] .reveal-item,
body[data-model-state="error"] .reveal-item,
body[data-model-state="fallback"] .reveal-item {
  opacity: 1;
  transform: translateY(0);
}

body[data-model-state="ready"] .headline.reveal-item {
  transition-delay: 0.08s;
}

/* ------------------------------------------------------------------ */
/* Flow, hero, and article                                            */
/* ------------------------------------------------------------------ */

.flow {
  position: relative;
  z-index: 10;
}

.hero {
  position: relative;
  height: 100dvh;
  pointer-events: none;
}

/* Progress 0 at the top of the page, 1 once the specimen has docked. JS writes
   it every frame; everything below reads from it, so the whole transition is a
   single interpolated value rather than a class flip. */
:root {
  --p: 0;
}

/* The reveal choreography sets `opacity: 1` from a body-state selector, which
   outranks a bare `.headline` rule — so the scroll fade has to be stated at
   the same specificity or it never applies. Transitions are shortened here so
   the headline tracks the scroll instead of trailing 0.7s behind it. */
body[data-model-state="ready"] .headline.reveal-item,
body[data-model-state="error"] .headline.reveal-item,
body[data-model-state="fallback"] .headline.reveal-item {
  opacity: calc(1 - var(--p) * 1.6);
  transform: translateX(-50%) translateY(calc(var(--p) * -46px)) scale(calc(1 - var(--p) * 0.14));
  transform-origin: top center;
  transition: opacity 0.22s ease, transform 0.28s var(--ease-out);
  will-change: opacity, transform;
}

.scroll-cue {
  position: absolute;
  bottom: clamp(24px, 5vh, 54px);
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: calc(1 - var(--p) * 2.4);
  transform: translateX(-50%);
}

.scroll-cue-rule {
  width: 1px;
  height: clamp(20px, 4vh, 40px);
  background: linear-gradient(to bottom, transparent, var(--ink-3));
}

/* ------------------------------------------------------------------ */
/* Left rail — docked specimen above the section index                */
/* ------------------------------------------------------------------ */

/* Above the specimen layer, so the controls in the well are not buried under
   the drag patch. The container itself stays transparent to the pointer and
   only its interactive children opt back in — otherwise the empty part of the
   well would swallow the drags that rotate the docked specimen. */
.rail {
  position: fixed;
  z-index: 30;
  top: 0;
  left: 0;
  width: var(--rail-w);
  height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: 0 clamp(16px, 1.6vw, 26px) clamp(20px, 4vh, 44px);
  opacity: var(--p);
  pointer-events: none;
  transform: translateX(calc((1 - var(--p)) * -18px));
}

.rail.live .rail-list,
.rail.live .spin-toggle {
  pointer-events: auto;
}

/* The space the specimen docks into; the index starts below it. */
.rail-well {
  position: relative;
  flex: 0 0 auto;
  height: var(--rail-well-h);
}

/* Sits in the corner of the well, beside the docked specimen. */
.spin-toggle {
  position: absolute;
  right: 0;
  bottom: 4px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 7px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: color 0.18s ease, border-color 0.18s ease, opacity 0.18s ease;
}

.spin-toggle svg {
  width: 15px;
  height: 15px;
}

.spin-toggle:hover {
  color: var(--ink-2);
  border-color: color-mix(in srgb, var(--ink-3) 40%, transparent);
}

/* Off reads as dimmed rather than as a different control. */
.spin-toggle[aria-pressed="false"] {
  color: color-mix(in srgb, var(--ink-3) 55%, transparent);
}

.spin-toggle[aria-pressed="false"] svg {
  opacity: 0.5;
}

.rail-list {
  flex: 1 1 auto;
  padding-top: clamp(14px, 2.2vh, 26px);
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.rail-list::-webkit-scrollbar {
  width: 0;
  display: none;
}

/* One row per section: icon, name, and the anatomy it maps onto. */
.tile {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 13px;
  width: 100%;
  padding: 11px 12px;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  text-align: left;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.tile:hover {
  background: color-mix(in srgb, var(--tile-accent) 14%, transparent);
  color: var(--ink);
}

.tile[aria-pressed="true"] {
  background: color-mix(in srgb, var(--tile-accent) 18%, transparent);
  color: var(--ink);
}

/* Square swatch, one-to-one, carrying the number the specimen drops. */
.tile-icon {
  position: relative;
  width: clamp(36px, 3.2vw, 46px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--tile-accent) 45%, transparent);
  background: color-mix(in srgb, var(--tile-accent) 14%, transparent);
}

.tile[aria-pressed="true"] .tile-icon {
  border-color: var(--tile-accent);
  background: color-mix(in srgb, var(--tile-accent) 58%, transparent);
}

.icon-glyph {
  position: relative;
  width: 60%;
  height: 60%;
  color: color-mix(in srgb, var(--tile-accent) 60%, var(--ink));
}

.tile[aria-pressed="true"] .icon-glyph {
  color: var(--ink);
}

.tile-text {
  min-width: 0;
}

.tile-title {
  display: block;
  font-size: clamp(15px, 1.2vw, 17.5px);
  line-height: 1.28;
}

.tile-anatomy {
  display: block;
  margin-top: 2px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: clamp(11px, 0.86vw, 12.5px);
  letter-spacing: 0.02em;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* Article — one column, under the docked specimen                     */
/* ------------------------------------------------------------------ */

.article {
  position: relative;
  width: var(--article-w);
  /* Centred on the screen, not in the gap beside the rail — the two only differ
     when the viewport is narrow, where the max() pushes it clear of the rail
     instead of letting them overlap. */
  margin: 0 0 0
    max(calc(var(--rail-w) + 20px), calc((100% - var(--article-w)) / 2));
  padding: clamp(20px, 4vh, 48px) 0 clamp(80px, 16vh, 180px);
}

.article-title {
  margin: 0 0 10px;
  font-family: var(--serif);
  font-size: clamp(32px, 3.1vw, 46px);
  font-weight: 400;
  letter-spacing: -0.022em;
  line-height: 1.06;
}

/* The break at the end of the essay, before the references. */
.article-rule {
  width: 100%;
  height: 0;
  margin: 58px 0 34px;
  border: 0;
  border-top: 1px solid color-mix(in srgb, var(--ink-3) 34%, transparent);
}

.article .reader-heading {
  margin: 0 0 26px;
  font-size: clamp(25px, 2.05vw, 33px);
  letter-spacing: -0.017em;
  line-height: 1.14;
}

.article .reader-body p {
  margin-bottom: 1.15em;
  font-size: clamp(16px, 1.12vw, 17.5px);
  line-height: 1.78;
  letter-spacing: 0.002em;
  color: color-mix(in srgb, var(--ink) 82%, var(--ink-2));
}

/* Figures breathe, and sit centred rather than shunted to one side. */
.article .reader-figure {
  width: min(100%, 460px);
  margin: 38px auto 42px;
}

.article .reader-figure figcaption {
  margin-top: 12px;
  text-align: center;
  font-size: 13px;
  line-height: 1.5;
}

/* References: numbered to match the superscripts in the prose, title as the
   link, author and year underneath. */
.references {
  margin: 0;
}

.references-title {
  margin: 0 0 22px;
  font-size: clamp(17px, 1.28vw, 20px);
  font-weight: 700;
  letter-spacing: -0.012em;
  line-height: 1.2;
}

.reference-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.reference-list li {
  display: grid;
  grid-template-columns: 2.6em 1fr;
  gap: 0 14px;
  margin: 0 0 14px;
  padding: 0;
  align-items: baseline;
}

.reference-list li:last-child {
  margin-bottom: 0;
}

/* Bracketed to match the citations in the prose, so [4] in a sentence and [4]
   in the list are visibly the same mark. */
.ref-num {
  color: color-mix(in srgb, var(--ink) 78%, var(--ink-2));
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.ref-num::before {
  content: "[";
}

.ref-num::after {
  content: "]";
}

/* The papers the section is actually about carry its colour. The accent is
   pulled well down into the ink first: at full strength these read as a pale
   wash rather than as a number. */
.reference-list .is-key .ref-num {
  color: color-mix(in srgb, var(--article-accent, var(--ink)) 42%, var(--ink));
}

.reference-list .is-key a {
  font-weight: 700;
}

.ref-main {
  min-width: 0;
}

.reference-list a {
  color: var(--ink);
  font-size: 15px;
  line-height: 1.45;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s ease;
}

.reference-list a:hover {
  border-bottom-color: color-mix(in srgb, var(--article-accent, var(--ink-3)) 65%, transparent);
}

.ref-lab {
  display: block;
  margin-top: 3px;
  color: var(--ink-3);
  font-size: 13px;
  line-height: 1.4;
}

/* Inline citation: a bracketed superscript numeral keyed to the list
   underneath. The brackets are drawn here rather than written into the text, so
   the link's own content stays the bare number.

   Colour is mostly ink with the section's accent mixed in behind it. The accent
   at full strength is a pastel by design, which is right for a wash across the
   cortex and much too faint for a 10px numeral inside a line of prose. */
.cite {
  display: inline-block;
  margin-left: 1px;
  color: color-mix(in srgb, var(--article-accent, var(--ink)) 34%, var(--ink));
  font-size: 0.68em;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1;
  text-decoration: none;
  vertical-align: super;
}

.cite::before {
  content: "[";
}

.cite::after {
  content: "]";
}

.cite:hover {
  color: var(--ink);
  text-decoration: underline;
}

/* Each block staggers in so the article assembles rather than blinking on;
   --stagger is set per element as the content is built. */
.article.drawing .reader-block {
  animation: reader-content-in 0.19s var(--ease-out) both;
  animation-delay: calc(0.04s + var(--stagger, 0) * 0.015s);
}

@keyframes reader-content-in {
  from {
    opacity: 0;
    transform: translateY(5px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ------------------------------------------------------------------ */
/* Figures — inline diagrams in the specimen's own drawing language    */
/* ------------------------------------------------------------------ */

.reader-figure {
  margin: 0 0 22px;
}

.reader-figure svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

.reader-figure figcaption {
  margin-top: 9px;
  color: var(--ink-3);
  font-size: 11.5px;
  font-style: italic;
  line-height: 1.4;
}

/* Shared primitives across every diagram type. */
.fig-hair {
  fill: none;
  stroke: color-mix(in srgb, var(--ink-3) 62%, transparent);
  stroke-width: 0.7;
}

.fig-rule {
  fill: none;
  stroke: color-mix(in srgb, var(--ink-3) 40%, transparent);
  stroke-width: 0.6;
}

.fig-link {
  fill: none;
  stroke: color-mix(in srgb, var(--reader-accent) 52%, var(--ink-3));
  stroke-width: 0.7;
}

.fig-link-strong {
  fill: none;
  stroke: color-mix(in srgb, var(--reader-accent) 88%, var(--ink));
  stroke-width: 1.15;
}

.fig-node {
  fill: color-mix(in srgb, var(--paper) 88%, var(--ink-3));
  stroke: color-mix(in srgb, var(--ink-3) 70%, transparent);
  stroke-width: 0.7;
}

.fig-node-on {
  fill: var(--reader-accent);
  stroke: color-mix(in srgb, var(--reader-accent) 60%, var(--ink));
  stroke-width: 0.7;
}

.fig-fill {
  fill: color-mix(in srgb, var(--reader-accent) 30%, transparent);
  stroke: none;
}

.fig-fill-strong {
  fill: color-mix(in srgb, var(--reader-accent) 74%, transparent);
  stroke: none;
}

.fig-cell {
  fill: color-mix(in srgb, var(--ink-3) 16%, transparent);
}

.fig-cell-on {
  fill: color-mix(in srgb, var(--reader-accent) 82%, transparent);
}

.fig-curve {
  fill: none;
  stroke: color-mix(in srgb, var(--reader-accent) 90%, var(--ink));
  stroke-width: 1.3;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.fig-curve-ghost {
  fill: none;
  stroke: color-mix(in srgb, var(--ink-3) 55%, transparent);
  stroke-width: 0.9;
  stroke-dasharray: 2.5 2.5;
}

.fig-tick {
  fill: var(--ink-3);
  font-family: var(--mono);
  font-size: 7.5px;
  letter-spacing: 0.04em;
}

/* Diagram labels — lowercase and set in the page's own mono, so they read as
   part of the drawing rather than as chrome bolted on top of it. */
.fig-label {
  fill: var(--ink-2);
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: 0.02em;
}

/* Halftone wash, so diagrams belong to the same print as the specimen. */
.fig-dots {
  fill: color-mix(in srgb, var(--reader-accent) 62%, var(--ink));
}

/* ------------------------------------------------------------------ */
/* Responsive                                                         */
/* ------------------------------------------------------------------ */

/* The headline centres via left:50% + translateX(-50%), so these breakpoints
   constrain it with max-width rather than setting left/right, which would
   fight the centring transform. */
@media (max-width: 1120px) {
  .headline {
    max-width: min(420px, 42vw);
    font-size: clamp(18px, 2.1vw, 24px);
    white-space: normal;
  }
}

@media (max-width: 860px) {
  :root {
    --rail-w: clamp(210px, 34vw, 280px);
  }

  .article {
    --article-w: calc(100% - var(--rail-w) - var(--chrome-x) * 2);
  }

  .reader-body p {
    font-size: 13.5px;
  }
}

@media (max-width: 720px) {
  .headline {
    top: 18px;
    max-width: calc(100% - 32px);
    font-size: clamp(20px, 5.4vw, 26px);
    white-space: normal;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
