/* ==========================================================================
   Slow Fast — essay reading surface
   --------------------------------------------------------------------------
   Ported from the visual reference at
   .config/slowfast-workspace/essay-reference.html (style block, lines 11-173).

   Rules marked LIFTED are byte-for-byte the reference's intent and must not
   drift. Rules marked NORMALISED and INVENTED are deliberate departures and
   are each recorded in docs/design/essay-reading-surface.md so the fidelity
   gate can exempt them.

   No JavaScript is served with this stylesheet. There is no theme toggle.
   Font delivery is SELF-HOSTED, and this file is the only place it is
   declared. The page shell emits no third-party font link and no preconnect,
   so an essay page reaches exactly one origin and no reader is disclosed to a
   font CDN in order to see type. See section 0.
   ========================================================================== */


/* --------------------------------------------------------------------------
   0. FONTS
   Newsreader, self-hosted, OFL-1.1. Two files and no more: it is a variable
   font, so one roman binary carries every weight and optical size the site
   asks for and one italic binary carries the same. Static instances would be
   a dozen files to say less.

   `font-weight: 400 500` is the range this surface actually uses — body text
   at 400, `h2` and `strong` at 500 — declared as a range so the browser
   interpolates rather than synthesising. The binaries carry the wider 200-800
   axis upstream ships; declaring the narrower range here is what keeps a
   stray `font-weight: 700` from rendering as something this design never
   chose. The `opsz` 6-72 axis is what `body { font-optical-sizing: auto }`
   drives, and it is the reason the same outlines hold up at the 3rem h1 and
   at the .86rem notes.

   `font-display: swap` is deliberate and matches the motion budget: the
   fallback stack paints immediately and the webfont swaps in when it lands.
   Nothing on this surface is allowed to withhold legible text.

   Provenance, pinned upstream refs and the reason the axis was NOT narrowed
   are in `fonts/PROVENANCE.md`. The licence travels with the binaries: the
   build copies `fonts/OFL.txt` into `dist/essays/assets/fonts/`.
   INVENTED — the reference linked Google Fonts; this surface does not.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("/assets/fonts/newsreader-variable-roman.woff2") format("woff2");
}

@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url("/assets/fonts/newsreader-variable-italic.woff2") format("woff2");
}


/* --------------------------------------------------------------------------
   1. TOKENS
   Three blocks, in this exact order: bare :root, the prefers-color-scheme
   query guarded by :root:not([data-theme="light"]), then :root[data-theme="dark"].
   All six tokens are redefined in full in each of the two dark blocks so that
   no colour has its only definition inside a media query.
   LIFTED.
   -------------------------------------------------------------------------- */

:root {
  --paper: #fcfcfa;
  --ink: #1b1d24;
  --ink-2: #6a6d78;
  --rule: #dcdcd6;
  --evidence: #2a58b4;
  --plate: #eeeeea;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #121316;
    --ink: #e6e4de;
    --ink-2: #9295a0;
    --rule: #2c2e35;
    --evidence: #88a9ec;
    --plate: #1d1f25;
  }
}

/* INTENTIONALLY DORMANT HOOK.
   Nothing in this slice sets data-theme. There is no toggle, no client
   JavaScript, and no server-side preference. The attribute selectors are kept
   so that an explicit per-viewer choice can be wired up later without
   restructuring the cascade: the light guard above lets a future
   data-theme="light" win over an OS dark preference, and the block below lets
   a future data-theme="dark" win over an OS light preference. Until such a
   control exists these two selectors match nothing, by design. */
:root[data-theme="dark"] {
  --paper: #121316;
  --ink: #e6e4de;
  --ink-2: #9295a0;
  --rule: #2c2e35;
  --evidence: #88a9ec;
  --plate: #1d1f25;
}


/* --------------------------------------------------------------------------
   2. RESET AND BODY
   LIFTED.
   -------------------------------------------------------------------------- */

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

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Newsreader", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
  font-optical-sizing: auto;
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern", "liga";
}

@media (min-width: 40em) {
  body {
    font-size: 1.1875rem;
    line-height: 1.5;
  }
}

i,
em {
  font-style: italic;
}

b,
strong {
  font-weight: 500;
}


/* --------------------------------------------------------------------------
   3. LAYOUT
   The measure is 38rem on essay pages and on the index alike — one measure is
   what makes them read as one publication rather than a feed bolted to a
   magazine.

   --gutter mirrors the horizontal half of .page's padding so the wide-figure
   breakout in section 9 and the page padding can never fall out of agreement:
   change one number here and both follow.

   overflow-x: clip contains the wide-figure breakout. clip is used rather than
   hidden precisely because it does not create a scroll container, so
   scroll-behavior and :target scrolling into the notes still work.
   .page padding and max-width are LIFTED; --gutter and overflow-x are INVENTED.
   -------------------------------------------------------------------------- */

.page {
  --gutter: 1.25rem;
  max-width: 33rem;
  margin: 0 auto;
  padding: 3.5rem 1.25rem 6rem;
  overflow-x: clip;
}

@media (min-width: 40em) {
  .page {
    --gutter: 3.25rem;
    padding: 6.5rem 3.25rem 7rem;
  }
}


/* --------------------------------------------------------------------------
   4. MASTHEAD
   INVENTED — the reference has no masthead at all.
   Sits outside <header> as the first child of .page. Carries its own
   text-indent: 0 rather than relying on the "header p" exception, because it
   is not inside header and may contain a paragraph.
   On an essay page it carries the bare "Slow Fast" wordmark. On the index it
   also carries the stance line beneath that wordmark.
   -------------------------------------------------------------------------- */

.masthead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: .86rem;
  letter-spacing: .02em;
  color: var(--ink-2);
  text-indent: 0;
  margin: 0 0 3.2rem;
}

.masthead a {
  color: inherit;
  text-decoration: none;
}

.masthead .wordmark {
  color: var(--ink);
}

/* The stance line is content, not chrome, and renders on the index only. */
.masthead .stance {
  display: block;
  margin: .55rem 0 0;
  color: var(--ink-2);
  text-indent: 0;
  font-style: italic;
}

/* THE MASTHEAD'S RIGHT-HAND SIDE.
   `.masthead` is space-between and was always built for two items. Without a
   second one the about page is published and unreachable from every reading
   page. It inherits the masthead's own quiet scale — this is a way out, not a
   thing to look at. */
.masthead-about {
  color: var(--ink-2);
  text-decoration: none;
  white-space: nowrap;
}

@media (prefers-reduced-motion: no-preference) {
  .masthead-about {
    transition: color 120ms ease;
  }
}

.masthead-about:hover,
.masthead-about:focus-visible {
  color: var(--ink);
}

/* THE SITE FOOTER. Index only. The standalone pages would otherwise be
   reachable from the about page and from each other, but never from the front
   door. Same quiet scale as the masthead; the rule above it does the
   separating, exactly as `.notes` does on an essay. */
.site-footer {
  margin-top: 4.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem;
  font-size: .86rem;
  letter-spacing: .02em;
  color: var(--ink-2);
  text-indent: 0;
}

.site-footer a {
  color: inherit;
  text-decoration: none;
}

@media (prefers-reduced-motion: no-preference) {
  .site-footer a {
    transition: color 120ms ease;
  }
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--ink);
}


/* On the index the publication's name is the page's heading, so it is an
   <h1>. It must not inherit the essay-title type scale — visually it stays
   exactly the masthead wordmark it was before. */
.masthead h1.wordmark-heading {
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  margin: 0;
}


/* --------------------------------------------------------------------------
   5. HEADER, TITLE AND BYLINE
   NORMALISED: the reference's single fluid h1 size becomes three fixed
   breakpoint sizes, and its negative tracking is dropped altogether rather
   than written out as a zero value.
   Everything else LIFTED.
   -------------------------------------------------------------------------- */

header h1 {
  font-weight: 400;
  font-size: 2.05rem;
  line-height: 1.06;
  margin: 0 0 1.4rem;
  text-wrap: pretty;
}

@media (min-width: 40em) {
  header h1 {
    font-size: 2.5rem;
  }
}

@media (min-width: 52em) {
  header h1 {
    font-size: 3rem;
  }
}

header .byline {
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--ink-2);
  margin: 0 0 4.25rem;
}

/* The <time> element is emitted inside the fused byline string so the byline
   renders pixel-identically while becoming machine-readable. */
header .byline time {
  font-style: inherit;
  color: inherit;
}

/* INVENTED. A header image sits below the title and byline. The generator adds
   this class to <header> rather than relying on :has(), and it pulls the
   byline's generous 4.25rem trailing space in to 1.6rem so the image reads as
   part of the opening rather than as the first thing in the prose. */
header.has-header-image .byline {
  margin-bottom: 1.6rem;
}


/* --------------------------------------------------------------------------
   6. PROSE
   NORMALISED — this is the one substantive departure from the reference's
   setting of the page.

   The reference sets prose the way a book does: p { margin: 0 } with a 1.55em
   first-line indent, so paragraphs are separated by the indent alone and the
   column runs as an unbroken block of type. That works on a printed page and
   it works for the reference essay, which is broken up by seven numbered
   sections. It does not hold for an essay with no sections at all — several
   here have none — where it renders as one undifferentiated wall.

   So: space between paragraphs, and NO first-line indent. The two are
   alternatives, not additions; using both is a redundancy that reads as an
   error. Indentation is still never stored in the content model — a paragraph
   is <p> and nothing more — the rule set simply separates them differently.

   1.15em is a little under one line (line-height is 1.58), which separates
   clearly without letting the column drift apart.
   -------------------------------------------------------------------------- */

p {
  margin: 0 0 1.15em;
  hyphens: auto;
  /* Never hyphenate a word shorter than 6 characters, and never leave fewer
     than 3 before or after the break. Unconstrained `hyphens: auto` on a
     ragged-right column breaks two-syllable words and litters the right edge
     with hyphens that buy nothing. */
  hyphenate-limit-chars: 6 3 3;
  /* Costs the last lines so a paragraph does not end on a single short word.
     The reference applies this to display type only; body text is where a
     runt is actually distracting. */
  text-wrap: pretty;
}

p:last-child {
  margin-bottom: 0;
}

p.close {
  margin-top: 1.55em;
}

h2 {
  font-weight: 500;
  font-size: 1.42rem;
  line-height: 1.22;
  margin: 3.6rem 0 1.15rem;
  text-wrap: pretty;
  /* Every numbered heading carries an id, so it is a deep-link target. Without
     this it lands flush against the top of the viewport with no air above it.
     The notes list already does the same. */
  scroll-margin-top: 1.5rem;
}

/* The section number. Ordinals are computed at render from document order and
   never stored. */
h2 .n {
  font-weight: 400;
  color: var(--ink-2);
  margin-right: .55em;
}

/* INVENTED. Prose links get the same treatment as note links so that a link
   mark in a body paragraph never falls back to the browser default. Neither
   essay in this slice contains one, so this rule changes nothing today. */
article a {
  color: var(--evidence);
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: .14em;
}

/* Footnote references. LIFTED. */
sup.ref {
  font-size: .6em;
  line-height: 0;
  vertical-align: .62em;
  margin-left: .06em;
}

sup.ref a {
  color: var(--evidence);
  text-decoration: none;
  padding: 0 .12em;
}

sup.ref a:hover {
  text-decoration: underline;
}

/* LIFTED. */
a:focus-visible {
  outline: 2px solid var(--evidence);
  outline-offset: 2px;
  border-radius: 2px;
}


/* --------------------------------------------------------------------------
   7. PULL QUOTES
   LIFTED. Note that .pull declares NO font-weight — it inherits the body's,
   and that is the reference's intent, not an omission. Its negative tracking
   is dropped per the same normalisation as the h1.
   Whether a pull quote carries aria-hidden is computed at render from whether
   its text already occurs in the prose; it is never a styling concern.
   -------------------------------------------------------------------------- */

.pull {
  margin: 2.4rem 0;
  padding: 0 1.5rem 0 0;
  font-size: 1.42rem;
  line-height: 1.28;
  text-indent: 0;
  text-wrap: pretty;
}


/* --------------------------------------------------------------------------
   8. SECTION BREAKS
   INVENTED — the reference has no section breaks. Carries the author's literal
   em dash as text content with role="separator" on the element.
   -------------------------------------------------------------------------- */

p.brk {
  text-indent: 0;
  text-align: center;
  color: var(--ink-2);
  margin: 2.6rem 0;
}


/* --------------------------------------------------------------------------
   9. FIGURES
   INVENTED — the reference has no figures.

   layout: "column" is the 38rem measure and needs no breakout.
   layout: "wide" breaks out WITHOUT shifting the box. The usual half-width
   translate trick is deliberately not used: it would create a stacking
   context, risks fractional-pixel blur on the image, and interferes with
   :target scrolling. Instead a negative margin-inline pulls the figure out to
   half of the wider measure, bounded by the viewport minus one gutter, so it
   never touches the screen edge and never overflows .page's clip.

   A figure whose status is "pending" carries no <img> at all — it renders as a
   caption alone, not as an empty frame.
   -------------------------------------------------------------------------- */

figure {
  margin: 2.8rem 0;
}

figure img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 2px;
}

figure figcaption {
  font-size: .86rem;
  line-height: 1.5;
  color: var(--ink-2);
  text-indent: 0;
  margin-top: .7rem;
}

figure figcaption .credit {
  display: block;
  margin-top: .3rem;
}

figure.wide {
  margin-inline: calc(50% - min(26rem, 50vw - var(--gutter)));
}

/* The header image, below title and byline. */
figure.header {
  margin: 0 0 3.4rem;
}


/* --------------------------------------------------------------------------
   10. NOTES
   The notes section lives inside <main> but outside </article>.
   LIFTED in full, including the plate bleed on :target — the box-shadow spreads
   the plate .55rem past the list item's own box so a targeted note reads as a
   physical plate laid on the paper rather than as a highlighted rectangle.
   -------------------------------------------------------------------------- */

.notes {
  margin-top: 5.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--rule);
  font-size: .86rem;
  line-height: 1.5;
}

@media (min-width: 40em) {
  .notes {
    font-size: .92rem;
  }
}

.notes h2 {
  font-size: 1rem;
  font-weight: 500;
  margin: 0 0 1.1rem;
}

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

.notes li {
  position: relative;
  padding-left: 2.1rem;
  margin: 0 0 .8rem;
  scroll-margin-top: 1.5rem;
}

.notes li .back {
  position: absolute;
  left: 0;
  top: 0;
  width: 1.7rem;
  color: var(--evidence);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

/* THE PLATE BLEED. */
.notes li:target {
  background: var(--plate);
  box-shadow: 0 0 0 .55rem var(--plate);
  border-radius: 2px;
}

.notes a {
  color: var(--evidence);
  text-decoration: underline;
  text-decoration-thickness: from-font;
  text-underline-offset: .14em;
}

.notes .back:hover {
  text-decoration: underline;
}


/* --------------------------------------------------------------------------
   11. ESSAY NAV
   INVENTED. Previous / All essays / next, at the foot of an essay page,
   inside <main> and after the notes. Hidden in print.
   -------------------------------------------------------------------------- */

nav.essay-nav {
  margin-top: 4.5rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--rule);
  display: flex;
  justify-content: space-between;
  gap: 1.2rem;
  font-size: .92rem;
  color: var(--ink-2);
}

nav.essay-nav a {
  color: var(--ink-2);
  text-decoration: none;
}

nav.essay-nav a:hover {
  text-decoration: underline;
}

/* Stands in for an absent neighbour so "All essays" keeps its place.
   It must NOT grow: `justify-content: space-between` is what does the
   positioning, and a growing spacer would absorb the free space and leave
   nothing to distribute, packing the two real links together. */
nav.essay-nav .spacer {
  flex: 0 0 auto;
}


/* --------------------------------------------------------------------------
   12. INDEX PAGE
   INVENTED. Same 38rem measure as an essay page. Items are 2.8rem apart with
   no rules between them — the space does the separating.
   -------------------------------------------------------------------------- */

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

.essay-list li {
  margin: 0 0 2.8rem;
}

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

.essay-list .title {
  font-size: 1.42rem;
  font-weight: 500;
  line-height: 1.22;
  margin: 0;
  text-wrap: pretty;
}

.essay-list .title a {
  color: var(--ink);
  text-decoration: none;
}

.essay-list .date {
  display: block;
  font-size: .86rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  margin-top: .45rem;
}

.essay-list .excerpt {
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink-2);
  text-indent: 0;
  margin-top: .55rem;
}

/* The most recent essay is featured with a larger title, echoing the first two
   h1 breakpoints so the index and an essay page share one type scale. */
.essay-list li.featured {
  margin-bottom: 3.6rem;
}

.essay-list li.featured .title {
  font-size: 2.05rem;
  font-weight: 400;
  line-height: 1.1;
}

@media (min-width: 40em) {
  .essay-list li.featured .title {
    font-size: 2.5rem;
  }
}


/* --------------------------------------------------------------------------
   13. SKIP LINK
   INVENTED. Visually hidden until focused, then pinned top-left on the plate.
   Clipped rather than display:none so it stays in the focus order.
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link:focus,
.skip-link:focus-visible {
  position: fixed;
  top: .75rem;
  left: .75rem;
  z-index: 10;
  width: auto;
  height: auto;
  margin: 0;
  padding: .55rem .9rem;
  overflow: visible;
  clip-path: none;
  background: var(--plate);
  color: var(--ink);
  border-radius: 2px;
  font-size: .92rem;
  text-decoration: none;
}


/* --------------------------------------------------------------------------
   14. MOTION
   The motion budget is one transition and the reference's already-gated
   scroll-behavior. There is deliberately NO entrance fade anywhere: it would
   delay first legible text, which is the one thing this surface exists to
   deliver. No keyframes are declared in this file.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .essay-list a {
    transition: color 120ms ease, opacity 120ms ease;
  }
}

.essay-list a:hover,
.essay-list a:focus-visible {
  color: var(--evidence);
}


/* --------------------------------------------------------------------------
   15. PRINT
   LIFTED, extended to drop the three invented navigational elements — they
   are all screen affordances and carry no meaning on paper.
   -------------------------------------------------------------------------- */

@media print {
  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  .page {
    max-width: none;
    padding: 0;
  }

  sup.ref a,
  .notes a,
  .notes .back,
  article a {
    color: #000;
  }

  .notes li:target {
    background: none;
    box-shadow: none;
  }

  .masthead,
  nav.essay-nav,
  .skip-link {
    display: none;
  }

  figure.wide {
    margin-inline: 0;
  }
}
