/* =============================================================
   PAPER MOON PRESS
   An independent publishing studio.

   Design system, entirely local to this world:
     paper   #F4EAD7   warm, slightly yellowed stock
     ink     #171717   letterpress black, never pure
     cobalt  #2F4DB8   plate 1 — structural, editorial
     tomato  #E95A4F   plate 2 — corrections, emphasis
     pencil  #8A857A   annotations, marks, marginalia
     fluor   #F2E85C   plate 3 — crop only, never printed

  Type — the press owns no images, so every word is set, and everything
  is set twice over: a display face for titles, a text face for running
  matter, and the typewriter for the numbers. There is no sans on this
  page at all, which is the whole argument.

    display   Perpetua first: Gill's 1929 chiseled roman, cut for slow
              reading and old-style figures, then Baskerville and
              Caslon behind it. Deliberately not the Iowan/Palatino
              house faces the other nine worlds reach for.
    text      Charter: a face drawn by hand for setting in ink, with
              the sturdy low-contrast shapes a press run wants.
    annot     Courier: the typewriter the press actually owns.

   Shape language: rules, crop marks, registration crosses,
   square corners, printed sheets. No rounded anything, no
   shadows pretending to be depth — only ink spread.
   ============================================================= */

:root {
  --paper:    #F4EAD7;
  --paper-2:  #EDE0C7;
  --paper-3:  #E5D5B6;
  --ink:      #171717;
  --cobalt:   #2F4DB8;
  --tomato:   #E95A4F;
  --pencil:   #8A857A;
  --fluor:    #F2E85C;

  /* Source Serif 4 leads: the opsz axis runs 8-60, so the display face
     genuinely tracks small sizes and still holds colour at 10.5rem. Every
     name behind it is Monotype/Apple/Adobe/Windows-only and must not lead
     the stack — behind a dead name the webfont would never be reached. */
  --serif: "Source Serif 4", Perpetua, "Perpetua Titling MT", Baskerville,
           "Baskerville Old Face", "Hoefler Text", "Adobe Caslon Pro", Caslon,
           "EB Garamond", Garamond, serif;
  --text:  Charter, "Charter MT", "Bitstream Charter", "Charis SIL",
           "Linux Libertine O", "Adobe Garamond Pro", Garamond, serif;
  /* Courier Prime leads: metric Courier that belongs to a print shop, with
     a true italic. Courier New was the lead before and is Windows-only. */
  --typr:  "Courier Prime", "Courier New", "Courier Std", "Nimbus Mono PS",
           "Nimbus Mono L", "PT Mono", Courier, monospace;

  --measure: 34rem;
  --gutter: clamp(1.15rem, 4vw, 3.25rem);
  --sheet: 74rem;

  --rule: 1px solid var(--ink);
  --rule-soft: 1px solid rgba(23, 23, 23, 0.22);

  --t-fast: 160ms;
  --t-mid: 320ms;
  --t-slow: 620ms;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

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

body {
  margin: 0;
  background-color: var(--paper);
  /* paper grain: two crossed fibre gradients, no images */
  background-image:
    repeating-linear-gradient(90deg, rgba(23,23,23,0.014) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg, rgba(23,23,23,0.012) 0 1px, transparent 1px 4px),
    radial-gradient(120% 80% at 12% 0%, rgba(255,252,242,0.9), transparent 60%),
    radial-gradient(90% 70% at 100% 100%, rgba(23,23,23,0.055), transparent 62%);
  color: var(--ink);
  /* running matter is set in the text face, not set in a UI sans */
  font-family: var(--text);
  font-variant-numeric: oldstyle-nums proportional-nums;
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
  line-height: 1.62;
  overflow-x: hidden;
}

h1, h2, h3 { font-family: var(--serif); font-weight: 400; margin: 0; letter-spacing: -0.015em; }
p { margin: 0 0 1em; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }
button { font: inherit; color: inherit; }

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

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--cobalt);
  outline-offset: 3px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 90;
  background: var(--ink); color: var(--paper);
  padding: 0.6rem 1rem; font-family: var(--typr); font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: 0.14em; text-decoration: none;
}
.skip:focus { left: 0; }

/* ── type utilities ──────────────────────────────────────────── */

.annot {
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.19em;
  color: var(--pencil);
}

.marginalia {
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--pencil);
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.5rem;
  margin: 0;
}
.marginalia--inline { margin-bottom: 1.1rem; }
.marginalia--inline::before {
  content: "";
  width: 2.4rem; height: 1px; align-self: center;
  background: var(--tomato);
}

.hl {
  background: linear-gradient(to bottom, transparent 58%, var(--fluor) 58%);
  padding: 0 0.06em;
}

.linkbtn {
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 1px solid currentColor;
  padding: 0 0 1px;
  margin: 0;
  cursor: pointer;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--cobalt);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.linkbtn:hover { color: var(--tomato); }
.linkbtn--wide { margin-top: 1.4rem; }
.linkbtn[aria-pressed="true"] { background: var(--fluor); color: var(--ink); }

/* ── registration overlay (the unique detail) ─────────────────── */

.reg {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  --drift-x: 0px;
  --drift-y: 0px;
}

.reg__plate {
  position: absolute;
  inset: 0;
  transition: transform var(--t-slow) var(--ease), opacity var(--t-slow) var(--ease);
}
.reg__plate--cobalt {
  border: 1px solid rgba(47, 77, 184, 0.34);
  transform: translate(calc(var(--drift-x) * -0.55), calc(var(--drift-y) * -0.55));
}
.reg__plate--tomato {
  border: 1px solid rgba(233, 90, 79, 0.3);
  outline: 1px solid rgba(233, 90, 79, 0.1);
  outline-offset: -5px;
  transform: translate(calc(var(--drift-x) * 0.55), calc(var(--drift-y) * 0.35));
}
.reg__plate--fluor {
  border: 1px dashed rgba(199, 179, 32, 0.55);
  outline: 1px dashed rgba(199, 179, 32, 0.22);
  outline-offset: -11px;
  transform: translate(calc(var(--drift-x) * 0.9), calc(var(--drift-y) * -0.75));
}
/* when the visitor changes sections, the three plates fall into register */
.reg.is-registered {
  --drift-x: 0px;
  --drift-y: 0px;
  animation: plate-settle 1400ms var(--ease) 1;
}
@keyframes plate-settle {
  0%   { filter: none; }
  22%  { filter: saturate(1.5) contrast(1.1); }
  100% { filter: none; }
}

.reg__marks { position: absolute; inset: 0; }
.reg__mark, .reg__cross {
  position: absolute;
  background: rgba(23, 23, 23, 0.34);
  transition: transform var(--t-slow) var(--ease);
}
.reg__mark { width: 15px; height: 15px; }
.reg__mark::before, .reg__mark::after {
  content: ""; position: absolute; background: inherit;
}
.reg__mark::before { width: 100%; height: 1px; top: 0; left: 0; }
.reg__mark::after  { height: 100%; width: 1px; top: 0; left: 0; }
.reg__mark--tl { top: 14px; left: 14px; }
.reg__mark--tr { top: 14px; right: 14px; transform: scaleX(-1); }
.reg__mark--bl { bottom: 14px; left: 14px; transform: scaleY(-1); }
.reg__mark--br { bottom: 14px; right: 14px; transform: scale(-1); }
.reg__cross--h { left: 0; right: 0; top: 50%; height: 1px; opacity: 0.2; }
.reg__cross--v { top: 0; bottom: 0; left: 50%; width: 1px; opacity: 0.2; }

.reg.is-registered .reg__mark { background: var(--tomato); }

.reg-status {
  position: fixed;
  right: var(--gutter);
  bottom: 0.85rem;
  z-index: 61;
  margin: 0;
  font-family: var(--typr);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--pencil);
  pointer-events: none;
  transition: color var(--t-mid) var(--ease);
}
.reg-status::before {
  content: "";
  display: inline-block;
  width: 0.5rem; height: 0.5rem;
  margin-right: 0.55rem;
  background: var(--tomato);
  transform: rotate(45deg);
  transition: background var(--t-mid) var(--ease);
}
.reg-status.is-registered { color: var(--cobalt); }
.reg-status.is-registered::before { background: var(--cobalt); }

/* ── masthead ────────────────────────────────────────────────── */

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(3px);
  border-bottom: var(--rule);
}
.masthead__inner {
  max-width: var(--sheet);
  margin: 0 auto;
  padding: 0.75rem var(--gutter);
  display: flex;
  align-items: baseline;
  gap: 1.25rem;
  flex-wrap: wrap;
}
.masthead__back {
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--pencil);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.masthead__back:hover { color: var(--tomato); border-bottom-color: var(--tomato); }
.masthead__name {
  margin: 0 auto 0 0;
  font-family: var(--serif);
  font-size: 1.06rem;
  letter-spacing: 0.01em;
  display: flex; align-items: center; gap: 0.5rem;
}
.masthead__mark { color: var(--cobalt); display: inline-flex; }
.masthead__nav { display: flex; gap: 1.35rem; flex-wrap: wrap; }
.masthead__nav a {
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink);
  text-decoration: none;
  position: relative;
  padding-bottom: 2px;
}
.masthead__nav a::after {
  content: "";
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--cobalt);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-fast) var(--ease);
}
.masthead__nav a:hover::after, .masthead__nav a.is-current::after { transform: scaleX(1); }
.masthead__nav a.is-current { color: var(--cobalt); }

/* ── sections: the leaves that turn on scroll ────────────────── */

.leaf {
  position: relative;
  max-width: var(--sheet);
  margin: 0 auto;
  padding: clamp(3.5rem, 8vw, 7rem) var(--gutter);
  border-bottom: var(--rule-soft);
  /* --turn is written by JS from this section's scroll progress */
  --turn: 0;
}
.leaf > * { position: relative; z-index: 1; }
.leaf::after {
  content: "";
  position: absolute;
  right: 0; bottom: 0;
  width: 6.5rem;
  height: 6.5rem;
  max-width: 34%;
  max-height: 40%;
  transform: scale(var(--turn, 0));
  transform-origin: 100% 100%;
  background:
    linear-gradient(315deg,
      rgba(23,23,23,0.16) 0%,
      rgba(23,23,23,0.04) 34%,
      rgba(255,255,255,0.42) 36%,
      rgba(255,255,255,0.05) 62%,
      transparent 100%),
    linear-gradient(315deg, var(--paper-3), var(--paper));
  border-left: 1px solid rgba(23,23,23,0.16);
  border-top: 1px solid rgba(23,23,23,0.16);
  pointer-events: none;
  z-index: 2;
}

/* ── hero ────────────────────────────────────────────────────── */

.hero {
  padding-top: clamp(2.75rem, 6vw, 5rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0 clamp(2rem, 5vw, 4.5rem);
}
.marginalia--hero {
  grid-column: 1 / -1;
  border-bottom: var(--rule-soft);
  padding-bottom: 0.6rem;
}
.hero__title {
  grid-column: 1 / -1;
  font-size: clamp(3.1rem, 13vw, 10.5rem);
  line-height: 0.86;
  letter-spacing: -0.035em;
  margin: 0.4rem 0 0;
  max-width: 14ch;
}
.hero__title-line { display: block; }
.hero__title-line--em {
  font-style: italic;
  color: var(--cobalt);
  padding-left: 0.06em;
}
.hero__standfirst {
  grid-column: 1 / -1;
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: clamp(1.08rem, 0.98rem + 0.5vw, 1.42rem);
  line-height: 1.5;
  margin: 1.5rem 0 0;
}

/* ── the stack: signature interaction ────────────────────────── */

.stack-block {
  grid-column: 1 / -1;
  margin-top: clamp(3rem, 7vw, 5.5rem);
  border-top: 3px double var(--ink);
  padding-top: 1.4rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3rem);
}
.stack-block__head { max-width: 32rem; }
.stack-block__title {
  font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.5rem);
  line-height: 1;
  margin-bottom: 0.55rem;
}
.stack-block__hint {
  font-family: var(--typr);
  font-size: 0.75rem;
  line-height: 1.65;
  letter-spacing: 0.04em;
  color: var(--pencil);
  margin: 0;
}

.stack {
  display: grid;
  gap: 0.42rem;
  perspective: 1200px;
  counter-reset: spine;
}

.spine {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.9rem;
  padding: 0.85rem 0.95rem;
  background: var(--paper-2);
  border: var(--rule);
  cursor: grab;
  touch-action: pan-y;
  transform: translate3d(0, 0, 0);
  transition: transform var(--t-mid) var(--ease),
              background var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease);
  box-shadow: 3px 3px 0 rgba(23, 23, 23, 0.12);
}
.spine:hover { background: #F2E7CE; }
.spine.is-dragging {
  cursor: grabbing;
  z-index: 5;
  transition: none;
  background: var(--fluor);
  box-shadow: 10px 12px 0 rgba(23, 23, 23, 0.2);
}
.spine.is-sliding { transition: transform var(--t-mid) var(--ease); }

.spine__num {
  font-family: var(--typr);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  color: var(--paper);
  background: var(--ink);
  padding: 0.2rem 0.4rem;
  align-self: stretch;
  display: flex; align-items: center;
}
.spine__body { min-width: 0; }
.spine__word {
  display: block;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 1.1rem + 1.9vw, 2.6rem);
  line-height: 1;
  letter-spacing: -0.02em;
}
.spine__note {
  display: block;
  font-family: var(--typr);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.17em;
  color: var(--pencil);
  margin-top: 0.4rem;
}
.spine__grip {
  width: 0.85rem;
  align-self: stretch;
  border-left: 1px dotted rgba(23, 23, 23, 0.35);
  background-image: repeating-linear-gradient(
    180deg, rgba(23,23,23,0.3) 0 2px, transparent 2px 6px);
  background-position: right center;
  background-size: 5px 100%;
  background-repeat: no-repeat;
}

/* keyboard / touch move buttons: always reachable, drag is optional */
.spine__moves {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.spine__move {
  appearance: none;
  width: 1.5rem; height: 1.35rem;
  border: 1px solid rgba(23, 23, 23, 0.35);
  background: transparent;
  color: var(--ink);
  font-family: var(--typr);
  font-size: 0.6875rem;
  line-height: 1;
  cursor: pointer;
  display: grid; place-items: center;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.spine__move:hover:not(:disabled) { background: var(--cobalt); color: var(--paper); border-color: var(--cobalt); }
.spine__move:disabled { opacity: 0.25; cursor: default; }

/* the running order readout, set like a galley proof */
.stack__slot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.9rem;
  margin: 0;
  padding: 0.7rem 0;
  border-top: var(--rule-soft);
  border-bottom: var(--rule-soft);
}
.stack__slot-label {
  font-family: var(--typr);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--tomato);
}
.stack__slot-text {
  font-family: var(--serif);
  font-size: clamp(1rem, 0.9rem + 0.5vw, 1.3rem);
  font-style: italic;
  letter-spacing: 0.01em;
}

.sentence {
  position: relative;
  padding: clamp(1.4rem, 3vw, 2.2rem) 0 0 clamp(1.1rem, 3vw, 2.6rem);
  max-width: 40rem;
}
.sentence::before {
  content: "";
  position: absolute;
  left: 0; top: 1.6rem; bottom: 1.9rem;
  width: 3px;
  background: var(--tomato);
}
.sentence__text {
  font-family: var(--serif);
  font-size: clamp(1.3rem, 1rem + 1.5vw, 2.35rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 1.1rem;
}
.sentence__text .em { font-style: italic; color: var(--cobalt); }
.sentence__note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.6rem;
  margin: 0;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--pencil);
}

/* ── catalogue ───────────────────────────────────────────────── */

.cat__head { max-width: 44rem; margin-bottom: clamp(2.4rem, 6vw, 4rem); }
.cat__title {
  font-size: clamp(2rem, 1.3rem + 3.4vw, 4.4rem);
  line-height: 0.98;
  margin-bottom: 1.1rem;
}
.cat__title em { font-style: italic; color: var(--tomato); }
.cat__note {
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.08rem;
  line-height: 1.55;
  margin: 0;
}

.shelf {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: clamp(1.8rem, 4vw, 3rem) clamp(1.2rem, 2.5vw, 2.4rem);
}

.book__card { display: grid; gap: 0.85rem; }

.book__cover {
  position: relative;
  aspect-ratio: 3 / 4;
  border: var(--rule);
  background: var(--paper-2);
  overflow: hidden;
  perspective: 900px;
}
.book__cover--tomato { background: color-mix(in srgb, var(--tomato) 14%, var(--paper-2)); }
.book__cover--cobalt { background: color-mix(in srgb, var(--cobalt) 13%, var(--paper-2)); }
.book__cover--plain  { background: var(--paper-3); }

.book__face {
  position: absolute;
  inset: 0;
  padding: clamp(1rem, 2.2vw, 1.6rem);
  display: flex;
  flex-direction: column;
  border-left: 5px solid var(--ink);
  transition: transform var(--t-slow) var(--ease);
  transform-origin: left center;
  transform: rotateY(0deg);
}
.book__cover:hover .book__face { transform: rotateY(-3.5deg) translateX(-2px); }

.book__kicker {
  font-family: var(--typr);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.19em;
  color: var(--pencil);
  margin: 0 0 auto;
}
.book__title {
  font-family: var(--serif);
  font-size: clamp(1.35rem, 1.05rem + 1.1vw, 1.95rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 0.6rem;
}
.book__author {
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.95rem;
  margin: 0;
}
.book__mark {
  position: absolute;
  right: clamp(0.7rem, 1.6vw, 1.1rem);
  bottom: clamp(0.7rem, 1.6vw, 1.1rem);
  margin: 0;
  width: 2.1rem; height: 2.1rem;
  display: grid; place-items: center;
  border: 1px solid var(--ink);
  background: var(--paper);
  font-family: var(--serif);
  font-size: 0.8rem;
  letter-spacing: 0.02em;
}

/* the peel: a triangular corner lifts to show what is underneath */
.book__under {
  position: absolute;
  inset: 0;
  padding: clamp(1.1rem, 2.4vw, 1.8rem);
  background: var(--ink);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.98rem;
  line-height: 1.5;
  clip-path: polygon(100% 0, 100% 0, 100% 0);
  transition: clip-path var(--t-slow) var(--ease);
}
.book__under p { margin: 0; }
.book__under-sig {
  font-family: var(--typr);
  font-style: normal;
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--fluor);
  margin-top: 0.7rem;
}
.book__cover:hover .book__under,
.book__cover:focus-within .book__under {
  clip-path: polygon(100% 0, 100% 0, 0 100%);
}
.book__cover:focus-within .book__under { --peel: 1; }

/* a lifted corner of the actual cover, drawn over the reveal */
.book__cover::after {
  content: "";
  position: absolute;
  top: 0; right: 0;
  width: 0; height: 0;
  border-style: solid;
  border-width: 0 0 0 0;
  border-color: transparent var(--paper-3) transparent transparent;
  filter: drop-shadow(-2px 3px 2px rgba(23,23,23,0.28));
  transition: border-width var(--t-slow) var(--ease);
  pointer-events: none;
}
.book__cover:hover::after,
.book__cover:focus-within::after {
  border-width: 0 3.4rem 3.4rem 0;
}

.book__meta {
  border-top: var(--rule-soft);
  padding-top: 0.5rem;
  display: grid;
  gap: 0.15rem;
}
.book__line {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--pencil);
}
.book__line span:last-child { color: var(--ink); text-align: right; }

/* ── imposition / crop-mark proof ────────────────────────────── */

.imp__title {
  font-size: clamp(1.9rem, 1.2rem + 3.2vw, 4rem);
  line-height: 1;
  max-width: 16ch;
  margin-bottom: 1.1rem;
}
.imp__body {
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.1rem;
  line-height: 1.55;
  margin-bottom: clamp(2.4rem, 5vw, 3.6rem);
}
.imp__body em { font-style: italic; color: var(--cobalt); }

.crop {
  appearance: none;
  position: relative;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  display: inline-grid;
  grid-template-columns: auto auto;
  align-items: center;
  gap: 0.9rem;
  color: var(--ink);
}
.crop__mark {
  color: var(--tomato);
  display: inline-flex;
  transition: transform var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}
.crop:hover .crop__mark { transform: translate(2px, -2px) rotate(-2deg); color: var(--cobalt); }
.crop__label {
  font-family: var(--typr);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 0.25rem;
}
.crop:hover .crop__label { border-bottom-color: var(--cobalt); color: var(--cobalt); }

/* the proof expands from the crop mark's own rectangle */
.proof {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: center;
  padding: var(--gutter);
}
.proof[hidden] { display: none; }
.proof__scrim {
  position: absolute;
  inset: 0;
  background: rgba(23, 23, 23, 0.55);
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease);
}
.proof__sheet {
  position: relative;
  width: min(58rem, 100%);
  max-height: 100%;
  overflow: auto;
  background: var(--paper);
  border: var(--rule);
  box-shadow: 14px 16px 0 rgba(23, 23, 23, 0.28);
  padding: clamp(1.1rem, 2.6vw, 2rem);
  opacity: 0;
  transform: scale(var(--from-scale, 0.2)) translate(var(--from-x, 0px), var(--from-y, 0px));
  transform-origin: var(--from-ox, 50%) var(--from-oy, 50%);
  transition: transform var(--t-slow) var(--ease), opacity var(--t-mid) var(--ease);
}
.proof.is-open .proof__scrim { opacity: 1; }
.proof.is-open .proof__sheet {
  opacity: 1;
  transform: scale(1) translate(0, 0);
}
.proof.is-closing .proof__sheet {
  opacity: 0;
  transform: scale(var(--from-scale, 0.2)) translate(var(--from-x, 0px), var(--from-y, 0px));
}
.proof.is-closing .proof__scrim { opacity: 0; }

.proof__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  border-bottom: var(--rule);
  padding-bottom: 0.7rem;
  margin-bottom: clamp(1.1rem, 2.4vw, 1.8rem);
}
.proof__id {
  margin: 0;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--pencil);
}
.proof__close {
  appearance: none;
  background: none;
  border: var(--rule);
  padding: 0.3rem 0.55rem;
  cursor: pointer;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.proof__close:hover { background: var(--ink); color: var(--paper); }
.proof__esc {
  border: 1px solid currentColor;
  padding: 0 0.25rem;
  font-size: 0.5625rem;
  opacity: 0.7;
}

.proof__body {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: clamp(1.2rem, 3vw, 2.4rem);
  align-items: start;
}
.proof__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px dashed var(--cobalt);
  padding: 0.5rem;
  gap: 0.35rem;
}
.pg {
  position: relative;
  aspect-ratio: 3 / 4;
  border: 1px solid rgba(23, 23, 23, 0.3);
  background: var(--paper-2);
  display: grid;
  place-items: end start;
  padding: 0.3rem;
}
.pg i {
  font-style: normal;
  font-family: var(--typr);
  font-size: 0.5625rem;
  color: var(--pencil);
}
.pg--f {
  background: var(--fluor);
  border-color: var(--tomato);
}
.pg--f::before, .pg--f::after {
  content: "";
  position: absolute;
  width: 0.55rem; height: 0.55rem;
  border: 1px solid var(--tomato);
}
.pg--f::before { top: 0.2rem; left: 0.2rem; border-right: 0; border-bottom: 0; }
.pg--f::after { bottom: 0.2rem; right: 0.2rem; border-left: 0; border-top: 0; }

.proof__legend {
  display: grid;
  gap: 0.55rem;
  counter-reset: plate;
}
.proof__legend li {
  font-family: var(--typr);
  font-size: 0.6875rem;
  line-height: 1.5;
  letter-spacing: 0.05em;
  color: var(--ink);
  padding-left: 1.5rem;
  position: relative;
}
.proof__legend li::before {
  counter-increment: plate;
  content: counter(plate);
  position: absolute;
  left: 0; top: 0;
  width: 1.1rem; height: 1.1rem;
  display: grid; place-items: center;
  border: 1px solid var(--ink);
  font-size: 0.5625rem;
}
.proof__legend b {
  font-weight: 400;
  color: var(--cobalt);
  letter-spacing: 0.16em;
}
.proof__legend li:nth-child(2) b { color: var(--tomato); }
.proof__legend li:nth-child(3) b { color: #8a7412; }

.proof__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.4rem;
  margin-top: clamp(1.1rem, 2.4vw, 1.8rem);
  padding-top: 0.7rem;
  border-top: var(--rule-soft);
  font-family: var(--typr);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--pencil);
}

/* ── colophon + loupe ────────────────────────────────────────── */

.col__title {
  font-size: clamp(1.9rem, 1.2rem + 3.2vw, 4rem);
  line-height: 1;
  margin-bottom: 1.1rem;
}
.col__body {
  max-width: var(--measure);
  font-family: var(--serif);
  font-size: 1.1rem;
  line-height: 1.55;
  margin-bottom: clamp(2rem, 4.5vw, 3rem);
}

.micro-wrap {
  position: relative;
  max-width: 46rem;
  padding: clamp(1.1rem, 2.6vw, 1.9rem);
  border: var(--rule);
  background: var(--paper-2);
}
.micro {
  font-family: var(--typr);
  font-size: 0.78rem;
  line-height: 1.85;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.micro p { margin: 0; }

.loupe {
  position: absolute;
  top: 0; left: 0;
  width: 12rem; height: 12rem;
  margin: -6rem 0 0 -6rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-fast) var(--ease);
  z-index: 4;
}
.loupe.is-live { opacity: 1; }
.loupe__glass {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 50%;
  background: var(--paper-2);
  box-shadow: 0 0 0 1px var(--ink), 8px 8px 0 rgba(23, 23, 23, 0.18);
}
.loupe__inner {
  position: absolute;
  inset: 0;
  transform-origin: 0 0;
  will-change: transform;
}
.loupe__inner .micro-wrap {
  border: 0;
  padding: clamp(1.1rem, 2.6vw, 1.9rem);
  background: var(--paper-2);
}
.loupe__inner .micro { font-size: 0.78rem; }
.loupe__ring {
  position: absolute;
  inset: 0.55rem;
  border: 1px solid var(--fluor);
  border-radius: 50%;
}
.loupe__read {
  position: absolute;
  left: 50%;
  bottom: -1.6rem;
  transform: translateX(-50%);
  font-family: var(--typr);
  font-size: 0.625rem;
  letter-spacing: 0.18em;
  color: var(--ink);
  background: var(--fluor);
  padding: 0.1rem 0.4rem;
}

.colophon-facts {
  margin-top: clamp(2.4rem, 5vw, 3.6rem);
  border-top: 3px double var(--ink);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1.4rem clamp(1.4rem, 3vw, 2.6rem);
  padding-top: 1.4rem;
}
.colophon-facts dt {
  font-family: var(--typr);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--tomato);
  margin-bottom: 0.3rem;
}
.colophon-facts dd {
  font-family: var(--serif);
  font-size: 1.05rem;
  line-height: 1.4;
}

/* ── footer ──────────────────────────────────────────────────── */

.foot {
  background: var(--ink);
  color: var(--paper);
  padding: clamp(2.6rem, 6vw, 4.5rem) var(--gutter);
}
.foot__inner {
  max-width: var(--sheet);
  margin: 0 auto;
  display: grid;
  gap: 0.8rem;
  justify-items: start;
}
.foot__mark { margin: 0; color: var(--fluor); }
.foot__line {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(1.15rem, 1rem + 0.9vw, 1.7rem);
  line-height: 1.25;
  max-width: 26ch;
}
.foot__fine {
  margin: 0;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.17em;
  color: rgba(244, 234, 215, 0.55);
}
.foot__back {
  margin-top: 0.9rem;
  font-family: var(--typr);
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--fluor);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}
.foot__back:hover { color: var(--paper); }

/* ══════════════════════════════════════════════════════════════════════════
   THE ROOM — tooth, raking light, dust, and the press actually running

   Everything in this block is ambient and slow. Nothing here is decoration
   for its own sake: the platen descends because a platen descends, the sheet
   arrives because sheets arrive off a bed, the ink stands and settles because
   ink does. The vocabulary is the shop's, not a carousel's.

   Two texture lessons are baked in here, both measured rather than assumed:
     - The tooth sits on a PALE ground, so it uses soft-light. Overlay is
       base-preserving on cream and deposits nothing; soft-light has its
       neutral point at mid-grey, which is exactly where fractal noise sits,
       so the speckle lands in both directions without crushing the paper.
     - The tooth is genuinely low-frequency-and-wide as well as fine, because
       broad soft value is brushwork and high-frequency speckle is only grain.
       One filter blends both so the layer reads as stock, not as noise.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── paper tooth and fibre, one fixed layer over the whole page ─────────
   Sized explicitly: an unsized inline SVG falls back to the UA's 300x150
   replaced-element box and renders as a slab with hard edges.            */

.grain {
  position: fixed;
  inset: 0;
  z-index: 55;
  pointer-events: none;
  /* Chosen by measurement, not by the published rule, because the published
     rule was wrong here twice.

     soft-light at 0.14 measured dSd -0.01 and dTooth +0.013 across three
     flat patches: a no-op. Its modulation scales with (1 - base), and this
     ground sits at luminance 239 of 255, so there are only ~6% of the
     backdrop left for it to work on. Overlay and soft-light are not merely
     base-preserving on a pale ground — at this brightness they are inert.

     multiply at 0.28 deposits on all three patches (dTooth +0.941, +1.010,
     +1.095) and drops the ground mean about 25 levels. That darkening is
     wanted, not incidental: our hero measured mean 229 against the bar's
     176, so this is the one change on the page that moves the ground toward
     the reference rather than away from it. */
  mix-blend-mode: multiply;
  opacity: 0.28;
}
.grain__svg {
  display: block;
  width: 100%;
  height: 100%;
  /* explicit box: an unsized inline SVG falls back to the UA's 300x150
     replaced-element default and renders as a slab with hard edges */
}

/* ── light raking across the sheet ────────────────────────────────────
   One slow pass of window light, wide and soft, the way a room actually
   looks when the sun moves. Fixed and clipped, so it never widens the
   document and never scrolls with the content.                        */

.rake {
  position: fixed;
  inset: 0;
  z-index: 54;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: soft-light;
  opacity: 0.62;
}
.rake::before {
  content: "";
  position: absolute;
  top: -35%;
  bottom: -35%;
  left: -60%;
  width: 60%;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 251, 238, 0.1) 22%,
    rgba(255, 252, 244, 0.62) 50%,
    rgba(255, 251, 238, 0.1) 78%,
    transparent 100%
  );
  filter: blur(14px);
  /* 150s for the whole pass. This band is 60% of the viewport wide, so it is
     the largest moving area on the page; at 46s it crossed the screen in
     under half a minute and dominated every two-frame comparison. */
  animation: pm-rake 150s linear infinite;
}

/* ── dust in the beam ───────────────────────────────────────────────────
   TWO motes, not nine, and both on long periods.

   Nine motes on nine 37-61s periods measured changedPct 3.479 in the hero
   against the bar's 0.260 — we were 13x livelier than the bar and still
   losing. The reason is not how much moves, it is HOW. Small fast motes
   re-randomise the field every frame; the bar's motion is broad, slow and
   low-frequency, so two frames apart it has barely moved and that movement
   still reads as composed. Chasing the metric with more particles is the
   opposite of the fix, so the dust is thinned until it drifts. */

.motes {
  position: fixed;
  inset: 0;
  z-index: 56;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: normal;
}
.motes span {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(255, 250, 236, 0.6);
  box-shadow: 0 0 6px 2px rgba(255, 246, 224, 0.26);
  opacity: 0;
}
.motes span:nth-child(1) { left: 31%; top: 62%; animation: pm-mote 96s linear infinite; }
.motes span:nth-child(2) { left: 68%; top: 38%; animation: pm-mote 118s linear infinite -47s; width: 2px; height: 2px; }
/* the remaining seven are inert by design — see the note above */
.motes span:nth-child(n+3) { display: none; }

/* ── the press, drawn ────────────────────────────────────────────────────
   Positioned inside the hero and clipped by it, so the illustration can
   be as large as it likes without ever contributing a pixel of overflow. */

.hero > .pressroom {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0.92;
}
.pressroom__svg {
  display: block;
  position: absolute;
  right: -3%;
  top: 3%;
  width: min(32rem, 54%);
  /* the height follows from the 520x640 viewBox. Stretching it to a
     percentage of a very tall hero left the press floating in empty space. */
  height: auto;
  aspect-ratio: 520 / 640;
}
/* the hero's own children sit above the illustration */
.hero > .marginalia,
.hero > .hero__title,
.hero > .hero__standfirst,
.hero > .stack-block { z-index: 1; }

/* washes — broad, low-frequency, the brushwork under the tooth */
/* Washes are broad, low-frequency and the only real value structure in the
   hero, so they carry more weight here than the tooth does. Deeper than a
   tint: the hero measured a span of 17 with them off and 65 with them on,
   and the bar's painted cloud spans 83. */
.p-wash { opacity: 0.72; }
.p-wash-cobalt { fill: rgba(47, 77, 184, 0.62); }
.p-wash-tomato { fill: rgba(233, 90, 79, 0.5); }
.p-wash-fluor  { fill: rgba(242, 232, 92, 0.44); }

/* the moon, hung where the lamp would be */
/* The moon has to clear the fluor wash behind it, which sits at 0.5 alpha
   in nearly the same hue. Ink on a wash, not a wash on a wash. */
.p-moon       { fill: rgba(247, 240, 148, 0.72); stroke: rgba(23, 23, 23, 0.26); stroke-width: 1.4; }
.p-moon-limb  { fill: rgba(244, 234, 215, 0.72); }

/* crop marks and register cross, drawn into the scene */
.p-mark       { fill: none; stroke: rgba(23, 23, 23, 0.34); stroke-width: 1.4; }
.p-mark--weak { stroke: rgba(233, 90, 79, 0.5); }

/* the machine — an under-impression, so it reads behind the type */
.p-floor    { fill: none; stroke: rgba(23, 23, 23, 0.26); stroke-width: 1.6; }
.p-plinth   { fill: rgba(23, 23, 23, 0.1); stroke: rgba(23, 23, 23, 0.3); stroke-width: 1.5; }
.p-upright  { fill: rgba(47, 77, 184, 0.09); stroke: rgba(23, 23, 23, 0.32); stroke-width: 1.5; }
.p-beam     { fill: rgba(47, 77, 184, 0.16); stroke: rgba(47, 77, 184, 0.5); stroke-width: 1.6; }
.p-leg      { fill: none; stroke: rgba(23, 23, 23, 0.26); stroke-width: 1.4; }
.p-bed      { fill: rgba(23, 23, 23, 0.12); stroke: rgba(23, 23, 23, 0.34); stroke-width: 1.5; }
.p-board    { fill: rgba(23, 23, 23, 0.07); stroke: rgba(23, 23, 23, 0.24); stroke-width: 1.4; }
.p-crank    { fill: none; stroke: rgba(23, 23, 23, 0.3); stroke-width: 3; stroke-linecap: round; }
.p-wheel    { fill: rgba(244, 234, 215, 0.3); stroke: rgba(23, 23, 23, 0.34); stroke-width: 2; }
.p-spoke    { fill: none; stroke: rgba(23, 23, 23, 0.3); stroke-width: 2; stroke-linecap: round; }
.p-hub      { fill: rgba(23, 23, 23, 0.3); }

.p-screw    { fill: rgba(23, 23, 23, 0.16); stroke: rgba(23, 23, 23, 0.34); stroke-width: 1.4; }
.p-platen   { fill: rgba(47, 77, 184, 0.22); stroke: rgba(47, 77, 184, 0.55); stroke-width: 1.6; }
.p-tympan   { fill: rgba(244, 234, 215, 0.62); stroke: rgba(23, 23, 23, 0.24); stroke-width: 1.2; }
.p-tympan--sheet { fill: rgba(244, 234, 215, 0.44); stroke: rgba(23, 23, 23, 0.18); stroke-width: 1; }

/* The rib rect must reference the pattern by id. Without it, fill falls back
   to the SVG initial value of black, which painted a 189x24 solid bar — the
   one genuinely broken thing in the illustration, and invisible to any count
   of filters or keyframes. The rib alpha is low because the ribs sit at 40%
   coverage over the roller; a roller on an under-impression is a suggestion
   of metal, not a hole in the page. */
.p-roller { fill: rgba(23, 23, 23, 0.07); stroke: rgba(23, 23, 23, 0.3); stroke-width: 1.4; }
.p-ribs   { fill: url(#pm-ribs); }
.p-rib    { fill: rgba(23, 23, 23, 0.16); }
.p-inkfilm { fill: rgba(47, 77, 184, 0.3); }

.p-sheet       { fill: rgba(244, 234, 215, 0.8); stroke: rgba(23, 23, 23, 0.28); stroke-width: 1.3; }
.p-sheet-moon  { fill: rgba(242, 232, 92, 0.8); }
.p-sheet-rule  { fill: none; stroke: rgba(23, 23, 23, 0.3); stroke-width: 1.4; stroke-linecap: round; }

.p-stack       { fill: rgba(244, 234, 215, 0.66); stroke: rgba(23, 23, 23, 0.26); stroke-width: 1.3; }
.p-stack--top  { fill: rgba(233, 90, 79, 0.16); stroke: rgba(233, 90, 79, 0.45); }

/* ── the press, running ────────────────────────────────────────────────
   Resting states are written as the base rule and every keyframe starts
   from them, so with animation removed the scene is still fully composed.
   Nothing here depends on an animation existing to be legible.        */

/* the stroke: down hard, held under pressure, then released slowly */
.a-platen {
  animation: pm-stroke 11s cubic-bezier(0.55, 0.06, 0.3, 1) infinite;
  transform-box: fill-box;
  transform-origin: 50% 0%;
}

/* the flywheel, which turns whether or not anyone is watching */
/* 64s a turn. A flywheel at 19s was the one thing on the page that read as
   machinery running rather than machinery standing; the press here is a
   hand-press worked slowly, and the wheel moves when it is used. */
.a-flywheel {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: pm-flywheel 64s linear infinite;
}

/* the rollers: one pattern period, so the ribs read as turning metal */
.a-ribs { animation: pm-rollers 2.6s linear infinite; }

/* the ink standing on the rollers, then sinking into them */
.a-ink { animation: pm-ink-settle 11s cubic-bezier(0.4, 0, 0.2, 1) infinite; }

/* the sheet: arrives off the bed, is read, goes to the pile */
.a-sheet {
  opacity: 1;
  animation: pm-sheet-feed 23s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

/* One pattern period, so the ribs read as turning metal. 9s is a slow
   traverse rather than a blur: at 2.6s this was 192px of re-randomising
   high-frequency stripe every frame — the fastest-moving thing on the page
   and the least composed. */
.a-ribs { animation: pm-rollers 9s linear infinite; }

/* the pile, which never quite settles */
.a-stack {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: pm-stack-settle 23s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

/* the washes and the moon drift, slowly, out of phase with each other */
.p-wash { animation: pm-wash-drift 37s ease-in-out infinite alternate; }
.p-wash-tomato { animation-duration: 44s; animation-delay: -12s; }
.p-wash-fluor  { animation-duration: 31s; animation-delay: -6s;  }
.a-moon {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: pm-moon-drift 29s ease-in-out infinite alternate;
}

/* the crop marks in the scene never hold perfectly still */
.p-marks {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: pm-mark-hunt 13s ease-in-out infinite alternate;
}

/* ── keyframes ───────────────────────────────────────────────────────── */

/* the platen comes down, bites, and is let back up */
@keyframes pm-stroke {
  0%        { transform: translateY(0); }
  16%       { transform: translateY(0); }
  27%       { transform: translateY(15px); }
  34%       { transform: translateY(15px); }
  43%       { transform: translateY(15px); }
  62%       { transform: translateY(0); }
  100%      { transform: translateY(0); }
}

@keyframes pm-flywheel {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* translating by exactly one 11px pattern period is a seamless loop */
@keyframes pm-rollers {
  from { transform: translateX(0); }
  to   { transform: translateX(-11px); }
}

/* ink stands proud under pressure and sinks back as the press releases */
@keyframes pm-ink-settle {
  0%,  16%  { opacity: 0.34; transform: scaleY(1); }
  27%       { opacity: 0.9;  transform: scaleY(1.5); }
  34%, 43%  { opacity: 0.9;  transform: scaleY(1.5); }
  62%       { opacity: 0.34; transform: scaleY(1); }
  100%      { opacity: 0.34; transform: scaleY(1); }
}

/* the sheet comes off the bed, is carried away, and the bed is empty again */
@keyframes pm-sheet-feed {
  0%        { opacity: 0; transform: translate(34px, 0); }
  6%        { opacity: 0; transform: translate(34px, 0); }
  14%       { opacity: 1; transform: translate(0, 0); }
  46%       { opacity: 1; transform: translate(0, 0); }
  58%       { opacity: 1; transform: translate(-26px, 26px); }
  66%       { opacity: 0; transform: translate(-26px, 26px); }
  100%      { opacity: 0; transform: translate(34px, 0); }
}

@keyframes pm-stack-settle {
  0%, 58%  { transform: translateY(0); }
  64%       { transform: translateY(-1.6px); }
  100%      { transform: translateY(0); }
}

@keyframes pm-wash-drift {
  from { transform: translate(-10px, 6px) scale(1); }
  to   { transform: translate(14px, -8px) scale(1.06); }
}

@keyframes pm-moon-drift {
  from { transform: translateY(4px); }
  to   { transform: translateY(-7px); }
}

@keyframes pm-mark-hunt {
  from { transform: translate(0.8px, -0.6px); }
  to   { transform: translate(-1.1px, 0.9px); }
}

/* one pass of window light, then a long absence of it */
@keyframes pm-rake {
  0%   { transform: translateX(0); }
  62%  { transform: translateX(340%); }
  100% { transform: translateX(340%); }
}

@keyframes pm-mote {
  0%   { opacity: 0;   transform: translate(0, 0) scale(0.6); }
  12%  { opacity: 0.62; }
  55%  { opacity: 0.4; }
  100% { opacity: 0;   transform: translate(34px, -180px) scale(1.15); }
}

/* ── the registration marks hunt, then hold ─────────────────────────────
   Before the visitor has read past the front of the sheet the crop marks
   are still hunting for register, which is what they are for. Once the
   plates lock (the is-registered class, written by world.js) the hunt
   stops and the marks sit still, exactly as ink does.                   */

/* Long periods, and deliberately so. These four marks sit at the four
   corners of the viewport, so a short cycle re-randomises the whole sheet's
   corners many times a minute. A press hunts for register slowly or not at
   all, and the slow hunt is also what keeps this layer from reading as
   noise when two frames are compared 1.5s apart. */
.reg__mark { animation: pm-mark-hunt 19s ease-in-out infinite alternate; }
.reg__mark:nth-of-type(2) { animation-duration: 24s; animation-delay: -6s; }
.reg__mark:nth-of-type(3) { animation-duration: 29s; animation-delay: -11s; }
.reg__mark:nth-of-type(4) { animation-duration: 21s; animation-delay: -14s; }
.reg.is-registered .reg__mark { animation: none; }

/* the status lamp is a lamp: it is on, or it is off */
.reg-status::before { animation: pm-lamp 6.5s ease-in-out infinite; }
.reg-status.is-registered::before { animation-duration: 3.4s; }

@keyframes pm-lamp {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 1; }
}

/* ── wide screens: the sheet opens into two columns ──────────── */

@media (min-width: 62rem) {
  .hero {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  }
  .hero__standfirst { grid-column: 1 / -1; }
  .stack-block {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: start;
  }
  .stack-block__head { grid-column: 1 / -1; }
  .stack { grid-column: 1; }
  .stack__slot, .sentence { grid-column: 2; }
  .stack__slot { grid-row: 2; margin-top: 0; }
  .sentence { grid-row: 3; }

  .proof__body { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}

@media (min-width: 78rem) {
  .loupe { width: 14rem; height: 14rem; margin: -7rem 0 0 -7rem; }
}

/* ── narrow screens ──────────────────────────────────────────── */

@media (max-width: 47.99rem) {
  .reg__plate--fluor { outline-offset: -6px; }
  .masthead__inner { gap: 0.55rem 1rem; padding: 0.6rem var(--gutter); }
  .masthead__name { font-size: 0.98rem; }
  .masthead__nav { gap: 0.9rem; width: 100%; order: 3; }
  .spine { grid-template-columns: auto 1fr auto; gap: 0.7rem; padding: 0.7rem 0.75rem; }
  .spine__grip { display: none; }
  .leaf::after { max-width: 46%; }
  .proof__body { grid-template-columns: minmax(0, 1fr); }
  .proof__foot { font-size: 0.5625rem; gap: 0.3rem 0.9rem; }
  .reg-status { display: none; }
  .loupe { width: 10rem; height: 10rem; margin: -5rem 0 0 -5rem; }
  /* At 390 the press bled off the right edge and lost the flywheel, which is
     the one part of the drawing that says what the machine is. Pulled in and
     lifted so the whole press reads behind the title. */
  .pressroom__svg {
    right: 2%;
    top: 1%;
    width: min(20rem, 72%);
  }
}

/* ── reduced motion: the press stops, the paper stays ────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reg.is-registered { animation: none; }
  .loupe { transition: none; }
  .leaf::after { transition: none; }
  .spine { transition: background var(--t-fast) linear; }
  .spine.is-dragging { transition: none; }

  /* The press stops. It does not disappear.
     A world that looks broken without animation is a worse failure than a
     static one, so every resting state below is a COMPOSED state, not an
     empty one: the sheet lies on the bed as it does at rest, the ink sits
     on the rollers, the pile is stacked, the moon is up, the light is where
     it falls. What stops is the movement, not the picture. */

  .a-platen  { transform: translateY(0); }
  .a-sheet   { opacity: 1; transform: translate(0, 0); }
  .a-stack   { transform: translateY(0); }
  .a-ink     { opacity: 0.34; transform: scaleY(1); }
  .a-ribs    { transform: translateX(0); }
  .a-flywheel{ transform: rotate(0deg); }
  .a-moon    { transform: translateY(4px); }
  .p-marks   { transform: none; }

  /* the tooth and the raking light are static materials, not movements,
     so they stay exactly as they are — only the pass of light is stopped */
  .rake::before { transform: translateX(120%); }
  .motes span { opacity: 0; }
  .reg__mark { animation: none; }
  .reg-status::before { animation: none; opacity: 1; }
}
