/* ============================================================
   paper.css — the entire design
   Palette:  newsprint grey, ink, registration red, ghost cyan
   Type:     blackletter masthead / Archivo condensed caps (headlines) / Source Serif 4 (body)
             Encode Sans Condensed (utility) / JetBrains Mono (data)
   Signature: offset misregistration on the masthead + halftone plates
   ============================================================ */

:root {
  --paper:      #e3dfd4;
  --paper-deep: #d8d3c5;
  --plate-paper: #e5e1d7;   /* photographs are prints. prints are on paper,
                              whatever colour the page behind them is. */
  --ink:        #17171b;
  --ink-soft:   #56564f;
  --ink-faint:  #8b8a80;
  --rule:       #b6b3a8;
  --spot:       #b3122b;   /* registration red — section flags, nothing else */
  --ghost:      #2aa4b8;   /* cyan misregistration only. never for text. */

  --masthead: "Manufacturing Consent", "Old English Text MT", serif;
  --display: "Archivo", "Arial Narrow", sans-serif;
  --body:    "Source Serif 4", Georgia, serif;
  --util:    "Encode Sans Condensed", "Arial Narrow", sans-serif;
  --data:    "JetBrains Mono", ui-monospace, monospace;

  --measure: 66ch;
  --gutter: 1.6rem;
}

/* The theme is an attribute on <html>, set by a tiny inline script before paint.
   That keeps all the dark values in ONE selector instead of duplicating them
   across a media query and an override. */
:root { color-scheme: light; }

:root[data-theme="dark"] {
  /* microfiche: there is no such thing as a newspaper at night, so we pick
     the next most honest object — a reel of amber film on a reader. */
  color-scheme: dark;
  --paper:      #0d0e11;
  --paper-deep: #16171b;
  --ink:        #e9dfc6;
  --ink-soft:   #a89f8a;
  --ink-faint:  #6d6759;
  --rule:       #3a3a38;
  --spot:       #e2685f;
  --ghost:      #2aa4b8;
}

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

body {
  margin: 0;
  background: var(--paper);
  position: relative;
  color: var(--ink);
  font-family: var(--body);
  font-size: 1.0625rem;
  line-height: 1.62;
  font-variant-numeric: oldstyle-nums;
  -webkit-font-smoothing: antialiased;
}

.sheet {
  max-width: 92rem;
  margin: 0 auto;
  padding: 0 var(--gutter) 5rem;
}

/* ---------- the paper itself ---------- */
/* fractal noise, generated by the browser, tiled. no image file. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;          /* above the text, below the plates. see .plate */
  pointer-events: none;
  opacity: .38;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* grain on a dark page must lighten, not darken, or it only muddies */
:root[data-theme="dark"] body::before { mix-blend-mode: screen; opacity: .16; }

/* ---------- the appearance switch ---------- */
.edition-toggle {
  font: inherit; font-family: var(--util); font-size: .72rem;
  letter-spacing: .09em; text-transform: uppercase;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--ink-faint); text-decoration: underline;
  text-decoration-color: var(--rule); text-underline-offset: 3px;
}
.edition-toggle:hover { color: var(--spot); }

/* ---------- rules ---------- */
.rule      { border: 0; border-top: 1px solid var(--rule); margin: 0; }
.rule--hair{ border-top-width: 1px; }
.rule--thick { border-top: 3px double var(--ink); }

/* ---------- folio ---------- */
.folio {
  display: flex; justify-content: space-between; gap: 1rem;
  font-family: var(--util); font-size: .72rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--ink-faint);
  padding: .7rem 0 .5rem;
}
.folio span:nth-child(2) { text-align: center; }

/* ---------- masthead + ears ---------- */
/* "ears" is the real term for the boxes flanking a masthead. they are always
   there in a real paper, and their absence is why a masthead floats. */
.masthead-row {
  display: grid;
  grid-template-columns: 9rem 1fr 9rem;
  align-items: center;
  gap: var(--gutter);
}
.ear {
  font-family: var(--util); font-size: .72rem; line-height: 1.4;
  color: var(--ink-soft); border: 1px solid var(--rule); padding: .45rem .55rem;
}
.ear--right { text-align: right; }
.ear__label {
  display: block; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink); font-size: .66rem;
}
@media (max-width: 720px) {
  .masthead-row { grid-template-columns: 1fr; }
  .ear { display: none; }   /* on a phone the masthead needs the whole width */
}

.masthead { text-align: center; padding: .9rem 0 .6rem; }
.masthead__name {
  font-family: var(--masthead);
  font-weight: 400;
  font-size: clamp(2.2rem, 7.5vw, 5rem);
  line-height: .92;
  letter-spacing: -0.02em;
  margin: 0;
  /* the signature: cheap offset press, plates a hair out of register */
  text-shadow: 1.5px 0 0 color-mix(in srgb, var(--ghost) 55%, transparent),
              -1.5px 0 0 color-mix(in srgb, var(--spot) 45%, transparent);
}
.masthead__name a { color: inherit; text-decoration: none; }
.masthead__rule { border: 0; border-top: 1px solid var(--ink); margin: .55rem 0 0; }
.masthead__motto {
  font-family: var(--util); font-size: .72rem; letter-spacing: .34em;
  text-transform: uppercase; color: var(--ink-soft); margin: .5rem 0 0;
}

/* ---------- nav ---------- */
.nav {
  display: flex; flex-wrap: wrap; gap: 0 1.5rem; justify-content: center;
  font-family: var(--util); font-size: .8rem; letter-spacing: .12em;
  text-transform: uppercase; padding: .55rem 0;
  border-top: 1px solid var(--ink); border-bottom: 3px double var(--ink);
}
.nav a { color: var(--ink); text-decoration: none; padding: .15rem 0; }
.nav a:hover, .nav a[aria-current="page"] { color: var(--spot); }

/* ---------- section flag ---------- */
.flag {
  font-family: var(--util); font-size: .72rem; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--spot);
  border-bottom: 1px solid var(--ink); padding-bottom: .3rem; margin-bottom: .6rem;
}

/* ---------- dateline ---------- */
/* wire-service convention: body copy opens with where it was filed from. */
.dateline {
  font-family: var(--util); font-weight: 600; font-size: .8em;
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink);
}

/* ---------- the seconds row ---------- */
.seconds {
  display: grid; grid-template-columns: 1fr; gap: 0 var(--gutter);
}
.seconds__item { padding: 1rem 0; border-top: 1px solid var(--rule); }
@media (min-width: 700px) {
  .seconds { grid-template-columns: 1fr 1fr; }
  .seconds__item:nth-child(2n) { border-left: 1px solid var(--rule); padding-left: var(--gutter); }
}
@media (min-width: 1100px) {
  .seconds { grid-template-columns: repeat(4, 1fr); }
  .seconds__item:nth-child(n) { border-left: 1px solid var(--rule); padding-left: var(--gutter); }
  .seconds__item:first-child { border-left: 0; padding-left: 0; }
}

/* ---------- motoring ---------- */
/* the fold: the car of the issue takes about two thirds, a note takes the rest */
.fold {
  display: grid;
  grid-template-columns: minmax(0, 2.1fr) minmax(0, 1fr);
  gap: 0 var(--gutter);
}
.fold__note { border-left: 1px solid var(--rule); padding-left: var(--gutter); }

/* the cross: the picture row mirrors the motoring row, so the heavy blocks
   alternate left/right down the page instead of stacking into a column */
.fold--flip { grid-template-columns: minmax(0, 1fr) minmax(0, 2.1fr); }
.fold--flip .fold__note { border-left: 0; border-right: 1px solid var(--rule);
  padding-left: 0; padding-right: var(--gutter); }
.fold__picture { margin: 0; }
@media (max-width: 700px) {
  .fold, .fold--flip { grid-template-columns: 1fr; }
  .fold__note, .fold--flip .fold__note {
    border-left: 0; border-right: 0; padding-left: 0; padding-right: 0;
    border-top: 1px solid var(--rule); margin-top: 1rem; padding-top: 1rem;
  }
  /* stacked, the picture should lead its row rather than trail it */
  .fold--flip .fold__note { order: 2; }
}

/* ---------- the picture desk ---------- */
.frames {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--gutter);
  margin-top: 1.5rem;
}
/* a picture page has a dominant frame. it is always the first one written. */
.frame--lead { grid-column: 1 / -1; }
.frame--lead .frame__plate { aspect-ratio: 21/9; }
.frame { margin: 0; }
.frame__btn {
  display: block; width: 100%; padding: 0; border: 0; background: none;
  cursor: zoom-in; font: inherit;
}
.frame__plate { aspect-ratio: 3/2; }
.lot--frame { max-width: 56rem; }
.lot--frame .plate { margin-bottom: .6rem; }

.carbox { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: var(--gutter); }
.carbox__plate { aspect-ratio: 4/3; }
@media (max-width: 560px) { .carbox { grid-template-columns: 1fr; } }

/* the catalogue grid */
.cars {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1px;
  background: var(--rule);          /* the 1px gap IS the rules between cells */
  border: 1px solid var(--rule);
  margin-top: 1.5rem;
}
.car {
  font: inherit; text-align: left; cursor: pointer;
  background: var(--paper); border: 0; padding: .7rem;
  display: flex; flex-direction: column; gap: .4rem;
}
.car:hover { background: var(--paper-deep); }
.car__plate { aspect-ratio: 4/3; }
.car__name {
  font-family: var(--display); font-variation-settings: "wdth" 80, "wght" 700;
  font-size: .95rem; color: var(--ink); line-height: 1.15;
}
.car__meta {
  font-family: var(--util); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* the lot card */
.lot {
  max-width: 34rem; width: calc(100% - 2rem);
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--ink); padding: 1.2rem;
}
.lot::backdrop { background: rgba(0, 0, 0, .55); }
.lot__close {
  float: right; font: inherit; font-size: 1.4rem; line-height: 1;
  background: none; border: 0; color: var(--ink-faint); cursor: pointer;
}
.lot__close:hover { color: var(--spot); }
.lot__plate { aspect-ratio: 4/3; margin: .8rem 0; }
.lot__note { font-size: .92rem; color: var(--ink-soft); margin: .8rem 0 0; }
.lot__data { border-collapse: collapse; font-family: var(--util); font-size: .8rem; }
.lot__data th {
  text-align: left; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); padding: .2rem 1rem .2rem 0; white-space: nowrap;
}
.lot__data td { color: var(--ink); padding: .2rem 0; }

/* the page: catalogue left, standing matter right. align-items:start is what
   lets the rail be sticky — a stretched grid item has nothing to slide within. */
.motoring {
  display: grid;
  grid-template-columns: minmax(0, 3.2fr) minmax(0, 1fr);
  gap: 0 var(--gutter);
  align-items: start;
  margin-top: 1.5rem;
}
.motoring__rail {
  position: sticky;
  top: 1rem;
  border-left: 1px solid var(--rule);
  padding-left: var(--gutter);
}
@media (max-width: 850px) {
  .motoring { grid-template-columns: 1fr; }
  .motoring__rail {
    position: static; border-left: 0; padding-left: 0;
    border-top: 3px double var(--ink); margin-top: 2rem; padding-top: 1rem;
  }
}

/* arrivals — the shipping news, as a stock table. year, bar, count. */
.arrivals { width: 100%; border-collapse: collapse; }
.arrivals th {
  font-family: var(--data); font-size: .78rem; color: var(--ink-faint);
  text-align: left; font-weight: 400; padding: .3rem .6rem .3rem 0; width: 3rem;
}
.arrivals td { padding: .3rem 0; border-top: 1px solid var(--rule); }
.arrivals__bar {
  display: inline-block; height: .62rem; background: var(--ink);
  vertical-align: middle; min-width: 2px;
}
.arrivals__n {
  font-family: var(--data); font-size: .72rem; color: var(--ink-soft);
  padding-left: .4rem; vertical-align: middle;
}

.tally { border: 1px solid var(--ink); padding: .7rem .8rem; margin-bottom: 1.4rem; }
.tally__n {
  font-family: var(--display); font-variation-settings: "wdth" 70, "wght" 900;
  font-size: 2.6rem; line-height: 1; color: var(--ink);
}
.tally__label {
  font-family: var(--util); font-size: .7rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* ---------- arts & leisure ---------- */
/* An arts page is a lead review plus listings. Three equal lists is a document
   with columns; one big thing and three dense ones is a page. */
.culture-lead {
  display: grid;
  grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr);
  gap: 0 var(--gutter);
  padding-top: 1.2rem;
}
.culture-lead__note {
  font-family: var(--body); font-size: 1.05rem; line-height: 1.6;
  color: var(--ink); margin: .8rem 0 0; max-width: 46ch;
}
.culture-lead__box {
  border-left: 1px solid var(--rule); padding-left: var(--gutter);
}
.culture-lead__box p {
  font-size: .85rem; color: var(--ink-soft); margin: .5rem 0 0;
}
@media (max-width: 820px) {
  .culture-lead { grid-template-columns: 1fr; }
  .culture-lead__box {
    border-left: 0; padding-left: 0;
    border-top: 1px solid var(--rule); margin-top: 1.2rem; padding-top: .8rem;
  }
}

.stars { color: var(--spot); font-size: 1.1rem; letter-spacing: .18em; margin: .2rem 0 0; }

/* the listings: three columns of dense entries, hairlines between */
.listings {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 var(--gutter);
  margin-top: 1.2rem;
}
@media (min-width: 700px)  { .listings { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .listings { grid-template-columns: 1fr 1fr 1fr; } }
.listings__desk + .listings__desk { border-left: 1px solid var(--rule); padding-left: var(--gutter); }
@media (max-width: 999px) {
  /* at two columns the third desk wraps, so the rule cannot be "every one but
     the first" — reset and re-apply per row */
  .listings__desk:nth-child(2n+1) { border-left: 0; padding-left: 0; }
  .listings__desk:nth-child(n+3) { border-top: 1px solid var(--rule); margin-top: 1.2rem; padding-top: 1rem; }
}
@media (max-width: 699px) {
  .listings__desk + .listings__desk {
    border-left: 0; padding-left: 0;
    border-top: 3px double var(--ink); margin-top: 1.5rem; padding-top: 1rem;
  }
}

.listing { padding: .8rem 0; border-bottom: 1px solid var(--rule); }
.listing:first-of-type { padding-top: .4rem; }
.listing__stars { color: var(--spot); font-size: .72rem; letter-spacing: .1em; margin: 0 0 .15rem; }
.listing__title {
  font-family: var(--display); font-variation-settings: "wdth" 78, "wght" 800;
  font-size: 1.05rem; line-height: 1.15; margin: 0; color: var(--ink);
  text-transform: uppercase;
}
.listing__by {
  font-family: var(--util); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); margin: .15rem 0 .3rem;
}
.listing__note { font-size: .88rem; line-height: 1.5; color: var(--ink-soft); margin: 0; }

/* the standing recommendation, in the rail */
.recommends { border: 1px solid var(--ink); padding: .7rem .8rem; margin-top: 1.6rem; }
.recommends__desk {
  font-family: var(--util); font-size: .66rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--spot); margin: 0 0 .3rem;
}
.recommends__title {
  font-family: var(--display); font-variation-settings: "wdth" 76, "wght" 800;
  font-size: 1.15rem; line-height: 1.15; margin: 0; color: var(--ink);
}
.recommends__by {
  font-family: var(--util); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); margin: .2rem 0 .4rem;
}
.recommends__note { font-size: .85rem; color: var(--ink-soft); margin: 0; }

/* ---------- index box ---------- */
.index-box { border: 1px solid var(--ink); padding: .7rem .8rem; }
.index-box__row {
  display: flex; align-items: baseline; gap: .4rem;
  font-family: var(--util); font-size: .8rem; color: var(--ink);
  text-decoration: none; padding: .22rem 0;
  text-transform: capitalize;
}
.index-box__row:hover { color: var(--spot); }
/* the dotted leader, like a real index. it is just a stretchy dashed rule. */
.index-box__leader {
  flex: 1; border-bottom: 1px dotted var(--rule); transform: translateY(-.2em);
}

/* ---------- corrections ---------- */
.correction-box { border-top: 3px double var(--ink); margin-top: 1.4rem; padding-top: .6rem; }
.correction-box p { font-size: .85rem; color: var(--ink-soft); margin: .3rem 0 0; }
.correction-box a { color: var(--ink); }
.correction {
  border-left: 3px solid var(--spot); background: var(--paper-deep);
  padding: .6rem .8rem; font-size: .9rem; margin-bottom: 1.2rem;
}

/* ---------- figures ---------- */
.figure { margin: 0 0 1rem; }

/* ---------- the crossword ---------- */
/* Real cells, placed by coordinate. The gaps between words are not black
   squares — they are simply cells that do not exist, so the paper shows through.
   --cell is set by the caller: small in Column One, large in the dialog. */
.xword {
  --cell: 1.35rem;
  display: grid;
  grid-template-columns: repeat(var(--cols), var(--cell));
  grid-template-rows: repeat(var(--rows), var(--cell));
  gap: 0;
  width: max-content;
  max-width: 100%;
}
.xword__cell {
  position: relative;
  background: var(--paper-deep);      /* deeper than the page, so it reads as a printed grid */
  border: 1px solid var(--ink);
  margin: -0.5px;                     /* collapse the borders into single hairlines */
}
.xword__n {
  position: absolute; top: 1px; left: 2px;
  font-family: var(--data);
  font-size: calc(var(--cell) * .3);
  line-height: 1; color: var(--ink-soft);
}
.xword__a {
  display: grid; place-items: center; height: 100%;
  font-family: var(--display); font-variation-settings: "wdth" 90, "wght" 700;
  font-size: calc(var(--cell) * .62); color: var(--ink);
}

.puzzle { border-top: 3px double var(--ink); margin-top: 1.6rem; padding-top: .8rem; }
.puzzle__btn {
  display: block; padding: 0; border: 0; background: none;
  cursor: zoom-in; font: inherit; margin-bottom: .7rem;
}

.clues { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--gutter); }
.clues--compact { grid-template-columns: 1fr; gap: .6rem; }
.clues__head {
  font-family: var(--util); font-size: .68rem; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink);
  border-bottom: 1px solid var(--rule); padding-bottom: .2rem; margin: 0 0 .3rem;
}
.clues__list { list-style: none; margin: 0; padding: 0; }
.clues__list li {
  font-size: .78rem; line-height: 1.4; color: var(--ink-soft); margin-bottom: .2rem;
}
.clues__n { font-family: var(--data); font-size: .72rem; color: var(--ink); }

.solution { margin-top: 1rem; border-top: 1px solid var(--rule); padding-top: .5rem; }
.solution__toggle {
  font-family: var(--util); font-size: .72rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--spot); cursor: pointer;
}
.solution__body {
  transform: rotate(180deg);          /* as a paper prints it. turn your head. */
  font-family: var(--data); font-size: .68rem; line-height: 1.5;
  color: var(--ink-soft); margin-top: .5rem;
}
.solution__body p { margin: .2rem 0; }

.lot--puzzle { max-width: 62rem; }
.puzzle-big { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--gutter); margin-top: .8rem; }
.puzzle-big .xword { --cell: 2rem; }
@media (max-width: 720px) {
  .puzzle-big { grid-template-columns: 1fr; }
  .puzzle-big .xword { --cell: 1.6rem; }
}

/* ---------- the cartoon ---------- */
.cartoon { border-top: 3px double var(--ink); margin: 1.6rem 0 0; padding-top: .8rem; }
.plate { position: relative; overflow: hidden; background: var(--plate-paper); }
.cartoon__missing {
  border: 1px dashed var(--rule); background: var(--paper-deep);
  padding: 1.4rem 1rem; text-align: center;
}
.cartoon__missing p {
  font-family: var(--display); font-variation-settings: "wdth" 80, "wght" 700;
  text-transform: uppercase; font-size: .95rem; color: var(--ink-soft); margin: 0;
}
.cartoon__missing-sub {
  font-family: var(--body) !important; font-variation-settings: normal !important;
  text-transform: none !important; font-size: .78rem !important;
  font-style: italic; color: var(--ink-faint) !important; margin-top: .5rem !important;
}

/* ---------- markets ---------- */
/* A newspaper prints a stock TABLE, not a scrolling chyron. Static, dense,
   read at a glance. This is a real <table> because it is real tabular data. */
.markets {
  width: 100%;
  border-collapse: collapse;
  border-bottom: 3px double var(--ink);
  margin-top: .4rem;
}
.markets__caption {
  font-family: var(--util); font-size: .68rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-faint);
  text-align: left; padding: .5rem 0 .35rem;
}
.markets__q {
  padding: .3rem .9rem .5rem 0;
  white-space: nowrap;
  border-right: 1px solid var(--rule);
  padding-left: .9rem;
}
.markets__q:first-child { padding-left: 0; }
.markets__q:last-child { border-right: 0; }
.markets__sym {
  font-family: var(--display); font-variation-settings: "wdth" 78, "wght" 800;
  font-size: .95rem; color: var(--ink); padding-right: .5rem;
}
.markets__last { font-family: var(--data); font-size: .85rem; color: var(--ink); }
.markets__chg { font-family: var(--data); font-size: .78rem; padding-left: .5rem; }
.markets__q--up   .markets__chg { color: var(--spot); }
.markets__q--down .markets__chg { color: var(--ink-soft); }
.markets__q--flat .markets__chg { color: var(--ink-faint); }
@media (max-width: 700px) {
  /* a table cannot wrap, so on a phone the strip becomes a scrollable tape */
  .markets { display: block; overflow-x: auto; }
}

/* ---------- front page grid ---------- */
/* Three zones, deliberately unequal: the left feature column is thinner than
   the right rail, which pushes the main column left of centre — where the eye
   lands anyway. Equal rails read as a template.
   DOM order is main, one, rail: the lead story is first for a screen reader
   and for a phone, and grid-template-areas puts Column One back on the left. */
.front {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 2.6fr) minmax(0, 1.15fr);
  grid-template-areas: "one main rail";
  gap: 0 var(--gutter);
  padding-top: 1.4rem;
}
.front__main { grid-area: main; }

.front__one {
  grid-area: one;
  border-right: 1px solid var(--rule);
  padding-right: var(--gutter);
}
.front__aside {
  grid-area: rail;
  border-left: 1px solid var(--rule);
  padding-left: var(--gutter);
}

/* Two zones: the rail is navigation and stays. Column One drops below the
   fold and goes wide, set in two columns like a real feature spread. */
@media (max-width: 1200px) {
  .front {
    grid-template-columns: minmax(0, 2.4fr) minmax(0, 1.2fr);
    grid-template-areas:
      "main rail"
      "one  one";
  }
  .front__one {
    border-right: 0;
    padding-right: 0;
    border-top: 3px double var(--ink);
    margin-top: 2rem;
    padding-top: 1rem;
  }
  .front__one .teaser { columns: 2; column-gap: var(--gutter); column-rule: 1px solid var(--rule); }
}

@media (max-width: 850px) {
  .front { grid-template-columns: 1fr; grid-template-areas: "main" "one" "rail"; }
  .front__one .teaser { columns: 1; }
  .front__aside {
    border-left: 0; padding-left: 0;
    border-top: 3px double var(--ink); margin-top: 2rem; padding-top: 1rem;
  }
}

/* ---------- headlines ---------- */
/* headlines: condensed gothic, all caps, like an American paper.
   wdth is a REAL axis (62-125) — the designer drew every width, so narrowing
   keeps every stroke correct. this is the honest version of "stretch to fit". */
.hl {
  font-family: var(--display);
  font-variation-settings: "wdth" 72, "wght" 800;
  line-height: 1.04; letter-spacing: 0;
  margin: .2rem 0 .4rem; text-wrap: balance;
}
.hl--lead, .hl--sec { text-transform: uppercase; }
.hl--lead { font-variation-settings: "wdth" 66, "wght" 900; letter-spacing: -.005em; }
/* the anchor may be inside .hl (headlines) or be the .hl itself (briefs rail) */
.hl a, a.hl { color: inherit; text-decoration: none; }
.hl a:hover, a.hl:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.hl--lead { font-size: clamp(2rem, 4.6vw, 3.4rem); }
.hl--sec  { font-size: clamp(1.4rem, 2.4vw, 1.9rem); }
.hl--one { font-size: 1.25rem; font-variation-settings: "wdth" 78, "wght" 800; text-transform: uppercase; }
.hl--brief { font-size: 1.05rem; font-variation-settings: "wdth" 85, "wght" 600; line-height: 1.25; }

.dek {
  font-family: var(--body); font-style: italic; font-size: 1.05rem;
  color: var(--ink-soft); margin: 0 0 .7rem; text-wrap: pretty;
}
.byline {
  font-family: var(--util); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); margin: 0 0 .8rem;
}

/* ---------- teaser columns (front page only — never article bodies) ---------- */
/* justified, hyphenated columns — this is what makes a column look printed.
   justification without hyphenation opens rivers of white; the two ship together. */
.teaser {
  font-size: .95rem;
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
  text-wrap: pretty;
}
@media (min-width: 851px) {
  .teaser--2col { columns: 2; column-gap: var(--gutter); column-rule: 1px solid var(--rule); }
}
.teaser p { margin: 0 0 .7rem; }
.jump {
  font-family: var(--util); font-size: .74rem; font-style: italic;
  letter-spacing: .05em; color: var(--spot); text-decoration: none;
}
.jump:hover { text-decoration: underline; }

/* ---------- plate (photo) ---------- */
/* Photographs arrive already screened by tools/screen.py, with the paper colour
   baked into the file. So: no blending, no filters, nothing themed. The one
   trick left is z-index — a print laid on the page does not get the page's
   grain over it, and body::before sits at z-index 1. */
.plate {
  position: relative;
  z-index: 2;
  overflow: hidden;
  background: var(--plate-paper);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .14);
}
.plate img { display: block; width: 100%; height: 100%; object-fit: cover; }
.plate__caption {
  font-family: var(--util); font-size: .72rem; color: var(--ink-faint);
  padding-top: .35rem; line-height: 1.35;
}

/* ---------- briefs list ---------- */
.briefs { list-style: none; margin: 0; padding: 0; }
.briefs li { padding: .6rem 0; border-bottom: 1px solid var(--rule); }
.briefs li:first-child { padding-top: 0; }
.brief__meta {
  font-family: var(--util); font-size: .7rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* ---------- project cards ---------- */
/* .article.article--wide, not .article--wide: chaining makes it (0,2,0), so it
   beats .article (0,1,0) regardless of which is written first. A modifier that
   relies on source order is a bug waiting for someone to reorder the file. */
.article.article--wide { max-width: none; }
.dek--sm { font-size: .95rem; }
.cards {
  display: grid; grid-template-columns: 1fr;
  gap: 0 var(--gutter); margin-top: 1.5rem;
}
.card { padding: 1.2rem 0; border-top: 1px solid var(--rule); }
.card__plate { aspect-ratio: 3/2; margin-bottom: .7rem; }
@media (min-width: 700px) {
  .cards { grid-template-columns: 1fr 1fr; }
  /* the rule falls between the columns, not down the page edge */
  .card:nth-child(2n) { border-left: 1px solid var(--rule); padding-left: var(--gutter); }
}

/* ---------- classifieds ---------- */
.classified {
  border: 1px solid var(--ink); padding: .8rem; margin-top: 1.4rem;
  background: var(--paper-deep);
}
.classified p {
  font-family: var(--body); font-size: .9rem; margin: .4rem 0 0; color: var(--ink-soft);
}
.classified a { color: var(--spot); }

/* ---------- article ---------- */
.article { max-width: var(--measure); margin: 2.5rem auto 0; }
.article__body > * + * { margin-top: 1.1rem; }
.article__body p { text-align: justify; hyphens: auto; -webkit-hyphens: auto; }
.article__body h2 {
  font-family: var(--display); font-size: 1.55rem; font-weight: 700;
  margin-top: 2.2rem; line-height: 1.15;
}
.article__body h3 { font-family: var(--util); font-size: 1rem; letter-spacing: .06em; text-transform: uppercase; margin-top: 1.8rem; }
.article__body > p:first-of-type::first-letter {
  float: left; font-family: var(--display); font-weight: 700;
  font-size: 3.6em; line-height: .78; padding: .05em .08em 0 0; color: var(--ink);
}
.article__body blockquote {
  margin: 1.6rem 0; padding: 0 0 0 1rem; border-left: 3px solid var(--spot);
  font-family: var(--display); font-size: 1.3rem; line-height: 1.3; color: var(--ink);
}
.article__body a { color: var(--ink); text-decoration-color: var(--spot); text-underline-offset: 3px; }
.article__body pre {
  font-family: var(--data); font-size: .82rem; background: var(--paper-deep);
  padding: .9rem; overflow-x: auto; border-left: 2px solid var(--rule);
}
.article__body code { font-family: var(--data); font-size: .85em; }
.article__body img { width: 100%; }

/* ---------- the about page ---------- */
/* Prose is one centred column. Each picture is a child of the paragraph it
   belongs beside, pulled out to that paragraph's own gutter with an absolute
   position. Because the anchor is the paragraph (position:relative on it),
   there are NO magic offset numbers — edit the prose freely and every picture
   follows its paragraph automatically. This is the fix for both the gaps
   (pictures are no longer grid rows) and the fragility (nothing is hand-tuned). */
.article--about { max-width: none; }
.article--about > .flag,
.article--about > .hl,
.article--about > .standfirst,
.article--about .article__body { max-width: 40rem; margin-left: auto; margin-right: auto; }

/* a paragraph that hosts a picture becomes the anchor for it */
.article--about .has-figure { position: relative; }

.article--about .side {
  position: absolute; top: 0;
  width: min(20rem, 32vw);
  margin: 0;
}
.article--about .side--right { left: calc(100% + 2.5rem); }
.article--about .side--left  { right: calc(100% + 2.5rem); }
.article--about .side > .plate,
.article--about .side > .mugshot,
.article--about .side > img { display: block; width: 100%; }
.article--about .side .plate__caption { display: block; }
.article--about .side img { display: block; width: 100%; }

.article--about .mugshot img {
  display: block; width: 100%; aspect-ratio: 1/1; object-fit: cover;
  background: var(--plate-paper); box-shadow: 0 0 0 1px rgba(0, 0, 0, .14);
}
.article--about .editor-box {
  border: 1px solid var(--ink); padding: .8rem; background: var(--paper-deep);
}
.article--about .editor-box__line, .article--about .editor-box__line {
  display: block; font-family: var(--body); font-size: .85rem; line-height: 1.45;
  color: var(--ink-soft); margin: .5rem 0 0; text-align: left; hyphens: none;
}
.article--about .editor-box__head { display: block; color: var(--ink); border-color: var(--rule); margin-bottom: .2rem; }
.article--about .editor-box__line { display: block; font-family: var(--body); font-size: .85rem; line-height: 1.45; color: var(--ink-soft); margin-top: .5rem; text-align: left; }
.article--about .editor-box a { color: var(--spot); }
.article--about .plate__caption { margin-top: .3rem; }
.article--about h3 { padding-top: .6rem; clear: none; }

.standfirst {
  font-family: var(--body); font-style: italic;
  font-size: 1.15rem; line-height: 1.5; color: var(--ink-soft);
  border-bottom: 1px solid var(--rule); padding-bottom: .8rem; margin: .4rem 0 1.4rem;
}

/* No gutters below 1180px: pictures rejoin the flow, positioning off. */
@media (max-width: 1180px) {
  .article--about .article__body { max-width: var(--measure); }
  .article--about .side {
    position: static; width: 100%; margin: 1.2rem 0;
    left: auto; right: auto;
  }
  .article--about .side.mugshot { width: 10rem; }
}

/* ---------- links & connections ---------- */
.links { margin: 1rem 0 0; }
.links__a {
  font-family: var(--util); font-size: .8rem; letter-spacing: .04em;
  color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--spot); padding-bottom: 1px;
}
.links__a:hover { color: var(--spot); }
.links__sep { color: var(--ink-faint); margin: 0 .3rem; }

.backlink {
  font-family: var(--util); font-size: .78rem; color: var(--ink-soft);
  border-left: 2px solid var(--spot); padding-left: .7rem; margin: 1rem 0 0;
}
.backlink a { color: var(--spot); }

.related { border-top: 3px double var(--ink); margin-top: 2rem; padding-top: .8rem; }
.related__list { list-style: none; margin: .6rem 0 0; padding: 0; }
.related__list li { padding: .5rem 0; border-bottom: 1px solid var(--rule); }
.related__title {
  font-family: var(--display); font-variation-settings: "wdth" 82, "wght" 700;
  font-size: 1.05rem; color: var(--ink); text-decoration: none; display: block;
}
.related__title:hover { color: var(--spot); }
.related__meta {
  font-family: var(--util); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint);
}

/* ---------- obituary ---------- */
.obit__dates {
  font-family: var(--util); font-size: .8rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-soft); text-align: center;
}
.obit__cause {
  font-family: var(--body); font-style: italic; text-align: center;
  color: var(--ink-soft); border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule); padding: .7rem 0; margin: 1rem 0 2rem;
}

/* ---------- archive ---------- */
.issue { display: grid; grid-template-columns: 8rem 1fr; gap: 1rem; padding: .7rem 0; border-bottom: 1px solid var(--rule); }
.issue__no { font-family: var(--data); font-size: .8rem; color: var(--ink-faint); }
@media (max-width: 600px) { .issue { grid-template-columns: 1fr; gap: .2rem; } }

/* ---------- quality floor ---------- */
:focus-visible { outline: 2px solid var(--spot); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}