/* One stylesheet: tokens, base, masthead and bar, the opening scene, night, posts,
   indexes, footer, 404.

   The idea: composure and force. Reading is quiet serif on white and browsing is the
   same voice on charcoal, with no boxes and no rules. The force comes in a few places
   only: the sans in the name and the scene's headline, one colour per post, and the
   square period, which closes every large heading and every post. */

/* ── Faces ── */
@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4.woff2') format('woff2');
  font-weight: 300 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Source Serif 4';
  src: url('../fonts/source-serif-4-italic.woff2') format('woff2');
  font-weight: 300 600;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Caveat';
  src: url('../fonts/caveat.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ── Tokens ── */
:root {
  --paper: #ffffff;
  --ink: #17191b;
  --ink-body: #26292c;
  --ink-soft: #5a6066;
  --ground: #f4f3f0;
  --char: #141618;
  --vermilion: #d34b3f;
  /* The accent deepened for small type, where the brand value falls short on white. */
  --vermilion-ink: #bd3a2e;

  /* A post's front matter overrides these with colours chosen for its art. */
  --tone: #21465e;
  --accent: #eccf94;

  /* How pictures sit on the dark: at rest, and while another one is pointed at. */
  --print: saturate(0.65) brightness(0.86);
  --print-back: saturate(0.45) brightness(0.5);

  --serif: 'Source Serif 4', 'Iowan Old Style', Georgia, serif;
  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', 'Cascadia Mono', 'SF Mono', Consolas, ui-monospace, monospace;
  --hand: 'Caveat', 'Segoe Print', 'Bradley Hand', cursive;

  --h-name: clamp(2.75rem, 1.75rem + 3vw, 4.25rem);
  --h-scene: clamp(2.75rem, 1.5rem + 3.6vw, 5.25rem);
  --h-scene-post: clamp(2.5rem, 1.5rem + 3vw, 4.5rem);
  --h-section: clamp(3rem, 1.5rem + 4.6vw, 6.5rem);
  --h-prose: clamp(1.75rem, 1.375rem + 0.7vw, 2.25rem);
  --h-card: clamp(1.625rem, 1.25rem + 0.7vw, 2.125rem);

  /* One film grain over colour and photograph, so they read as one surface. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* The red pen's sub-bullet: down from the text, then across into the note. A mask, so
     the ink stays a token. */
  --hook: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 28 28' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 1C5 6 5 11 7 13.5C9 15.8 14 15.5 24 14.5'/%3E%3Cpath d='M24 14.5c-2.2-1.6-4.6-3-7-4'/%3E%3Cpath d='M24 14.5c-2.4 1.2-4.8 2.6-6.8 4.4'/%3E%3C/svg%3E");

  --page-w: 92.5rem;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  /* Every band's inset, so full-width bands keep one left edge. Its percentage
     resolves where it's used, against the band's own full-width parent. */
  --edge: max(var(--gutter), calc((100% - var(--page-w)) / 2));
  --nav-h: 4rem;
  --section-y: clamp(5rem, 9vw, 9.5rem);

  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --dur: 0.25s;
}

@media (max-width: 767px) {
  :root {
    --nav-h: 3.25rem;
  }
}

/* With nothing to point with, a picture's colour can't come up on demand. */
@media (hover: none) {
  :root {
    --print: saturate(0.8) brightness(0.92);
  }
}

/* ── Base ── */
*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-padding-top: calc(var(--nav-h) + 1.5rem);
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

img,
svg {
  display: block;
  max-width: 100%;
}

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

:focus-visible {
  outline: 2px solid var(--vermilion);
  outline-offset: 3px;
}

::selection {
  background: rgba(211, 75, 63, 0.2);
}

/* Read by assistive tech, not shown: a heading the page already shows another way. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The square period. Sized from its text, so it stays in proportion at any scale.
   Set closer than the brief's 9px, because the y's slant already opens the gap. */
.mark {
  display: inline-block;
  width: 0.17em;
  height: 0.17em;
  margin-left: 0.07em;
  background: var(--vermilion);
}

.meta {
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

.meta span {
  margin: 0 0.6em;
}

/* Small labels speak in the serif's italic: a magazine's voice, not a dashboard's. */
.kicker,
.labels,
.feature__eyebrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.125rem;
  line-height: 1.35;
  color: var(--vermilion-ink);
}

.labels {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
}

/* Trailing, so a wrapped list never opens a line on a slash. */
.labels li:not(:last-child)::after {
  content: '/';
  margin: 0 0.45em;
  opacity: 0.5;
}

.labels a {
  position: relative;
  z-index: 1;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}

.labels a:hover {
  text-decoration-line: underline;
}

.read-link {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--serif);
  font-size: 1.25rem;
  line-height: 1.3;
  white-space: nowrap;
}

.arrow {
  flex: none;
  width: 1.05em;
  height: 1.05em;
  color: var(--vermilion);
  transition: transform var(--dur) var(--ease);
}

.read-link:hover .arrow {
  transform: translateX(0.35rem);
}

/* Large headings: light serif at display size, the last word turning italic, closed
   by the square. They need no rule or ground to mark a new section. */
.section-title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: var(--h-section);
  line-height: 1;
  letter-spacing: -0.032em;
}

.section-title .mark,
.lead__title .mark,
.post__title .mark,
.not-found__title .mark {
  width: 0.11em;
  height: 0.11em;
  margin-left: 0.06em;
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem 3rem;
  margin-bottom: clamp(2.5rem, 4.5vw, 4.75rem);
}

/* Headline links underline themselves on hover, line by line. */
.feature__title a,
.card__title a,
.lead__title a,
.topic__title a {
  background: linear-gradient(currentColor, currentColor) 0 96% / 0 0.05em no-repeat;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size 0.55s var(--ease);
}

.feature--link:hover .feature__title a,
.card:hover .card__title a,
.lead__title a:hover,
.topic:hover .topic__title a {
  background-size: 100% 0.05em;
}

/* Every band keeps the same edge. */
.masthead__inner,
.blognav__inner,
.site-footer__inner,
.lead,
.topics-all,
.topics-more,
.empty-state,
.post__body,
.post--page {
  padding-inline: var(--edge);
}

/* ── Masthead ── */
.masthead {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}

.masthead__inner {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem clamp(2rem, 5vw, 5rem);
  padding-block: clamp(2.25rem, 3.25vw, 3.25rem) clamp(1.75rem, 2.5vw, 2.5rem);
}

/* Behind the links and running off the header, which crops it. Decorative only. */
.masthead__leaf {
  position: absolute;
  z-index: -1;
  top: clamp(-5.5rem, -5vw, -2rem);
  right: calc(var(--edge) - clamp(2.5rem, 3vw, 5rem));
  width: clamp(12.5rem, 8rem + 13vw, 18rem);
  height: auto;
  max-width: none;
  transform: rotate(30deg);
  fill: var(--ink);
  opacity: 0.05;
  pointer-events: none;
}

/* Pulled in by Archivo's side bearing, so the P's stem sits on the page's edge. */
.masthead__name {
  margin-left: -0.05em;
  font-family: var(--sans);
  font-weight: 700;
  font-size: var(--h-name);
  line-height: 1;
  letter-spacing: -0.03em;
  white-space: nowrap;
}

/* Written under the name with a fine red pen, against its weight. */
.masthead__tag {
  margin-top: 0.5rem;
  font-family: var(--hand);
  font-size: clamp(1.625rem, 1.5rem + 0.5vw, 2rem);
  line-height: 1.1;
  letter-spacing: 0.02em;
  word-spacing: 0.06em;
  color: var(--vermilion-ink);
}

.nav-links {
  display: flex;
  gap: clamp(1.25rem, 2.2vw, 2rem);
  font-size: 0.9375rem;
}

.nav-links a {
  position: relative;
  display: flex;
  align-items: center;
  white-space: nowrap;
}

.nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--vermilion);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.35s var(--ease);
}

.nav-links a:hover::after,
.nav-links a[aria-current]::after {
  transform: scaleX(1);
}

.masthead__links a {
  padding-block: 0.375rem;
}

/* ── The bar ── */
.blognav {
  position: sticky;
  top: 0;
  z-index: 90;
  overflow: hidden;
  background: var(--paper);
}

.blognav__inner {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: var(--nav-h);
}

/* The masthead's leaf, cropped to a slice by the bar. Decorative only. */
.blognav__leaf {
  position: absolute;
  z-index: -1;
  top: -3rem;
  right: calc(var(--edge) - 7rem);
  width: 11rem;
  height: auto;
  max-width: none;
  transform: rotate(30deg);
  fill: currentColor;
  opacity: 0.06;
  pointer-events: none;
}

.blognav__name {
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: -0.03em;
  white-space: nowrap;
}

.blognav__links {
  align-self: stretch;
}

/* Over a night page the bar goes dark with it. */
.is-home .blognav,
.is-list .blognav {
  background: var(--char);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12);
  color: #fff;
}

/* On the front page the bar is the masthead collapsed: out of the flow, waiting
   above the page until js/blognav.js drops it in. */
.is-home .blognav {
  position: fixed;
  left: 0;
  right: 0;
  transform: translateY(-100%);
  visibility: hidden;
  transition:
    transform 0.35s var(--ease),
    visibility 0s linear 0.35s;
}

.is-home .blognav.is-shown {
  transform: none;
  visibility: visible;
  transition: transform 0.35s var(--ease);
}

/* On a post, a fine line across the bar's foot shows how far through you are.
   Where scroll timelines aren't supported, it's simply not there. */
@supports (animation-timeline: scroll()) {
  .is-page .blognav::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: var(--vermilion);
    transform-origin: left;
    animation: read-through linear both;
    animation-timeline: scroll(root);
  }
}

/* Where the sections' line is showing, that does this job instead. */
@media (min-width: 1280px) {
  .is-page:has(.post__rail) .blognav::after {
    content: none;
  }
}

@keyframes read-through {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

/* ── The opening scene ──
   Edge to edge, the headline anchored low like a film poster. Copy and art share
   one tone: the art fades into it, so no edge divides them, and one film grain
   runs over both, so the flat tone and the photograph read as one surface. */
.feature {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: flex-end;
  min-height: clamp(32rem, calc(100svh - 15rem), 52rem);
  overflow: hidden;
  background: var(--tone);
  color: #fff;
}

.feature--post {
  min-height: clamp(30rem, calc(100svh - 13rem), 50rem);
}

.feature--next {
  min-height: clamp(26rem, 62svh, 38rem);
}

.feature::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(70% 90% at 12% 8%, rgba(255, 255, 255, 0.1), transparent 70%),
    linear-gradient(to top, rgba(0, 0, 0, 0.26), transparent 55%);
}

.feature::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--grain);
  mix-blend-mode: overlay;
  opacity: 0.32;
  pointer-events: none;
}

.feature__copy {
  width: 100%;
  padding-block: clamp(3.5rem, 5.5vw, 6rem);
  padding-inline: var(--edge);
  animation: rise 0.9s var(--ease) backwards;
}

.feature__copy > * {
  max-width: min(42rem, 48vw);
}

.feature__art {
  position: absolute;
  z-index: -1;
  top: 0;
  right: 0;
  bottom: 0;
  width: 68%;
  overflow: hidden;
  /* Eased, because a straight ramp shows where it starts as a vertical line. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent,
    rgba(0, 0, 0, 0.04) 8%,
    rgba(0, 0, 0, 0.16) 17%,
    rgba(0, 0, 0, 0.38) 27%,
    rgba(0, 0, 0, 0.66) 37%,
    rgba(0, 0, 0, 0.88) 47%,
    #000 58%
  );
  mask-image: linear-gradient(
    to right,
    transparent,
    rgba(0, 0, 0, 0.04) 8%,
    rgba(0, 0, 0, 0.16) 17%,
    rgba(0, 0, 0, 0.38) 27%,
    rgba(0, 0, 0, 0.66) 37%,
    rgba(0, 0, 0, 0.88) 47%,
    #000 58%
  );
}

.feature__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: right center;
  animation: settle 1.8s var(--ease) backwards;
  transition: transform 1.6s var(--ease);
}

.feature--link:hover .feature__art img {
  transform: scale(1.025);
}

@keyframes settle {
  from {
    transform: scale(1.05);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(0.75rem);
  }
}

.feature .labels,
.feature__eyebrow {
  font-size: clamp(1.1875rem, 1.0625rem + 0.3vw, 1.375rem);
  color: var(--accent);
}

.feature__title {
  margin-top: clamp(0.875rem, 1.2vw, 1.25rem);
  font-family: var(--sans);
  font-weight: 700;
  font-size: var(--h-scene);
  line-height: 1.03;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.feature--post .feature__title,
.feature--next .feature__title {
  font-size: var(--h-scene-post);
}

/* The whole scene is the title's hit area; the topics sit above it. */
.feature--link .feature__title a::after {
  content: '';
  position: absolute;
  inset: 0;
}

.feature__dek {
  margin-top: clamp(1.25rem, 1.8vw, 1.75rem);
  font-family: var(--serif);
  font-size: clamp(1.1875rem, 1.0625rem + 0.45vw, 1.4375rem);
  line-height: 1.42;
  color: rgba(255, 255, 255, 0.92);
  max-width: min(36rem, 46vw);
}

.feature .meta {
  margin-top: clamp(1.5rem, 2vw, 2rem);
  color: rgba(255, 255, 255, 0.74);
}

/* ── Night ──
   Below the opening scene, and on every index, the page goes dark and stays dark into
   the footer, so the scene's colour is the one loud thing. It's only a change of
   tokens: what sits on it needs no dark version of its own. */
.night,
.is-list main {
  --ink: #fff;
  --ink-body: rgba(255, 255, 255, 0.86);
  --ink-soft: rgba(255, 255, 255, 0.66);
  --ground: var(--char);
  --vermilion-ink: #e8a79f;

  display: flow-root;
  padding-bottom: clamp(3.5rem, 6vw, 6rem);
  background: var(--char);
  color: var(--ink);
}

/* Pictures on the dark are held back, so unrelated art reads as one series and the
   scene stays the brightest thing on the page. Pointing at one brings up its true
   colour while the others step back. */
.card__art img,
.mosaic img,
.strip img {
  filter: var(--print);
  transition:
    filter 0.6s var(--ease),
    transform 1.2s var(--ease);
}

.card:hover .card__art img,
.card:focus-within .card__art img,
.topic:hover .strip img,
.mosaic:hover img {
  filter: none;
}

.card:hover .card__art img,
.card:focus-within .card__art img {
  transform: scale(1.025);
}

@media (hover: hover) {
  .cards:has(.card:hover) .card:not(:hover) .card__art img {
    filter: var(--print-back);
  }
}

.further {
  margin-top: var(--section-y);
}

.further .section-head,
.index__head {
  padding-inline: var(--edge);
}

.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(3rem, 4.5vw, 4.5rem) clamp(1.5rem, 2.6vw, 2.75rem);
  padding-inline: var(--edge);
}

/* The date sits on the card's foot, so a row's labels, titles and dates share lines
   as far as the titles allow. */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
}

.card__art {
  flex: none;
  aspect-ratio: 3 / 2;
  margin-bottom: 1.125rem;
  overflow: hidden;
}

.card__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card .labels {
  font-size: 1.0625rem;
}

.card__title {
  margin-top: 0.25rem;
  font-family: var(--serif);
  font-weight: 300;
  font-size: var(--h-card);
  line-height: 1.1;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

.card__title a::after {
  content: '';
  position: absolute;
  inset: 0;
}

.card__dek {
  margin-top: 0.625rem;
  font-family: var(--serif);
  font-size: 1.125rem;
  line-height: 1.42;
  color: var(--ink-soft);
}

.card .meta {
  margin-top: auto;
  padding-top: 1rem;
}

/* Past the cards: the same posts' voice with the pictures gone, a contents page. */
.contents {
  margin-top: clamp(3.5rem, 6vw, 6.5rem);
  padding-inline: var(--edge);
}

.contents__list {
  list-style: none;
}

.contents__row {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.25rem 2rem;
  padding-block: 0.875rem;
}

.contents__title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.5rem, 1.25rem + 0.7vw, 2.125rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
  background: linear-gradient(currentColor, currentColor) 0 96% / 0 1px no-repeat;
  transition: background-size 0.45s var(--ease);
  justify-self: start;
}

.contents__row:hover .contents__title {
  background-size: 100% 1px;
}

.contents__topic {
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--vermilion-ink);
}

/* ── Posts ── */
.post__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 40rem) minmax(0, 1fr);
  column-gap: clamp(2.5rem, 4vw, 4.5rem);
  align-items: start;
  margin-top: clamp(3.5rem, 6vw, 6.5rem);
}

.prose--post {
  grid-column: 2;
}

/* The post's sections, barely there until wanted. */
.post__rail {
  grid-column: 1;
  position: sticky;
  top: calc(var(--nav-h) + 2.5rem);
  max-width: 15rem;
}

.post__rail-label {
  margin-bottom: 0.75rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--ink);
}

/* A line from the first section's dot to the last. As you read, red runs down it and
   fills the dots it passes (js/rail.js). */
.toc ul {
  position: relative;
  list-style: none;
}

.toc ul::after,
.toc li:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 0.625rem;
  left: 3px;
  width: 1px;
}

.toc ul::after {
  z-index: 1;
  height: var(--progress, 0);
  background: var(--vermilion);
}

/* Each stretch runs on past the gap to the next dot's centre. */
.toc li:not(:last-child)::after {
  bottom: -1.625rem;
  background: rgba(23, 25, 27, 0.16);
}

.toc li {
  position: relative;
  padding-left: 1.25rem;
}

.toc li + li {
  margin-top: 1rem;
}

.toc li::before {
  content: '';
  position: absolute;
  z-index: 2;
  top: 0.40625rem;
  left: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px rgba(23, 25, 27, 0.32);
  transition:
    background-color 0.2s,
    box-shadow 0.2s;
}

.toc li.is-passed::before {
  background: var(--vermilion);
  box-shadow: none;
}

.toc a {
  display: block;
  font-family: var(--serif);
  font-size: 0.9375rem;
  line-height: 1.35;
  color: var(--ink-soft);
  transition: color 0.2s;
}

.toc a:hover,
.toc a[aria-current] {
  color: var(--ink);
}

/* Each post ends on the name's square, as a magazine piece ends on its mark, on its last
   paragraph even when a note follows that. */
.prose--post > p:last-child::after,
.prose--post > p:has(+ .callout:last-child)::after {
  content: '';
  display: inline-block;
  width: 0.6em;
  height: 0.6em;
  margin-left: 0.4em;
  background: var(--vermilion);
}

/* And opens on a heavy initial: the one loud letter in the running text. */
.prose--post > p:first-child::first-letter,
.prose--post > .callout:first-child + p::first-letter {
  float: left;
  padding: 0.085em 0.06em 0 0;
  font-family: var(--sans);
  font-weight: 700;
  font-size: 5.85em;
  line-height: 0.7;
  letter-spacing: -0.03em;
  color: var(--ink);
}

/* Read next: the next post's own scene closes the page. */
.post__next {
  margin-top: var(--section-y);
}

main:has(.post__next) + .site-footer {
  margin-top: 0;
}

/* Standing pages: one centred column. */
.post__head,
.post--page .prose {
  max-width: 40rem;
  margin-inline: auto;
}

.post__head {
  margin-top: clamp(3.5rem, 6vw, 6.5rem);
}

.post__title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: var(--h-section);
  line-height: 1;
  letter-spacing: -0.032em;
}

.post__dek {
  margin-top: clamp(1.25rem, 2vw, 1.75rem);
  font-family: var(--serif);
  font-size: clamp(1.25rem, 1.45vw, 1.5rem);
  line-height: 1.42;
  color: var(--ink-soft);
}

.post--page .prose {
  margin-top: clamp(2rem, 3vw, 3rem);
}

/* ── Running text ── */
.prose {
  font-family: var(--serif);
  font-size: clamp(1.1875rem, 1.125rem + 0.15vw, 1.3125rem);
  line-height: 1.65;
  color: var(--ink-body);
}

.prose > * + * {
  margin-top: 1.1em;
}

.prose h2 {
  margin-top: 2.3em;
  font-weight: 400;
  font-size: var(--h-prose);
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
}

.prose h2 + * {
  margin-top: 0.7em;
}

.prose h3 {
  margin-top: 1.8em;
  font-weight: 600;
  font-size: 1.2em;
  line-height: 1.25;
  color: var(--ink);
}

.prose strong {
  font-weight: 600;
  color: var(--ink);
}

.prose a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--vermilion);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  transition: color 0.2s;
}

.prose a:hover {
  color: var(--vermilion-ink);
}

/* External links (the render hook opens them in a new tab) carry a small arrow. */
.prose a[target='_blank']::after {
  content: '\2197';
  display: inline-block;
  margin-left: 0.15em;
  font-family: var(--sans);
  font-size: 0.7em;
  color: var(--ink-soft);
}

.prose ul,
.prose ol {
  padding-left: 1.25em;
}

.prose li + li {
  margin-top: 0.45em;
}

.prose li::marker {
  color: var(--vermilion);
}

/* A pull quote is a line someone took a red pen to: quiet italic, underlined with two
   separate, slightly uphill strokes. They're a fixed length, not fitted to the text, as a
   pen's would be. */
.prose blockquote {
  position: relative;
  margin-block: 2.4em;
  padding-bottom: 1.75rem;
}

.prose blockquote::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: min(70%, 26rem);
  height: 1.5rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 416 24' preserveAspectRatio='none'%3E%3Cpath d='M2 13C90 8 230 4 412 3M24 22C140 17 270 13 384 12' fill='none' stroke='%23bd3a2e' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E")
    left bottom / 100% 100% no-repeat;
}

.prose blockquote p {
  font-size: clamp(1.5rem, 1.05rem + 1vw, 2.125rem);
  font-style: italic;
  line-height: 1.24;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-wrap: balance;
}

/* The said shortcode: a line somebody is speaking, after a ">". */
.said {
  display: flex;
  align-items: baseline;
  gap: 0.7em;
  font-style: italic;
  color: var(--ink);
}

.said-mark {
  flex-shrink: 0;
  font-family: var(--sans);
  font-style: normal;
  font-weight: 600;
  color: var(--vermilion-ink);
}

/* Asides are the sub-bullets of someone with a red pen: a drawn hook, then a handwritten
   heading over a small sans body. In the text column the note is indented under the
   paragraph, with the hook in the indent. */
.prose .callout {
  position: relative;
  margin-block: 1em 2em;
  padding-left: 2.125rem;
  font-family: var(--sans);
  font-size: 1rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.callout::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 1.75rem;
  height: 1.75rem;
  background: var(--vermilion-ink);
  -webkit-mask: var(--hook) center / contain no-repeat;
  mask: var(--hook) center / contain no-repeat;
}

.callout .kicker {
  margin-bottom: 0.25rem;
  font-family: var(--hand);
  font-style: normal;
  font-size: 1.625rem;
  line-height: 1.1;
  letter-spacing: 0.02em;
  word-spacing: 0.06em;
}

.callout > * + * {
  margin-top: 0.8em;
}

.prose code {
  padding: 0.1em 0.35em;
  background: var(--ground);
  font-family: var(--mono);
  font-size: 0.84em;
}

.prose pre {
  padding: 1.25rem 1.5rem;
  overflow-x: auto;
  background: var(--char);
  color: #f1f1ef;
  font-size: 0.85em;
  line-height: 1.6;
}

.prose pre code {
  padding: 0;
  background: none;
  font-size: inherit;
}

/* A hairline fading out at both ends, parted around the masthead's square. */
.prose hr {
  --line: color-mix(in srgb, var(--ink) 28%, transparent);
  position: relative;
  height: 1px;
  margin: 3em 0;
  overflow: visible;
  border: 0;
  background: linear-gradient(
    to right,
    transparent,
    var(--line) 25%,
    var(--line) calc(50% - 1rem),
    transparent calc(50% - 1rem),
    transparent calc(50% + 1rem),
    var(--line) calc(50% + 1rem),
    var(--line) 75%,
    transparent
  );
}

.prose hr::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--vermilion);
  transform: translate(-50%, -50%);
}

/* With a free right margin, asides stand in it, with the hook hanging in the gap beside
   them. A note rises to sit beside the end of its paragraph, unless there's no paragraph
   above it. */
@media (min-width: 1400px) {
  .prose--post .callout {
    float: right;
    clear: right;
    width: 16.5rem;
    /* Its foot margin clears the next note's rise, and leaves 2rem between them. */
    margin: -4.5rem -21rem 6.5rem 0;
    padding-left: 0;
  }

  .prose--post :is(h2, h3) + .callout,
  .prose--post .callout:first-child {
    margin-top: 0.3em;
  }

  .prose--post .callout::before {
    left: -2.125rem;
  }
}

/* ── Indexes: all posts, each topic, the topics page ── */
.index__head {
  margin-top: clamp(3.5rem, 6vw, 6.5rem);
}

.index__head .kicker {
  margin-bottom: 0.5rem;
}

.index__dek {
  max-width: 34em;
  margin-top: clamp(1rem, 1.6vw, 1.5rem);
  font-family: var(--serif);
  font-size: clamp(1.1875rem, 1.3vw, 1.375rem);
  line-height: 1.45;
  color: var(--ink-soft);
}

.index__head .meta {
  margin-top: 1.125rem;
}

.index > .cards {
  margin-top: clamp(3rem, 5vw, 5.5rem);
}

.index__head--all {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 30rem);
  align-items: end;
  gap: 1.5rem clamp(3rem, 6vw, 7rem);
}

.labels--index {
  justify-content: flex-end;
  font-size: 1.0625rem;
}

/* The topics page opens on one topic, its copy beside its pictures. */
.lead {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: center;
  column-gap: clamp(2rem, 4vw, 4.5rem);
  margin-top: clamp(3rem, 5vw, 5rem);
}

.lead__title {
  margin-top: 0.5rem;
  font-family: var(--serif);
  font-weight: 300;
  font-size: var(--h-section);
  line-height: 1;
  letter-spacing: -0.032em;
}

.lead__dek {
  max-width: 28em;
  margin-top: 1.25rem;
  font-family: var(--serif);
  font-size: clamp(1.1875rem, 1.3vw, 1.375rem);
  line-height: 1.42;
  color: var(--ink-soft);
}

.lead .meta {
  margin-top: 1.25rem;
}

.lead .read-link {
  margin-top: 1.75rem;
}

.topics-all,
.topics-more {
  margin-top: var(--section-y);
}

.topic-posts {
  margin-top: 1.5rem;
  list-style: none;
}

.topic-posts li + li {
  margin-top: 0.5rem;
}

.topic-posts li {
  font-family: var(--serif);
  font-size: 1.1875rem;
  line-height: 1.3;
}

.topic-posts a {
  transition: color 0.2s;
}

.topic-posts a:hover {
  color: var(--vermilion-ink);
}

.topic-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(3rem, 4vw, 4.5rem) clamp(1.5rem, 2.6vw, 2.75rem);
}

.topics-all > .section-title {
  margin-bottom: clamp(2.5rem, 4.5vw, 4.75rem);
}

.topic-grid--compact {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  row-gap: clamp(2.25rem, 3vw, 3rem);
}

/* A topic card is wholly its link: the strip, the name and the count. */
.topic {
  position: relative;
}

.topic__title {
  margin-top: 1.125rem;
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--h-card);
  line-height: 1.12;
  letter-spacing: -0.016em;
}

.topic__title a::after {
  content: '';
  position: absolute;
  inset: 0;
}

.topic__dek {
  margin-top: 0.6rem;
  font-family: var(--serif);
  font-size: 1.0625rem;
  line-height: 1.42;
  color: var(--ink-soft);
}

.topic .meta {
  margin-top: 0.625rem;
}

/* A topic's pictures. The mosaic leads with one big image; the strip sets them
   side by side as equals. */
.mosaic,
.strip {
  display: grid;
  gap: 4px;
  overflow: hidden;
  background: var(--ground);
}

.mosaic {
  grid-template-columns: 2fr 1fr;
  grid-template-rows: 1fr 1fr;
  aspect-ratio: 3 / 2;
}

.mosaic--n1 {
  grid-template-columns: 1fr;
}

.mosaic img:first-child,
.mosaic--n2 img {
  grid-row: 1 / -1;
}

.strip {
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  aspect-ratio: 2 / 1;
}

.mosaic img,
.strip img {
  width: 100%;
  height: 100%;
  min-height: 0;
  object-fit: cover;
}

.empty-state {
  margin-top: clamp(3rem, 5vw, 5rem);
  font-family: var(--serif);
  font-size: 1.25rem;
  color: var(--ink-soft);
}

.empty-state .section-title {
  color: var(--ink);
}

.empty-state p {
  margin-top: 1.25rem;
}

/* ── Footer: the promise, set large, on charcoal ── */
.site-footer {
  margin-top: var(--section-y);
  background: var(--char);
  color: #fff;
}

/* Night runs straight into it, with a hairline for the seam. */
.is-home .site-footer,
.is-list .site-footer {
  margin-top: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.site-footer__inner {
  padding-block: clamp(4rem, 7.5vw, 8rem) 2.25rem;
}

.site-footer__line {
  max-width: 15em;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(2.25rem, 1.25rem + 3.6vw, 5rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.site-footer__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 3rem;
  margin-top: clamp(3.5rem, 7vw, 7.5rem);
}

.site-footer__name {
  font-weight: 700;
  font-size: 1.375rem;
  line-height: 1;
  letter-spacing: -0.03em;
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem clamp(1.25rem, 2.2vw, 2rem);
  font-size: 0.9375rem;
  color: rgba(255, 255, 255, 0.72);
}

.site-footer__links a {
  transition: color 0.2s;
}

.site-footer__links a:hover {
  color: #fff;
}

/* ── 404 ── */
.not-found {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 48rem;
  margin: clamp(3rem, 6vw, 6rem) auto 0;
  padding-inline: var(--gutter);
  text-align: center;
}

.not-found__title {
  margin-top: 0.5rem;
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(2.75rem, 1.5rem + 3.2vw, 4.5rem);
  line-height: 1.02;
  letter-spacing: -0.03em;
}

.not-found__dek {
  margin-top: 1.25rem;
  font-family: var(--serif);
  font-size: 1.25rem;
  color: var(--ink-soft);
}

.not-found__gif {
  width: min(32.5rem, 100%);
  margin-top: 2.5rem;
}

.not-found__gif img {
  width: 100%;
  height: auto;
}

.not-found__gif figcaption {
  margin-top: 0.75rem;
  font-family: var(--serif);
  font-style: italic;
  color: var(--ink-soft);
}

.not-found__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1rem 2.25rem;
  margin-top: 2.25rem;
  font-size: 1rem;
  color: var(--ink-soft);
}

.not-found__links a:not(.read-link):hover {
  color: var(--vermilion-ink);
}

/* ── Narrower screens ── */
/* No room for a margin column: the text alone, centred. */
@media (max-width: 1279px) {
  .post__body {
    grid-template-columns: minmax(0, 40rem);
    justify-content: center;
  }

  .prose--post {
    grid-column: 1;
  }

  .post__rail {
    display: none;
  }

  .topic-grid--compact {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Stacked: the copy first, then the art fading up into the same tone. The grid
   settles to two even columns under a full-width first post. */
@media (max-width: 960px) {
  .index__head--all,
  .lead {
    grid-template-columns: minmax(0, 1fr);
  }

  .labels--index {
    justify-content: flex-start;
  }

  .feature,
  .feature--post,
  .feature--next {
    display: block;
    min-height: 0;
  }

  .feature__copy {
    padding-block: clamp(2.75rem, 7vw, 4rem) clamp(1.25rem, 3vw, 2rem);
  }

  .feature__copy > *,
  .feature__dek {
    max-width: 40rem;
  }

  .feature__art {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 3 / 2;
    -webkit-mask-image: linear-gradient(
      to bottom,
      transparent,
      rgba(0, 0, 0, 0.3) 8%,
      rgba(0, 0, 0, 0.75) 17%,
      #000 26%
    );
    mask-image: linear-gradient(
      to bottom,
      transparent,
      rgba(0, 0, 0, 0.3) 8%,
      rgba(0, 0, 0, 0.75) 17%,
      #000 26%
    );
  }

  .cards,
  .topic-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .lead .mosaic {
    order: -1;
    margin-bottom: 1.75rem;
  }
}

/* Phones: the masthead stacks and every index goes to one column. */
@media (max-width: 767px) {
  .masthead__inner {
    flex-direction: column;
    align-items: flex-start;
  }

  .masthead__leaf {
    top: -2.5rem;
    right: -3.5rem;
  }

  .blognav__inner {
    gap: 0.75rem;
  }

  .blognav__name {
    font-size: 1.25rem;
  }

  .blognav__links {
    gap: 1rem;
    font-size: 0.875rem;
  }

  .cards,
  .topic-grid,
  .topic-grid--compact {
    grid-template-columns: minmax(0, 1fr);
  }

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

  .contents__row .meta {
    grid-column: 1 / -1;
  }
}

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