/* ════════════════════════════════════════════════════════════════════════
   THE HANOI DISPATCH — a one-person newspaper for the homepage.
   Light, print-authentic broadsheet. Self-contained (does not use the dark
   style.css). Loaded only by index.html.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Bone & Roast — the Sesame Almanac palette (source: LLTheme /
     sesame-brand.css), worn by the Dispatch's own furniture ── */
  --paper: #FBF6EC;       /* page paper */
  --paper-2: #EFE7D8;     /* bone — alt strips / hover */
  --paper-lift: #FFF9EF;  /* elevated cards / tiles */
  --ink: #241C14;         /* warm roast-brown ink */
  --ink-soft: #514840;    /* long-reading body */
  --ink-mute: #70675C;    /* captions / meta */
  --rule: #DED2BE;        /* paper-edge hairline */
  --rule-soft: rgba(146, 116, 66, 0.20);
  --band-wash: rgba(146, 116, 66, 0.07);  /* translucent warm stock for alt section sheets */
  --verm: #A24A28;        /* roast accent, AA-safe as text on paper */
  --verm-dk: #99411F;     /* accent-deep — hovers, small text */
  --verm-bright: #C2592E; /* decorative roast — fills, glyphs, rules */
  --accent-light: #F3DFD3;
  --accent-grad: linear-gradient(218deg, #7F351D 0%, #A64927 52%, #8A5A1B 100%);
  --accent-glow: rgba(194, 89, 46, 0.16);
  --blue: #667982;        /* slate signal (sparingly) */
  --blue-text: #4E5E66;   /* slate dark enough for small text on paper */

  /* mastery ladder (Seed → Sprouting → Ripening → Golden), AA text shades */
  --m-seed: #665B4D;
  --m-sprout: #46613E;
  --m-ripen: #99411F;
  --m-golden: #7E5A1E;
  --stage-seed: #A99E8D;
  --stage-sprout: #5C7C54;
  --stage-ripen: #C2592E;
  --stage-golden: #CF9A39;

  /* Soft Paper radius ladder + quiet, warm two-stage elevation */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --shadow-sm: 0 1px 2px rgba(20, 15, 10, 0.035), 0 8px 24px rgba(20, 15, 10, 0.045);
  --shadow-md: 0 2px 6px rgba(20, 15, 10, 0.045), 0 18px 44px rgba(20, 15, 10, 0.06);

  --disp: "Newsreader", Georgia, "Times New Roman", serif;
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --mono: "Spline Sans Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --sans: "Hanken Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --page: 1180px;
  --gutter: clamp(1rem, 4vw, 3rem);
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 4rem;
  --type-meta: 0.75rem;
  --type-support: 1rem;
  --type-body: 1.0625rem;
  --measure-copy: 68ch;
  --rule-strong: 3px solid var(--ink);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --motion-fast: 160ms;
  --motion-settle: 520ms;
  --section-space: clamp(3.5rem, 7vw, 6.5rem);
}

html { color-scheme: light; }
html[data-theme="night"] { color-scheme: dark; }

html[data-theme="night"] body.dispatch,
body.dispatch[data-theme="night"] {
  --paper: #1A120C;
  --paper-2: #241A11;
  --paper-lift: #21170F;
  --ink: #F7EDDE;
  --ink-soft: #D0C1AE;
  --ink-mute: #9A8B77;
  --rule: #463527;
  --rule-soft: rgba(229, 204, 161, 0.18);
  --verm: #E08A52;
  --verm-dk: #F0A06F;
  --verm-bright: #E08A52;
  --accent-light: #2F1A10;
  --accent-glow: rgba(224, 138, 82, 0.12);
  --blue: #9BAEB7;
  --blue-text: #9BAEB7;
  --m-seed: #B8AD9C;
  --m-sprout: #91AF84;
  --m-ripen: #E08A52;
  --m-golden: #E1B761;
  --stage-seed: #8A7B63;
  --stage-sprout: #91AF84;
  --stage-ripen: #E08A52;
  --stage-golden: #E1B761;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.16), 0 10px 28px rgba(0, 0, 0, 0.12);
  --shadow-md: 0 2px 7px rgba(0, 0, 0, 0.19), 0 20px 48px rgba(0, 0, 0, 0.15);
}

/* ════ ONE STOCK ════════════════════════════════════════════════════════
   Every page of the edition prints on the same sheet. Cards, strips and
   tiles resolve to the page paper and carry no shadow; hierarchy is a
   hairline, a type step, or air. The raw --paper/--paper-2/--paper-lift
   ladder above stays as the palette record — this is the sheet in use.
   (Lived in home-sesame.css until 2026-08-02, where it flattened only the
   homepage and left work/blog/articles on lifted cream cards.) */
body.dispatch {
  --stock: #F7F0E1;
  --paper: var(--stock);
  --paper-2: var(--stock);
  --paper-lift: var(--stock);
  --accent-light: var(--stock);
  --band-wash: transparent;
  --shadow-sm: 0 0 0 transparent;
  --shadow-md: 0 0 0 transparent;
  --lift-shadow: 0 0 0 transparent;
  --rule-soft: rgba(104, 89, 61, 0.20);
  /* interaction wash — hover/focus fills used to borrow --paper-2, which
     goes invisible the moment the stock is one colour. A roast tint is what
     those states actually mean, and it survives any paper change. Declared
     here, not on :root: a custom property resolves var() against the element
     it is declared on, and --verm only flips to its night value on
     body.dispatch — on :root the night wash would stay dark-on-dark. */
  --wash: color-mix(in srgb, var(--verm) 8%, transparent);
}

/* must repeat the night selector verbatim: the night token block above is
   (0,2,2) and would otherwise out-specify the flat `body.dispatch` sheet */
html[data-theme="night"] body.dispatch,
body.dispatch[data-theme="night"] {
  --stock: #17110B;
  --paper: var(--stock);
  --paper-2: var(--stock);
  --paper-lift: var(--stock);
  --accent-light: var(--stock);
  --band-wash: transparent;
  --shadow-sm: 0 0 0 transparent;
  --shadow-md: 0 0 0 transparent;
  --lift-shadow: 0 0 0 transparent;
  --wash: color-mix(in srgb, var(--verm) 8%, transparent);
}

/* night: the shell's ink-weight rules (running head, colophon) read as
   16:1 cream wires on the dark stock — step them to ink-soft so they are
   still rules, no longer glare */
html[data-theme="night"] body.dispatch :is(.d-runhead, .d-colophon),
body.dispatch[data-theme="night"] :is(.d-runhead, .d-colophon) {
  border-color: var(--ink-soft);
}

/* ════ THE SPOT PLATE ═══════════════════════════════════════════════════
   A broadsheet prints the body in one ink and runs a second plate for the
   section furniture. Every section of this edition declares which spot ink
   it is printed with, and all section furniture — flag rule, folio letter,
   desk tag, kicker, numerals, drop cap, panel wash — reads `--spot`. A
   section therefore changes colour by changing one attribute, and nothing
   else has to know.

     <section data-spot="sprout"> … </section>

   Omit the attribute and the section prints in the house roast, which is
   exactly what every page did before this system existed — so adding the
   system changed no page, and adopting it elsewhere is one attribute per
   section (see "adopting the plate" at the foot of this block).

   The four inks are the Almanac ladder already declared in the tokens
   above: no new colour is invented here and every one has a night value.
     roast   the house ink — identity, the front, the files, letters
     slate   navigation and indexes — the desk map, the latest columns
     sprout  the person — biography, the record, correspondence
     golden  craft — method, practice, side projects

   Three values, all of them used:
     --spot        the TEXT shade — ≥5.2:1 on the day stock, ≥7:1 on night,
                   safe for the small mono caps this site sets furniture in
     --spot-deep   the emphasis shade (only roast actually differs; the
                   ladder inks are dark enough to serve both roles)
     --spot-wash   an 8% ground for the ONE panel that leads a section
   Decorative-only shades already exist as the --stage-* ladder; nothing
   needs them yet, so the plate does not re-export them.

   The wash MUST be declared in a rule that also matches the section: a
   var() inside a custom property is substituted where the declaration
   sits, so a `--spot-wash` declared once on `body.dispatch` would freeze
   at roast for every section on the page. Same trap as `--wash` on :root.
   ════════════════════════════════════════════════════════════════════ */
body.dispatch,
body.dispatch [data-spot="roast"] {
  --spot: var(--verm);
  --spot-deep: var(--verm-dk);
}
body.dispatch [data-spot="slate"] {
  --spot: var(--blue-text);
  --spot-deep: var(--blue-text);
}
body.dispatch [data-spot="sprout"] {
  --spot: var(--m-sprout);
  --spot-deep: var(--m-sprout);
}
body.dispatch [data-spot="golden"] {
  --spot: var(--m-golden);
  --spot-deep: var(--m-golden);
}
/* one rule for the derived grounds — it re-declares them on each section,
   so the var(--spot) inside resolves against that section's own ink */
body.dispatch,
body.dispatch [data-spot] {
  --spot-wash: color-mix(in srgb, var(--spot) 8%, transparent);
  /* the interaction wash joins the plate too, so a hover inside a slate
     section is slate. On body itself --spot is --verm, so this resolves to
     the same value the one-stock block declared. */
  --wash: color-mix(in srgb, var(--spot) 8%, transparent);
}

/* ── what the plate takes over ─────────────────────────────────────────
   Furniture that was already an accent (kickers, notice labels, desk tags,
   drop caps, the proofing-pen underline, the letters rule) reads --spot
   unconditionally: off-plate that resolves to the house roast, which is
   the colour it was anyway, so those pages did not move.

   The five rules below are different — they were INK or grey before the
   plate existed, and colouring them is the change a section actually opts
   into. Scoping them to [data-spot] keeps every page that has not adopted
   the plate byte-identical, and makes adoption a single attribute:
   add data-spot to a section and its rule, folio letter, ledger spine,
   rail flag and figures all take the ink together. */
[data-spot] .d-flag::before { background: var(--spot); }
[data-spot] .d-flag::after  { color: var(--spot); }
[data-spot] .d-rail-flag    { border-bottom-color: var(--spot); }
[data-spot] .d-ledger       { border-top-color: var(--spot); }
[data-spot] .d-circ-n       { color: var(--spot); }

/* Adopting the plate on another page: put `data-spot` on the page's
   section elements the same way index.html does. Anything that should
   follow the ink uses var(--spot); anything that is site identity rather
   than section furniture (run-mark, focus ring, selection, skip link)
   stays on --verm on purpose, so the masthead reads the same on every
   page no matter which desk the reader is in. */

* { margin: 0; padding: 0; box-sizing: border-box; }

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

body.dispatch {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--type-body);
  line-height: 1.58;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-variant-ligatures: common-ligatures;
  font-optical-sizing: auto;
  overflow-x: hidden;
}

.dispatch [hidden] { display: none !important; }

.dispatch ::selection { background: var(--verm); color: var(--paper); }

/* Low-specificity base so class-level link colors (.d-jump, .d-btn-p,
   .article-source…) actually win the cascade. */
a { color: inherit; text-decoration: none; }

.skip-link {
  position: absolute; left: -999px; top: 0; z-index: 300;
  background: var(--ink); color: var(--paper); padding: 10px 16px;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase;
}
.skip-link:focus { left: 8px; top: 8px; }

/* shared shell ---------------------------------------------------------- */
.d-wrap { max-width: var(--page); margin: 0 auto; padding: 0 var(--gutter); }

.d-mono { font-family: var(--mono); text-transform: uppercase; letter-spacing: 0.14em; font-size: 11px; color: var(--ink-mute); }
.d-verm { color: var(--verm); }

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

/* ════ RUNNING HEAD (persistent top nav) ════════════════════════════════ */
.d-runhead {
  position: sticky; top: 0; z-index: 100;
  background: var(--paper);
  border-bottom: 1px solid var(--ink);
}
.d-runhead-in {
  max-width: var(--page); margin: 0 auto; padding: 0 var(--gutter);
  height: 46px; display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.d-run-mark {
  font-family: var(--disp); font-weight: 600; font-size: 17px; letter-spacing: -0.01em;
  white-space: nowrap; line-height: 1;
  min-block-size: 44px; display: inline-flex; align-items: center;
}
.d-run-mark .d-verm { color: var(--verm); }
.d-run-nav { display: flex; gap: clamp(0.9rem, 2.5vw, 1.9rem); }
.d-run-nav a {
  font-family: var(--sans); font-size: 13px; font-weight: 600; letter-spacing: 0.01em;
  color: var(--ink-soft); position: relative; padding: 8px 10px;
  min-inline-size: 44px; min-block-size: 44px; display: flex; align-items: center;
  border-radius: var(--r-sm);
  transition: background var(--motion-fast) ease, color var(--motion-fast) ease;
}
.d-run-nav a::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1.5px; width: 0;
  background: var(--verm); transition: width 0.2s var(--ease);
}
.d-run-nav a:hover,
.d-run-nav a:focus-visible { color: var(--ink); background: var(--wash); }
.d-run-nav a:hover::after, .d-run-nav a:focus-visible::after { width: 100%; }
.d-run-nav a[aria-current="page"] { color: var(--ink); }
.d-run-nav a[aria-current="page"]::after { width: 100%; }
.d-run-right { display: flex; align-items: center; gap: 14px; }
.d-run-clock { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; color: var(--ink-mute); white-space: nowrap; }

/* language toggle (used in runhead + folio) */
.d-lang { display: inline-flex; align-items: center; gap: 2px; }
.d-lang button {
  font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
  background: none; border: 0; color: var(--ink-mute); cursor: pointer;
  padding: 4px 5px; line-height: 1; min-block-size: 44px; min-inline-size: 44px;
  border-radius: var(--r-sm);
  transition: background var(--motion-fast) ease, color var(--motion-fast) ease;
}
.d-lang button:hover,
.d-lang button:focus-visible { background: var(--wash); color: var(--ink); }
.d-lang button[aria-pressed="true"] { color: var(--verm); text-decoration: underline; text-underline-offset: 3px; }
.d-lang .sep { color: var(--rule); }

/* theme toggle styling */
.d-theme-toggle {
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--ink-soft);
  padding: 6px;
  min-inline-size: 44px;
  min-block-size: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.16s var(--ease), color 0.16s var(--ease);
}
.d-theme-toggle:hover, .d-theme-toggle:focus-visible {
  color: var(--spot);
  background: var(--wash);
}
.d-theme-toggle svg {
  display: block;
}

/* mobile nav toggle */
.d-burger {
  display: none; background: none; border: 0; cursor: pointer; color: var(--ink);
  padding: 8px; min-inline-size: 44px; min-block-size: 44px;
  border-radius: var(--r-sm);
  transition: background var(--motion-fast) ease, color var(--motion-fast) ease;
}
.d-burger:hover,
.d-burger:focus-visible { background: var(--wash); color: var(--verm); }
.d-burger svg { display: block; }

/* ════ FRONT PAGE (hero) ════════════════════════════════════════════════ */
.d-front { padding: clamp(1.4rem, 3vw, 2.6rem) 0 clamp(2rem, 4vw, 3.4rem); }

/* front lead */
.d-gutter { background: var(--rule); }
.d-kicker {
  font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--spot);
  display: inline-block; inline-size: fit-content; justify-self: start;
  border-bottom: 2px solid var(--spot); padding-bottom: 3px; margin-bottom: 16px;
}
.d-standfirst {
  font-family: var(--serif); font-style: normal; font-weight: 400; font-size: clamp(18px, 2.1vw, 22px); line-height: 1.5; color: var(--ink-soft); max-width: var(--measure-copy);
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 13px 0; margin-bottom: 16px;
}
/* circulation figures + contact rail flag */
.d-rail-flag {
  font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink);
  inline-size: fit-content; justify-self: start;
  border-bottom: 2px solid var(--ink); padding-bottom: 5px; margin-bottom: 2px;
}
.d-circ { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 1px solid var(--rule); padding: 14px 0; gap: 12px; }
.d-circ-n { font-family: var(--disp); font-weight: 600; font-size: clamp(30px, 3.4vw, 40px); line-height: 1; font-variant-numeric: tabular-nums; }
.d-circ-l { font-family: var(--mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-soft); text-align: right; max-width: 130px; }

/* ════ SECTION RHYTHM — one continuous broadsheet ═══════════════════════════
   Every homepage chapter shares one paper stock. A consistent hairline and
   generous air mark each new front without introducing alternating bands. */
main { counter-reset: dsec; }
.d-section {
  position: relative;
  padding: clamp(3rem, 5.5vw, 5rem) 0;
  border-block-start: 1px solid var(--rule-soft);
  background: transparent;
  counter-increment: dsec;
}
/* a section folio (§ A, § B …) sits over the flag rule — the broadsheet's
   section letter, marking the top of each front */
.d-flag::after {
  content: "§ " counter(dsec, upper-alpha);
  position: absolute; right: 0; top: 0; transform: translateY(-150%);
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.2em; line-height: 1;
  color: var(--ink-mute); pointer-events: none;
}
/* a section carries one folio letter — secondary flags inside it stay bare */
.d-record-head::after { content: none; }

/* ════ SECTION FLAG (newspaper section header) ══════════════════════════ */
.d-flag {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; position: relative;
  padding-top: 12px; margin-bottom: clamp(18px, 2.4vw, 28px);
}
.d-flag::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--ink); transform-origin: left center;
}
.d-flag .tag {
  font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  padding: 0 0 4px; border-block-end: 2px solid currentColor;
  background: transparent; color: var(--spot-deep);
}
.d-flag .ttl { margin: 0; font-family: var(--disp); font-weight: 600; font-size: clamp(28px, 4.6vw, 38px); line-height: 1.08; letter-spacing: -0.01em; text-wrap: balance; }
.d-flag .more {
  min-inline-size: 44px;
  min-block-size: 44px;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.d-flag .more:hover { color: var(--spot); }

/* ════ THE EDITOR (about) — drop-capped columns ════════════════════════ */
.d-editor { columns: 2; column-gap: clamp(1.6rem, 4vw, 3rem); column-rule: 1px solid var(--rule); max-width: 56rem; }
.d-editor p { margin-bottom: 1.1rem; break-inside: avoid; color: var(--ink-soft); font-size: 17px; line-height: 1.62; }
.d-editor p:first-of-type::first-letter {
  font-family: var(--disp); font-weight: 600; font-size: 3.4em; line-height: 0.72;
  float: left; margin: 0.05em 0.09em 0 0; color: var(--spot);
}
.d-editor-sign { font-family: var(--mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-mute); margin-top: 0.4rem; }

/* ════ THE RECORD (experience) — LEDGER SPINE TIMELINE ══════════════════
   A career ledger filed down a vertical ink spine. Each entry is a record on
   the spine, pinned by a vermilion diamond node (the shared ◆ end-mark, here
   reused as a chronological pin). Era marker (mono) + folio № in a left rail;
   role as a Fraunces headline; outlet · beat as a mono dateline; italic dek.
   Pure CSS, flat/hard-edged, no rounding/glass/shadow. RM-safe. */
.d-ledger { list-style: none; border-top: 2px solid var(--ink); }
.d-rec {
  position: relative;
  display: grid;
  grid-template-columns: 168px 1fr;
  column-gap: clamp(20px, 3vw, 40px);
  align-items: start;
  padding: clamp(20px, 2.6vw, 30px) 0 clamp(20px, 2.6vw, 30px) 30px;
  border-bottom: 1px solid var(--rule);
}
/* the diamond node — the brand ◆ end-mark, repurposed as a chronological pin */
.d-rec-node {
  position: absolute; left: 50%; top: clamp(24px, 2.8vw, 34px);
  width: 9px; height: 9px; margin-left: -1px;
  transform: translate(-50%, -50%) rotate(45deg);
  background: var(--spot); border: 1.5px solid var(--paper);
  outline: 1px solid var(--spot);
}
/* left rail — folio number over era marker, tabular and aligned */
.d-rec-era { display: flex; flex-direction: column; gap: 5px; padding-top: 2px; }
.d-rec-no {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.14em; font-variant-numeric: tabular-nums;
  color: var(--ink-mute);
}
.d-rec-per {
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--spot-deep); line-height: 1.2;  /* --verm-dk clears WCAG AA on paper + hover */
}
/* the record body */
.d-rec-body { max-width: 52rem; }
/* The diamond pin is one unified vermilion brand motif for every record —
   no per-entry colour (keeps the ◆ a single device, not a traffic-light, and
   honours the rationing that keeps green/gold to the chips + the Sesame tile). */
.d-rec { transition: background 0.18s ease; }
.d-rec-node { transition: transform 0.22s var(--ease); }
.d-rec:hover,
.d-rec:focus-within { background: var(--wash); }
.d-rec:hover .d-rec-node,
.d-rec:focus-within .d-rec-node { transform: translate(-50%, -50%) rotate(45deg) scale(1.28); }
.d-jump {
  min-block-size: 44px;
  margin-top: 10px;
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--spot);
  border-bottom: 1px solid var(--spot);
}
/* shared CTA voice for archive cards (blog rows already scope their own) */
.venture-cta { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--spot); }

/* ════ SERVICE NOTICES (what I bring) — classified columns ══════════════ */
.d-notices { display: grid; grid-template-columns: repeat(3, 1fr); }
.d-notice { padding: 0 clamp(14px, 2vw, 26px); border-left: 1px solid var(--rule); }
.d-notice:first-child { padding-left: 0; border-left: none; }
.d-notice-label { font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--spot); display: block; margin-bottom: 10px; }
.d-notice h3 { font-family: var(--disp); font-weight: 600; font-size: clamp(20px, 2vw, 24px); line-height: 1.14; letter-spacing: -0.015em; margin-bottom: 10px; text-wrap: balance; }
.d-notice p { font-size: var(--type-support); line-height: 1.58; color: var(--ink-soft); }

/* meta line shared by the "Latest from the desk" columns */
.d-entry-meta { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); line-height: 1.5; }

/* ════ OFF THE WIRE (sidequests) ═══════════════════════════════════════ */
.d-wire { display: grid; gap: clamp(1rem, 2vw, 1.4rem); }

/* ════ LETTERS (contact) + colophon ════════════════════════════════════ */
.d-letters-grid { display: grid; gap: 0; }
.d-letters-main { padding-right: clamp(18px, 3vw, 36px); }
.d-avail-label { font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-mute); margin-bottom: 12px; }
.d-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
/* Sesame clipping-chips: paper chip, hairline edge, green "filed" leading bar */
.d-chips span {
  font-family: var(--serif); font-size: 15px; color: var(--ink);
  background: transparent; border: 1px solid var(--rule); border-radius: var(--r-sm);
  padding: 6px 12px; min-block-size: 32px; display: inline-flex; align-items: center;
}
.d-first { font-family: var(--serif); font-style: italic; font-size: 17px; color: var(--ink-soft); margin-bottom: 18px; }
.d-email {
  display: inline-flex; align-items: center; gap: 12px; font-family: var(--disp); font-weight: 600;
  font-size: clamp(22px, 3.6vw, 40px); letter-spacing: -0.01em; border-bottom: 3px solid var(--spot); padding-bottom: 6px;
  min-block-size: 44px;
}
.d-email:hover { color: var(--spot); }
.d-socials { padding-left: clamp(18px, 2.4vw, 26px); }
.d-socials .d-rail-flag { margin-bottom: 8px; }
.d-soc {
  min-block-size: 44px; display: flex; align-items: center; gap: 12px;
  margin-inline: calc(var(--space-2) * -1); padding: 10px var(--space-2);
  border-bottom: 1px solid var(--rule); border-radius: var(--r-sm);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
  transition: background var(--motion-fast) ease, color var(--motion-fast) ease;
}
.d-soc svg { width: 17px; height: 17px; flex: 0 0 auto; }
.d-soc:hover,
.d-soc:focus-visible { color: var(--spot); background: var(--wash); }

/* colophon footer */
.d-colophon { border-top: 3px solid var(--ink); margin-top: clamp(2rem, 4vw, 3rem); }
.d-colophon-in { max-width: var(--page); margin: 0 auto; padding: 20px var(--gutter); display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center; justify-content: space-between; font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute); }
.d-colophon-in .blue { color: var(--blue-text); }

/* reveal (subtle, reduced-motion safe) */
.d-reveal { opacity: 0; transform: translateY(12px); transition: opacity 0.5s var(--ease), transform 0.5s var(--ease); }
.d-reveal.d-in { opacity: 1; transform: none; }

/* ════ RESPONSIVE ══════════════════════════════════════════════════════ */
@media (max-width: 860px) {
  .d-letters-grid .d-gutter { display: none; }
  .d-letters-main { padding-right: 0; }
  .d-socials { padding-left: 0; margin-top: 26px; border-top: 1px solid var(--rule); padding-top: 20px; }
  .d-notices { grid-template-columns: 1fr; }
  .d-notice { border-left: none; padding-left: 0; padding-bottom: 22px; border-bottom: 1px solid var(--rule); margin-bottom: 4px; }
  .d-editor { columns: 1; }
  .d-rec { grid-template-columns: 132px 1fr; column-gap: clamp(16px, 2.6vw, 28px); }
}
/* the clock needs a full-width bar: beside a five-link nav it folded into
   three lines on a tablet */
@media (max-width: 960px) {
  .d-run-clock { display: none; }
}
@media (max-width: 640px) {
  body.dispatch { font-size: 16px; }
  /* section fronts stack on a phone: desk tag (and its "more" link) on the
     rule line, the title beneath on a line of its own — one rhythm for every
     front instead of the title landing beside short tags and under long ones */
  .d-flag { row-gap: 10px; }
  .d-flag .ttl { flex-basis: 100%; order: 1; font-size: clamp(28px, 7.6vw, 38px); }
  .d-flag .more { order: 0; }
  /* the colophon reads as a stacked imprint; the middot that joined the two
     halves of its first line goes with the line break */
  .d-colophon-in { flex-direction: column; align-items: flex-start; gap: 4px; }
  .d-colophon-sep { display: none; }
  .d-colophon-in > span:first-child > span[data-i18n-en] { display: block; }
  .d-colophon-in a { display: inline-block; padding-block: 6px; }
  /* article kicker: the source on its own line, date / read time beneath,
     so a separator never dangles at a line end */
  .article-kicker .article-source { flex-basis: 100%; padding-block: 6px; }
  .article-kicker .article-source + .article-sep { display: none; }
  .d-runhead-in { min-block-size: 46px; block-size: auto; flex-wrap: wrap; }
  .d-run-nav {
    order: 3;
    flex: 1 0 100%;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    border-block-start: 1px solid var(--rule);
  }
  .d-run-nav a { min-block-size: 48px; display: flex; align-items: center; }
  .d-burger { display: none; }
  .js .d-runhead-in { block-size: 46px; flex-wrap: nowrap; }
  .js .d-run-nav { display: none; }
  .js .d-burger { display: inline-flex; }
  /* One-stock sheet has no shadows and paper-lift equals the page, so the
     open menu needs a scrim to separate from the content behind it. Drawn
     as a header pseudo at z -1: below the bar and panel, above the page. */
  .d-runhead.open::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background: rgba(23, 17, 11, 0.45);
  }
  .d-runhead.open .d-run-nav {
    display: flex; position: absolute; top: 52px; left: 0; right: 0;
    flex-direction: column; gap: 0; margin-inline: var(--space-3);
    padding: var(--space-2);
    background: var(--paper); border: 1px solid var(--rule);
    border-radius: var(--r-lg); box-shadow: var(--shadow-md);
  }
  .d-runhead.open .d-run-nav a { padding: 12px; border-top: 1px solid var(--rule); }
  .d-runhead.open .d-run-nav a:first-child { border-top: 0; }
  /* ledger spine → single column; era rail stacks above the body, spine stays */
  .d-rec {
    grid-template-columns: 1fr;
    row-gap: 9px;
    padding: 18px 0 18px 26px;
  }
  .d-rec-node { left: 3px; top: 22px; }
  .d-rec-era { flex-direction: row; align-items: baseline; gap: 12px; padding-top: 0; }
}

/* ledger records file in down the spine, one after another, on reveal */
@media (prefers-reduced-motion: no-preference) {
  .d-ledger.d-reveal .d-rec { opacity: 0; transform: translateY(16px); }
  .d-ledger.d-reveal.d-in .d-rec {
    opacity: 1; transform: none;
    transition: opacity 0.55s var(--ease), transform 0.6s var(--ease);
  }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(1) { transition-delay: 0.04s; }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(2) { transition-delay: 0.14s; }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(3) { transition-delay: 0.24s; }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(4) { transition-delay: 0.34s; }
  /* the node drops onto the spine a beat after its record settles */
  .d-ledger.d-reveal .d-rec-node { transform: translate(-50%, -50%) rotate(45deg) scale(0); }
  .d-ledger.d-reveal.d-in .d-rec-node {
    transform: translate(-50%, -50%) rotate(45deg) scale(1);
    transition: transform 0.4s var(--ease);
  }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(1) .d-rec-node { transition-delay: 0.30s; }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(2) .d-rec-node { transition-delay: 0.40s; }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(3) .d-rec-node { transition-delay: 0.50s; }
  .d-ledger.d-reveal.d-in .d-rec:nth-child(4) .d-rec-node { transition-delay: 0.60s; }
}

@media (prefers-reduced-motion: reduce) {
  .d-reveal { opacity: 1; transform: none; transition: none; }
  .d-rec, .d-rec-node { transition: none; }
  * { scroll-behavior: auto !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   ARTICLE READER (.page-article) — light feature page
   ════════════════════════════════════════════════════════════════════════ */
.dispatch.page-article main, .article-page { max-width: 720px; margin: 0 auto; padding: clamp(1.6rem,4vw,3rem) var(--gutter) clamp(3rem,6vw,5rem); }

.article-progress {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 200;
  block-size: 3px;
  background: var(--spot);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.1s linear;
}
@media (prefers-reduced-motion: reduce) { .article-progress { transition: none; } }

.article-header { margin-bottom: clamp(1.8rem,3vw,2.6rem); }
.article-kicker { font-family: var(--mono); font-size: 11px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-mute); display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid var(--rule); }
.article-source { color: var(--spot); }
.article-source:hover { text-decoration: underline; text-underline-offset: 3px; }
.article-sep { color: var(--rule); }
.article-title { font-family: var(--disp); font-weight: 600; font-size: clamp(30px,5.2vw,56px); line-height: 1.08; letter-spacing: -0.015em; color: var(--ink); margin-bottom: 16px; text-wrap: balance; }
.article-subtitle { font-family: var(--serif); font-style: italic; font-size: clamp(18px,2.4vw,23px); line-height: 1.45; color: var(--ink-soft); margin-bottom: 20px; }
.article-meta-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; padding-top: 14px; border-top: 1px solid var(--rule); }
.article-author { font-family: var(--mono); font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); }
.article-author strong { color: var(--ink); font-weight: 600; }
.article-tags { display: flex; gap: 6px; flex-wrap: wrap; }
/* Category chips — Sesame mastery-chip grammar: tinted capsule, the stage
   color carries the TEXT (AA), its 13% tint carries the ground. */
.dispatch .blog-cat-tag, .article-tags span, .dispatch .featured-tag {
  font-family: var(--mono); font-size: 10px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--ink); background: color-mix(in srgb, currentColor 13%, transparent);
  padding: 4px 11px; border: 0; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 6px;
}
.dispatch .blog-cat-tag::before, .article-tags span::before, .dispatch .featured-tag::before {
  content: ""; inline-size: 7px; block-size: 7px; border-radius: 50%;
  background: currentColor; opacity: 0.75;
}
.dispatch .blog-cat-tag--culture { color: var(--m-ripen); }
.dispatch .blog-cat-tag--ai { color: var(--blue-text); }
.dispatch .blog-cat-tag--tech { color: var(--ink); }
.dispatch .blog-cat-tag--personal { color: var(--m-seed); }

.article-body { font-family: var(--serif); font-size: 19px; line-height: 1.72; color: var(--ink); }
.article-body p { margin: 0 0 1.25rem; }
.page-article .article-body :where(p, li) {
  min-inline-size: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.article-body > p:first-of-type::first-letter { font-family: var(--disp); font-weight: 600; font-size: 3.6em; line-height: 0.7; float: left; margin: 0.05em 0.1em 0 0; color: var(--spot); }
.article-body strong { font-weight: 700; color: var(--ink); }
.article-body em { font-style: italic; }
.article-body a { color: var(--spot); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; overflow-wrap: anywhere; }
.article-body a:hover { color: var(--spot-deep); }
.article-body h2, .article-body h3, .article-body h4 { font-family: var(--disp); font-weight: 600; line-height: 1.18; color: var(--ink); margin: 2rem 0 0.9rem; text-wrap: balance; }
.article-body h2[id], .article-body h3[id] { scroll-margin-block-start: 76px; }
.article-body h2 { font-size: clamp(22px,3vw,30px); }
.article-body h3 { font-size: clamp(19px,2.4vw,24px); }
.article-body h4 { font-size: clamp(18px,2.2vw,22px); }
.article-body ul, .article-body ol { margin: 0 0 1.25rem 1.3rem; }
.article-body li { margin-bottom: 0.5rem; }
.article-body li p { margin: 0; }
.article-body blockquote {
  margin: var(--space-6) 0;
  padding: var(--space-4);
  border: 1px solid var(--rule);
  border-inline-start: 4px solid var(--spot);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--spot) 6%, transparent);
  color: var(--ink-soft);
  font-style: italic;
  font-size: 1.1em;
  line-height: 1.55;
}
.article-body hr {
  inline-size: min(12rem, 45%);
  block-size: 1px;
  margin: 2.4rem auto;
  border: 0;
  background: var(--rule);
}
.article-body figure { margin: 1.8rem 0; }
.article-body figure > a {
  display: block;
  inline-size: fit-content;
  max-inline-size: 100%;
  margin-inline: auto;
  border-radius: var(--r-lg);
}
.article-body img {
  display: block; width: auto; max-width: 100%; height: auto; max-height: 640px;
  margin-inline: auto;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--paper-lift);
  box-shadow: var(--shadow-sm);
}
.article-body figcaption { font-family: var(--mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-mute); margin-top: 8px; border-left: 2px solid var(--spot); padding-left: 8px; }

/* Source / footnote list — keeps long unbroken URLs from overflowing the
   720px reading column on small screens. */
.article-footnotes { margin-top: clamp(2rem,4vw,3rem); padding-top: 1.4rem; border-top: 1px solid var(--rule); }
.article-footnotes ol { margin: 0 0 0 1.4rem; padding: 0; }
.article-footnotes li { font-family: var(--serif); font-size: 15px; line-height: 1.55; color: var(--ink-soft); margin-bottom: 0.65rem; }
.article-footnotes a { overflow-wrap: anywhere; word-break: break-word; }

.article-divider { display: flex; align-items: center; gap: 12px; margin: clamp(2rem,4vw,3rem) 0; }
.divider-line { flex: 1; height: 1px; background: var(--rule); }
.divider-dot { width: 6px; height: 6px; background: var(--spot); border-radius: 50%; }
.article-footer { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; padding-top: 18px; border-top: 2px solid var(--ink); }
.article-back {
  min-block-size: 44px;
  display: inline-flex;
  align-items: center;
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--spot);
}
.article-back:hover { text-decoration: underline; text-underline-offset: 3px; }
.article-share-label { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute); }

/* ════════════════════════════════════════════════════════════════════════
   ARCHIVE / INDEX (blog.html, work.html) — light newspaper listing
   ════════════════════════════════════════════════════════════════════════ */
.dispatch.page-archive main { max-width: var(--page); margin: 0 auto; padding: 0 var(--gutter) clamp(3rem,6vw,5rem); }

/* archive masthead header */
.work-page-header { padding: clamp(1.4rem,3vw,2.4rem) 0 clamp(1.4rem,2.4vw,2rem); border-bottom: 3px solid var(--ink); margin-bottom: clamp(1.4rem,2.4vw,2rem); }
.work-page-title { font-family: var(--disp); font-weight: 600; font-size: clamp(40px,9vw,96px); line-height: 0.96; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 12px; text-wrap: balance; }
.work-page-desc { font-family: var(--serif); font-size: clamp(17px,2vw,21px); line-height: 1.5; color: var(--ink-soft); max-width: 44rem; }
.work-language-note { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-mute); margin-top: 10px; }

/* featured story — the archive's largest, softly clipped paper frame */
.featured-story {
  border: 1px solid var(--rule); border-radius: var(--r-xl);
  padding: clamp(1.2rem,2.6vw,2rem); margin-bottom: clamp(1.6rem,3vw,2.4rem);
  display: grid; gap: 10px;
  background: var(--paper-lift); box-shadow: var(--shadow-md);
}
.featured-label { font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--spot); }
.featured-pub { font-family: var(--mono); font-size: 11px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-mute); }
.featured-title { font-family: var(--disp); font-weight: 600; font-size: clamp(24px,3.6vw,40px); line-height: 1.1; }
.featured-title a:hover,
.featured-title a:focus-visible { color: var(--spot); }
.featured-excerpt { font-family: var(--serif); font-size: 16px; line-height: 1.55; color: var(--ink-soft); max-width: 60ch; }
.featured-tag, .featured-story .blog-cat-tag { justify-self: start; }
/* The markup wraps the featured children in .featured-body; let them
   participate in the .featured-story grid so its gap + justify-self apply. */
.featured-body { display: contents; }
.featured-pub, .featured-title, .featured-excerpt { margin: 0; }

/* search + filters */
.work-search { margin-bottom: 14px; }
.work-search-input { width: 100%; font-family: var(--sans); font-size: 15px; color: var(--ink); background: var(--paper-lift); border: 1px solid var(--rule); border-radius: var(--r-md); padding: 12px 16px; box-shadow: var(--shadow-sm); }
.work-search-input::placeholder { color: var(--ink-mute); text-transform: uppercase; letter-spacing: 0.08em; font-size: 11px; font-family: var(--mono); }
.work-search-input:focus-visible { outline: 2px solid var(--verm); outline-offset: 1px; }
.work-filters, .blog-filters { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: clamp(1.4rem,2.4vw,2rem); padding-bottom: 14px; border-bottom: 1px solid var(--rule); }
.filter-scroll { display: flex; flex-wrap: wrap; gap: 8px; }
.filter-tag {
  font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-soft); background: var(--paper-lift); border: 1px solid var(--rule); border-radius: 999px;
  padding: 10px 16px; cursor: pointer; min-height: 44px;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.filter-tag:hover { border-color: var(--spot); color: var(--spot-deep); }
.filter-tag.active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.filter-count, .blog-filter-count { font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute); margin-left: auto; }

/* work list (ledger of articles) */
.work-year-group { margin-bottom: clamp(1.6rem,3vw,2.4rem); }
.work-year { font-family: var(--disp); font-weight: 600; font-size: clamp(24px,3vw,34px); color: var(--spot); padding-bottom: 6px; border-bottom: 2px solid var(--ink); margin-bottom: 4px; }
/* year dividers inside the archive read as ink filing tabs — red stays with
   the two section fronts so one accent level owns the page */
.work-year-group .work-year { color: var(--ink); }
.work-list { display: block; }
.work-item {
  display: grid; grid-template-columns: 104px minmax(0,1fr) auto;
  grid-template-areas: "badge name tag" "date name tag" "pub name tag";
  column-gap: clamp(0.8rem,2vw,1.6rem); row-gap: 2px; align-items: start;
  padding: 16px 12px 16px 18px;
  border-bottom: 1px solid var(--rule);
  border-radius: var(--r-sm);
  transition: background var(--motion-fast) ease;
}
.work-item:hover,
.work-item:focus-visible { background: var(--wash); }
.work-item.hidden,
.page-archive .blog-post.hidden { display: none; }
.work-date { grid-area: date; }
.work-pub { grid-area: pub; }
.work-date, .work-pub { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); }
.work-name { grid-area: name; font-family: var(--disp); font-weight: 600; font-size: clamp(16px,1.9vw,20px); line-height: 1.22; color: var(--ink); }
.work-item:hover .work-name { color: var(--spot); }
.work-tag { grid-area: tag; align-self: center; font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--spot); white-space: nowrap; }
.work-item::before { display: none; }
.work-item.has-badge::before { grid-area: badge; display: inline-block; content: attr(data-badge-label); font-family: var(--mono); font-size: 9px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--spot-deep); background: color-mix(in srgb, currentColor 13%, transparent); border-radius: 999px; padding: 3px 8px; justify-self: start; margin-bottom: 5px; }
.work-no-results, .blog-no-results { font-family: var(--serif); font-style: italic; color: var(--ink-mute); padding: 2rem 0; text-align: center; }

/* .featured-tag wears the shared category-chip grammar above (tint + dot);
   only its grid placement is local. It used to be the one chip on the site
   without a dot, which made the work archive read as a different system. */
.featured-tag { justify-self: start; }

/* blog grid (archive) */
.page-archive .blog-grid { display: grid; gap: 0; border-top: 2px solid var(--ink); margin-bottom: clamp(1.6rem,3vw,2.4rem); }
.page-archive .blog-post {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr) auto;
  grid-template-areas:
    "header title  footer"
    "header excerpt footer";
  grid-template-rows: auto 1fr;
  gap: 4px clamp(0.8rem, 2vw, 1.6rem);
  align-items: start;
  padding: 20px 12px 20px 18px;
  border-bottom: 1px solid var(--rule);
  border-radius: var(--r-sm);
  transition: background var(--motion-fast) ease;
}
.page-archive .blog-post-header { grid-area: header; }
.page-archive .blog-post-title { grid-area: title; }
.page-archive .blog-post-excerpt { grid-area: excerpt; }
.page-archive .blog-post-footer { grid-area: footer; }
.page-archive .blog-post:has(a:hover),
.page-archive .blog-post:focus-within { background: var(--wash); }
.page-archive .blog-post-header { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.page-archive .blog-post-date { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-mute); }
.page-archive .blog-post-title { font-family: var(--disp); font-weight: 600; font-size: clamp(18px,2.2vw,25px); line-height: 1.16; }
.page-archive .blog-post-title a:hover,
.page-archive .blog-post-title a:focus-visible { color: var(--spot); }
.page-archive .blog-post-excerpt { font-family: var(--serif); font-size: var(--type-body); line-height: 1.58; color: var(--ink-soft); margin-top: 6px; max-width: 56ch; }
.page-archive .blog-post-footer { display: flex; flex-direction: column; align-items: flex-end; gap: 8px; align-self: center; white-space: nowrap; }
.page-archive .blog-post-readtime { font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-mute); }
.page-archive .blog-post-footer .venture-cta { font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--spot); }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (max-width: 640px) {
  .page-archive .blog-post { grid-template-columns: 1fr; gap: 3px; }
  .page-archive .blog-post { grid-template-areas: none; grid-template-rows: none; }
  .page-archive .blog-post > * { grid-area: auto; }
  .work-tag { align-self: start; }
  .page-archive .blog-post-footer { flex-direction: row; align-items: center; gap: 12px; align-self: start; }
  .article-body { font-size: 17px; }
  .article-body > p:first-of-type::first-letter { font-size: 3em; }
}

/* ════════════════════════════════════════════════════════════════════════
   MOTION LAYER — "Press & Ink"  (all gated on prefers-reduced-motion)
   ════════════════════════════════════════════════════════════════════════ */

/* Page motion happens inside each document; cross-document view transitions
   are intentionally not enabled because they can expose black paint gaps. */

@media (prefers-reduced-motion: no-preference) {
  /* ─ scroll reveal (JS adds .d-reveal, then .d-in on enter) ─ */
  .d-reveal { opacity: 0; transform: translateY(18px); }
  .d-reveal.d-in {
    opacity: 1; transform: none;
    transition: opacity 0.6s var(--ease) calc(var(--ri, 0) * 60ms),
                transform 0.66s var(--ease) calc(var(--ri, 0) * 60ms);
  }
  /* section rule draws across when its flag reveals */
  .d-reveal.d-flag::before { transform: scaleX(0); }
  .d-reveal.d-flag.d-in::before { transform: scaleX(1); transition: transform 0.7s var(--ease) 0.06s; }

  .d-run-mark:hover .d-verm { animation: d-blink 0.7s steps(1) 1; }
}

@keyframes d-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.2; } }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* ════════════════════════════════════════════════════════════════════════
   "PRESSED PAPER" — background + vibe enhancement
   Turns the flat paper fill into a printed sheet: one fine fiber grain over
   the stock, plus a letterpress masthead. Pure CSS, inline data-URI noise
   only (no image files, no canvas, no per-frame JS). One pseudo-layer sits
   at z-index -1, below the chrome ladder (runhead 100 / progress 200 /
   skip-link 300). Safe under long-form reading.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  /* texture knobs (override-friendly) */
  --paper-grain: 0.07;     /* fiber tooth alpha — one monochrome pass */
  --grain-tile: 180px;     /* fine fiber tile size */

  /* fine fiber speckle — high baseFrequency = paper tooth; a contrast
     stretch (feComponentTransfer) punches the low-contrast turbulence up
     so a low multiply opacity still reads as real tooth, not nothing */
  --grain-svg:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2' intercept='-0.5'/%3E%3CfeFuncG type='linear' slope='2' intercept='-0.5'/%3E%3CfeFuncB type='linear' slope='2' intercept='-0.5'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* keep background:var(--paper) (line 35) as the floor; just host the layers */
body.dispatch { position: relative; z-index: 0; }

/* ── ONE PASS · monochrome fiber grain ──────────────────────────────────
   Greyscale noise on a single multiply pass only ever DARKENS into the
   warm sheet, so paper stays warm and never greys. Static, so reduced-
   motion users keep all of it. The old second layer — a warm-lamp
   gradient wash at z-index -2 — was on every page but the homepage, which
   made the same paper read as two different sheets across the edition. */
body.dispatch::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--grain-svg);
  background-size: var(--grain-tile) var(--grain-tile);
  background-repeat: repeat;
  opacity: var(--paper-grain);
  mix-blend-mode: multiply;
}

/* Night takes the same tooth as a lighter screen pass. */
html[data-theme="night"] body.dispatch::before,
body.dispatch[data-theme="night"]::before {
  opacity: 0.035;
  mix-blend-mode: screen;
}


/* The grain is static — the "ink settle" load fade and the mobile grain
   trim both went with the second texture layer; at 0.07 one pass there is
   nothing left to settle or trim. */

/* ── forced colors · let the OS contrast model win ──────────────────────── */
@media (forced-colors: active) {
  body.dispatch {
    --shadow-sm: none;
    --shadow-md: none;
  }
  body.dispatch::before { display: none; }
}

/* ── print · strip texture so it exports clean ──────────────────────────── */
@media print {
  body.dispatch {
    --shadow-sm: none;
    --shadow-md: none;
  }
  body.dispatch::before { display: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   SAME PRESS — Sesame ⇄ Dispatch cross-pollination
   The portfolio and the Sesame Almanac landing read as sibling editions off
   one press: shared print furniture (thick-over-thin rule, diamond end-mark)
   in ink/vermilion, plus a rationed green/gold palette borrowed from Sesame,
   confined to two semantic roles + the single tile that links to /sesame/.
   Pure CSS, flat (no rounding/glass/shadow/gradient on chrome). RM-safe.
   ════════════════════════════════════════════════════════════════════════ */

:root {
  --filed: #5C7C54;     /* Sesame sprout green — "clipped / filed" bar only  */
  --pick:  #CF9A39;     /* Sesame saffron — the single "pick" marker only    */
}

/* 2 · DIAMOND END-OF-STORY MARK — Sesame closes every story with a ◆ ──────
   The .article-divider that ends every article carries the mark: square its
   dot into the shared rotated-diamond device. (The footer used to repeat the
   diamond on its own rule two lines below — one end mark is enough.) */
.article-divider .divider-dot {
  width: 7px; height: 7px; border-radius: 0;
  background: var(--spot); transform: rotate(45deg);
}

/* 3 · CLIPPING LEADING-BAR on the contact chips (green = "filed") ─────────
   Sesame's clipping-chip green leading edge — and only that. The homepage
   layer controls the chip plate geometry. */
.d-chips span { position: relative; overflow: hidden; padding-left: 14px; }
.d-chips span::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--filed);
}

/* 5 · SESAME-TILE CAMEO — all remaining green/gold quarantined here ───────
   The one place the reader crosses into Sesame: a green "filed" leading bar
   (always on) and a gold rule on hover. Scoped to the wire card that links
   to /sesame/, so no other tile sees Sesame's palette. The hover rule is an
   inset box-shadow (no layout shift) rather than a border. */
.d-wire-card.d-wire-card--sesame {
  border-inline-start: 3px solid var(--filed);
  transition: box-shadow 0.15s ease, color 180ms var(--ease), background 180ms var(--ease);
}
.d-wire-card.d-wire-card--sesame:hover,
.d-wire-card.d-wire-card--sesame:focus-visible { box-shadow: inset 0 2px 0 var(--pick); }
@media (max-width: 640px) {
  .d-wire-card.d-wire-card--sesame { border-inline-start: 3px solid var(--filed); }
}
/* the seed's gradient stops are presentation attributes with day colours
   only; CSS wins over them, and the ladder tokens already carry night */
#dSeed stop:first-child { stop-color: var(--stage-golden); }
#dSeed stop:last-child { stop-color: var(--stage-ripen); }
@media (prefers-reduced-motion: reduce) {
  .d-wire-card.d-wire-card--sesame { transition: none; }
}

/* forced-colors: let the OS own status/accent decoration */
@media (forced-colors: active) {
  .d-chips span::before,
  .d-wire-card.d-wire-card--sesame { forced-color-adjust: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   LIVING PRESS — the de-stale layer
   The sheet is printed; the press should feel like it is still running.
   Four additions, each scoped to the newspaper metaphor (not generic fades):
     1 · headlines are SET, one word at a time, wiping up from the baseline
     2 · ambient press life — a roller glint crosses the masthead rule; the
         register mark breathes — so the page is never dead-still
     3 · ink-sweep hovers — the proof-reader's red pen on links & ledger rows
     4 · the live dateline clatters in over the wire (see dispatch.js)
   All transform/opacity/clip only. Everything below is fully disabled under
   prefers-reduced-motion at the foot of this block.
   ════════════════════════════════════════════════════════════════════════ */

/* ── 1 · hand-set headlines (JS splits words into .d-w > .d-w-i) ────────────
   Each word is clipped to its line box; the inner sits below the baseline and
   slides up when the headline is "set". Descenders get room via the
   padding/negative-margin trick so g/y/p never clip. */
@media (prefers-reduced-motion: no-preference) {
  .d-w {
    display: inline-block; overflow: hidden; vertical-align: top;
    padding-bottom: 0.16em; margin-bottom: -0.16em;
  }
  .d-w-i {
    display: inline-block;
    transform: translateY(118%);
    transition: transform 0.7s var(--ease);
    transition-delay: calc(var(--wi, 0) * 46ms);
  }
  /* landing headline: JS adds .is-set once the meta line and name have landed */
  .d-landing-headline.is-set .d-w-i { transform: none; }
  /* section titles: ride the flag reveal, or the homepage section reveal */
  .d-flag.d-in .ttl .d-w-i,
  .d-home-in .d-flag .ttl .d-w-i,
  .d-flag .ttl.is-set .d-w-i { transform: none; }
}

/* ── 3 · ink-sweep hovers (the red proofing pen) ───────────────────────────*/
/* Ledger rows receive one short inset proof mark; recommendation cards do not. */
.work-item, .page-archive .blog-post { position: relative; }
.work-item::after,
.page-archive .blog-post:nth-of-type(n + 3)::after {
  content: ""; position: absolute;
  inset-inline-start: 6px; inset-block: 25%; inline-size: 3px;
  background: var(--spot); transform: scaleY(0); transform-origin: top center;
  border-radius: 999px;
  transition: transform 0.22s var(--ease); pointer-events: none;
}
.work-item:hover::after,
.page-archive .blog-post:nth-of-type(n + 3):has(a:hover)::after,
.work-item:focus-within::after,
.page-archive .blog-post:nth-of-type(n + 3):focus-within::after { transform: scaleY(1); }

/* text links underline as if drawn in red pen, left to right */
.d-jump, .d-flag .more, .article-back {
  background-image: linear-gradient(var(--spot), var(--spot));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1.5px;
  transition: background-size 0.34s var(--ease);
}
.d-jump:hover, .d-flag .more:hover, .article-back:hover { background-size: 100% 1.5px; }

/* ── reduced-motion / forced-colors / print — strip the living layer ───────*/
@media (prefers-reduced-motion: reduce) {
  .d-w-i { transform: none; transition: none; }
  .work-item::after,
  .d-jump, .d-flag .more, .article-back { transition: none; }
}
@media (forced-colors: active) {
  .work-item::after,
  .page-archive .blog-post:nth-of-type(n + 3)::after { background: CanvasText; }
  .featured-story,
  .selected-work-card,
  .page-archive .blog-post:nth-of-type(-n + 2),
  .article-toc,
  .article-related,
  .archive-toggle {
    border-color: CanvasText !important;
    box-shadow: none !important;
  }
}
@media print {
  .d-w-i { transform: none; }
  .dispatch *,
  .dispatch *::before,
  .dispatch *::after {
    animation: none !important;
    transition: none !important;
  }
  .d-reveal {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .dispatch * { box-shadow: none !important; }
}


/* Typographical Back-to-Top link */
.d-back-top {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  cursor: pointer;
  background: none;
  border: 0;
  padding: 4px 0;
  min-block-size: 44px;
  transition: color 0.16s var(--ease);
}
.d-back-top:hover {
  color: var(--spot);
}

/* ════════════════════════════════════════════════════════════════════════
   LIVE DIGITAL EDITION — shared art direction and navigation utilities
   ════════════════════════════════════════════════════════════════════════ */

/* Archive covers: typography stays primary, but each lead story gets a
   publication-specific story plate instead of another empty text rectangle. */
.page-archive .work-page-header {
  position: relative;
  padding-block-start: clamp(var(--space-5), 4vw, var(--space-6));
  padding-inline-end: clamp(0rem, 9vw, 7.5rem);
}

.page-archive .work-page-header::after {
  content: "ARCHIVE / HÀ NỘI";
  position: absolute;
  inset-block-start: clamp(2rem, 5vw, 4.5rem);
  inset-inline-end: 0;
  color: var(--spot);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  writing-mode: vertical-rl;
}

:lang(vi) .page-archive .work-page-header::after { content: "KHO BÀI / HÀ NỘI"; }

.page-archive .featured-story {
  position: relative;
  min-block-size: clamp(260px, 30vw, 340px);
  padding-inline-end: clamp(18rem, 35%, 28rem);
  overflow: hidden;
  isolation: isolate;
  transition:
    transform 200ms var(--ease),
    border-color 180ms ease,
    box-shadow 200ms ease;
}

.page-archive .featured-story > *,
.page-archive .featured-body > * {
  position: relative;
  z-index: 1;
}

.page-archive .featured-story::before,
.page-archive .featured-story::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  inline-size: min(33%, 25rem);
  pointer-events: none;
}

.page-archive .featured-story::before {
  z-index: 0;
  border-inline-start: 1px solid var(--ink);
  background-color: var(--ink);
  background-image:
    radial-gradient(circle at 50% 50%, transparent 0 13%, var(--spot) 13.5% 14.5%, transparent 15% 25%, rgba(245, 239, 226, 0.72) 25.5% 26.2%, transparent 27%),
    radial-gradient(circle at 25% 30%, var(--spot) 0 4px, transparent 5px),
    radial-gradient(circle at 73% 68%, var(--paper) 0 4px, transparent 5px),
    repeating-linear-gradient(25deg, transparent 0 18px, rgba(245, 239, 226, 0.12) 18px 19px);
}

.page-archive .featured-story::after {
  z-index: 0;
  background: linear-gradient(115deg, transparent 0 45%, rgba(245, 239, 226, 0.12) 46% 47%, transparent 48%);
  transform: scale(1.08);
  transition: transform 600ms var(--ease);
}

@media (hover: hover) and (pointer: fine) {
  .page-archive .featured-story:has(a:hover) {
    transform: translateY(-2px);
    border-color: var(--spot);
    box-shadow: var(--shadow-md);
  }
  .page-archive .featured-story:has(a:hover)::after { transform: scale(1.18) rotate(2deg); }
}
.page-archive .featured-story:focus-within {
  border-color: var(--spot);
  box-shadow: var(--shadow-md);
  outline: 2px solid var(--verm);
  outline-offset: 3px;
}
.page-archive .featured-story:focus-within::after { transform: scale(1.18) rotate(2deg); }

/* The blog lead uses a softer editorial collage, not the work archive signal map. */
.page-archive .featured-story:has(a[href="marketing-tre-em.html"])::before {
  background-color: #D7A548;
  background-image:
    radial-gradient(circle at 26% 28%, var(--paper) 0 8%, transparent 8.5%),
    radial-gradient(circle at 72% 64%, var(--spot) 0 14%, transparent 14.5%),
    linear-gradient(132deg, transparent 0 44%, var(--ink) 44.5% 48%, transparent 48.5%),
    repeating-linear-gradient(-18deg, transparent 0 17px, rgba(22, 20, 15, 0.13) 17px 18px);
}

/* Ledger rows behave like proof sheets: metadata shifts before headline color. */
.work-item .work-date,
.work-item .work-pub,
.page-archive .blog-post:nth-of-type(n + 3) .blog-post-header {
  transition: transform 220ms var(--ease), color 160ms ease;
}
.work-item:hover .work-date,
.work-item:hover .work-pub,
.work-item:focus-visible .work-date,
.work-item:focus-visible .work-pub,
.page-archive .blog-post:nth-of-type(n + 3):has(a:hover) .blog-post-header,
.page-archive .blog-post:nth-of-type(n + 3):focus-within .blog-post-header {
  color: var(--spot);
  transform: translateX(4px);
}

/* Generated issue index for long articles. */
.article-toc {
  margin-block: 0 clamp(2rem, 4vw, 3rem);
  padding: var(--space-4);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: transparent;
  box-shadow: var(--shadow-sm);
}
.article-toc:focus-within {
  outline: 2px solid var(--verm);
  outline-offset: 3px;
}
.article-toc-title {
  margin-block-end: 10px;
  color: var(--spot);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
}
.article-toc-item--sub { padding-inline-start: 1rem; }
.article-toc ol {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 24px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: issue-index;
}
.article-toc li { counter-increment: issue-index; }
.article-toc a {
  display: grid;
  grid-template-columns: 2.2rem 1fr;
  gap: 8px;
  align-items: baseline;
  min-block-size: 44px;
  padding: 6px var(--space-2);
  border-radius: var(--r-sm);
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 15px;
  line-height: 1.3;
}
.article-toc a::before {
  content: counter(issue-index, decimal-leading-zero);
  color: var(--ink-mute);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
}
.article-toc a:hover,
.article-toc a:focus-visible { color: var(--spot); background: var(--wash); }

.page-article .article-header {
  position: relative;
  padding-block-start: clamp(1rem, 3vw, 2rem);
}
.page-article .article-header::before {
  content: "FIELD NOTES / HÀ NỘI";
  position: absolute;
  inset-block-start: 0;
  inset-inline-end: 0;
  color: var(--spot);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
:lang(vi) .page-article .article-header::before { content: "GHI CHÉP / HÀ NỘI"; }

@media (max-width: 700px) {
  .page-archive .work-page-header { padding-inline-end: 0; }
  .page-archive .work-page-header::after { display: none; }
  .page-archive .featured-story {
    min-block-size: 0;
    padding-block-end: 12rem;
    padding-inline-end: clamp(1.2rem, 2.6vw, 2rem);
  }
  .page-archive .featured-story::before,
  .page-archive .featured-story::after {
    inset-block-start: auto;
    inset-block-end: 0;
    inset-inline: 0;
    inline-size: 100%;
    block-size: 10rem;
    border-inline-start: 0;
    border-block-start: 1px solid var(--ink);
  }
  .article-toc ol { grid-template-columns: 1fr; }
  .page-article .article-header::before { position: static; display: block; margin-block-end: 12px; }
}

@media (max-width: 380px) {
  .d-runhead-in { padding-inline: 8px; gap: 4px; }
  .d-run-mark { font-size: 15px; }
  .d-run-right,
  .d-lang { gap: 0; }
  .d-lang .sep { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .page-archive .featured-story,
  .page-archive .featured-story::after,
  .work-item .work-date,
  .work-item .work-pub,
  .page-archive .blog-post-header { transition: none; }
}

/* ═══ 2026 INCLUSIVE REFINEMENT — shared archives, articles, and shell ═══ */
.work-page-desc,
.featured-excerpt,
.blog-post-excerpt,
.article-body,
.article-language-note {
  font-size: var(--type-body);
  line-height: 1.58;
}

.work-page-desc,
.featured-excerpt,
.article-language-note {
  max-inline-size: var(--measure-copy);
}

.filter-tag,
.venture-cta,
.d-back-top {
  min-inline-size: 44px;
  min-block-size: 44px;
  display: inline-flex;
  align-items: center;
}

.page-archive .featured-cta {
  justify-self: start;
  align-self: end;
  margin-block-start: var(--space-2);
  border-block-end: 1px solid currentColor;
  transition: color var(--motion-fast) ease;
}

.page-archive .featured-cta:hover,
.page-archive .featured-cta:focus-visible { color: var(--spot-deep); }

.work-search-input { min-block-size: 44px; }

.page-archive .featured-title a,
.page-archive .blog-post-title a {
  min-block-size: 44px;
  max-inline-size: 100%;
  display: inline-flex;
  align-items: center;
}

.selected-work-showcase {
  margin-block: clamp(2.5rem, 5vw, 4.5rem);
}

.archive-section-heading {
  margin-block-end: var(--space-4);
}

.selected-work-lead {
  margin-block-end: var(--space-3);
}

.selected-work-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
}

.selected-work-card {
  min-inline-size: 0;
  padding: var(--space-4);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-3);
  background: var(--paper-lift);
  box-shadow: var(--shadow-sm);
  transition:
    transform 200ms var(--ease),
    background var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    box-shadow 200ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .selected-work-card:has(a:hover) {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--spot) 48%, var(--rule));
    background: var(--wash);
    box-shadow: var(--shadow-md);
  }
}
.selected-work-card:focus-within {
  background: var(--wash);
  border-color: var(--spot);
  box-shadow: var(--shadow-md);
}
.selected-work-card-meta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.selected-work-card .blog-post-title { margin-block-end: var(--space-2); }
.selected-work-card .blog-post-excerpt { color: var(--ink-soft); }

.work-archive {
  margin-block-start: clamp(3rem, 6vw, 5rem);
}

.archive-heading {
  margin-block-end: var(--space-4);
}

.article-language-note {
  color: var(--ink-mute);
  font-style: italic;
  margin-block-start: var(--space-3);
}

.page-article .article-footer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
}

.article-related {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(240px, 1fr) repeat(4, auto);
  margin-block-start: var(--space-3);
  border: 1px solid var(--rule);
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--paper-lift);
  box-shadow: var(--shadow-sm);
}
.article-related:focus-within {
  outline: 2px solid var(--verm);
  outline-offset: 3px;
}

.article-related-feature {
  padding: var(--space-4);
  background: var(--wash);
  font-family: var(--disp);
  font-weight: 600;
  font-size: 18px;
  line-height: 1.2;
}

.d-colophon-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.article-related > a:not(.article-related-feature) {
  min-block-size: 100%;
  padding: var(--space-3);
  border-inline-start: 1px solid var(--rule);
  display: inline-flex;
  align-items: center;
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 600;
}

.article-related > a:hover,
.article-related > a:focus-visible { background: var(--wash); color: var(--spot-deep); }
.d-colophon-links a {
  min-inline-size: 44px;
  min-block-size: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.d-letters-grid {
  grid-template-columns: minmax(0, 1fr) 1px minmax(220px, 300px);
}

.d-letters-main,
.d-socials { min-inline-size: 0; }

.d-email {
  max-inline-size: 100%;
  min-inline-size: 0;
}

.d-email span {
  min-inline-size: 0;
  overflow-wrap: anywhere;
}

.d-availability-note {
  margin-block-start: var(--space-3);
  color: var(--ink-mute);
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0.04em;
}

@media (max-width: 860px) {
  .d-letters-grid { grid-template-columns: minmax(0, 1fr); }
  .d-letters-grid .d-gutter { display: none; }
  .d-letters-main { padding-inline-end: 0; }
  .d-socials {
    padding-inline-start: 0;
    padding-block-start: var(--space-4);
    margin-block-start: var(--space-5);
    border-block-start: 1px solid var(--rule);
  }
  .selected-work-grid { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .d-runhead.open .d-run-nav a { min-block-size: 48px; display: flex; align-items: center; }
  .d-email { font-size: clamp(17px, 6.4vw, 25px); gap: var(--space-2); }
  .d-email svg { inline-size: 22px; block-size: 22px; flex: 0 0 auto; }
  .page-article .article-footer { display: grid; grid-template-columns: 1fr; }
  .article-related { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .article-related-feature { grid-column: 1 / -1; }
  .article-related > a:not(.article-related-feature) {
    min-block-size: 56px;
    border-block-start: 1px solid var(--rule);
  }
  .article-related > a:nth-child(2),
  .article-related > a:nth-child(4) { border-inline-start: 0; }
}

@media (max-width: 360px) {
  .d-email { font-size: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  .dispatch *,
  .dispatch *::before,
  .dispatch *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ═══ LIVING EDITORIAL ISSUE — final shared composition layer ═════════ */

/* Work archive: JavaScript adds this class only after the complete,
   no-script-readable archive exists in the DOM. */
.work-item.is-curated-hidden { display: none; }

.archive-toggle {
  inline-size: 100%;
  min-block-size: 52px;
  margin-block: var(--space-3) var(--space-6);
  padding-inline: var(--space-3);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  background: var(--paper-lift);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background var(--motion-fast) ease,
    color var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    box-shadow 200ms ease;
}

.archive-toggle:hover,
.archive-toggle:focus-visible {
  background: var(--wash);
  border-color: var(--spot);
  color: var(--spot-deep);
  box-shadow: var(--shadow-md);
}

.archive-toggle-count {
  min-inline-size: 2.25rem;
  color: var(--spot);
  font-size: 13px;
  text-align: end;
}

.archive-toggle:hover .archive-toggle-count,
.archive-toggle:focus-visible .archive-toggle-count { color: currentColor; }

/* A real cover replaces the older CSS collage on the Writing lead. */
.featured-story:has(.featured-issue-art) {
  min-block-size: 340px;
  padding-inline-end: calc(34% + var(--space-5));
}

.featured-story:has(.featured-issue-art)::before,
.featured-story:has(.featured-issue-art)::after { display: none; }

.page-archive .featured-story > .featured-issue-art {
  position: absolute;
  z-index: 1;
  inset-block: 0;
  inset-inline-end: 0;
  inline-size: 34%;
  block-size: 100%;
  border-inline-start: 1px solid var(--ink);
  object-fit: cover;
}

.featured-story:has(.featured-issue-art) > :not(.featured-issue-art) {
  position: relative;
  z-index: 2;
}

/* Writing begins as a two-story recommendations spread, then returns to
   a restrained chronological ledger. */
.page-archive .blog-post:nth-of-type(-n + 2) {
  grid-template-columns: 1fr;
  grid-template-areas:
    "header"
    "title"
    "excerpt"
    "footer";
  grid-template-rows: auto auto 1fr auto;
  min-block-size: 260px;
  margin-block-end: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--paper-lift);
  box-shadow: var(--shadow-sm);
  transition:
    transform 200ms var(--ease),
    background var(--motion-fast) ease,
    border-color var(--motion-fast) ease,
    box-shadow 200ms ease;
}

.page-archive .blog-post:nth-of-type(-n + 2)::after { display: none; }

@media (hover: hover) and (pointer: fine) {
  .page-archive .blog-post:nth-of-type(-n + 2):has(a:hover) {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--spot) 48%, var(--rule));
    background: var(--wash);
    box-shadow: var(--shadow-md);
  }
}

.page-archive .blog-post:nth-of-type(-n + 2):focus-within {
  background: var(--wash);
  border-color: var(--spot);
  box-shadow: var(--shadow-md);
}

@media (min-width: 801px) {
  .page-archive .blog-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-3);
  }

  .page-archive .blog-post { grid-column: 1 / -1; }

  .page-archive .blog-post:nth-of-type(-n + 2) {
    grid-column: span 1;
    grid-template-columns: 1fr;
    grid-template-areas:
      "header"
      "title"
      "excerpt"
      "footer";
    grid-template-rows: auto auto 1fr auto;
    min-block-size: 300px;
  }

  .page-archive .blog-post:nth-of-type(-n + 2) .blog-post-title {
    font-size: clamp(25px, 3vw, 38px);
    line-height: 1.04;
    letter-spacing: -0.02em;
  }

  .page-archive .blog-post:nth-of-type(-n + 2) .blog-post-excerpt {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
  }

  .page-archive .blog-post:nth-of-type(-n + 2) .blog-post-footer {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    align-self: end;
  }
}

/* Generated article navigation is a proper disclosure on narrow screens. */
.article-toc-title {
  inline-size: 100%;
  min-block-size: 44px;
  padding: 0;
  border: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  background: transparent;
  text-align: start;
  cursor: pointer;
}

.article-toc-mark {
  display: none;
  color: var(--ink);
  font-size: 14px;
  transition: transform var(--motion-fast) var(--ease);
}

.article-toc-title[aria-expanded="true"] .article-toc-mark {
  transform: rotate(180deg);
}

.article-field-device {
  position: absolute;
  inset-block-start: 4.5rem;
  inset-inline-end: -11rem;
  inline-size: 8.5rem;
  block-size: auto;
  opacity: 0.72;
  pointer-events: none;
}

.page-article .article-body {
  max-inline-size: 68ch;
  margin-inline: auto;
}

.page-article .article-body h2 {
  margin-block-start: clamp(2.5rem, 6vw, 4rem);
}

@media (max-width: 1080px) {
  .article-field-device { display: none; }
}

@media (max-width: 800px) {
  /* the cover keeps its own proportion under the text instead of being
     cropped to a letterbox; the story reserves that height beneath its copy */
  .page-archive .featured-story:has(.featured-issue-art) {
    padding-inline-end: var(--space-4);
    padding-block-end: calc(75% + var(--space-4));
  }

  .page-archive .featured-story > .featured-issue-art {
    inset-block-start: auto;
    inset-block-end: 0;
    inset-inline-start: 0;
    inset-inline-end: 0;
    inline-size: 100%;
    block-size: auto;
    aspect-ratio: 720 / 540;
    border-inline-start: 0;
    border-block-start: 1px solid var(--ink);
  }
}

@media (max-width: 700px) {
  .article-toc { padding: var(--space-3); }
  .article-toc-title { margin-block-end: 0; }
  .article-toc-mark { display: inline-block; }
  .article-toc-title[aria-expanded="false"] + .article-toc-list { display: none; }
  .article-toc-title[aria-expanded="true"] + .article-toc-list {
    padding-block: var(--space-2);
  }

  .page-article .article-body {
    font-size: 1.1875rem;
    line-height: 1.64;
  }

  .page-article .article-body > p { margin-block-end: 1.1rem; }
  .page-article .article-body h2 { margin-block: 2.6rem 0.8rem; }
}

@media (max-width: 640px) {
  .work-item {
    grid-template-columns: 70px minmax(0, 1fr) auto;
    grid-template-areas:
      "date name tag"
      "pub name tag";
    gap: 2px var(--space-2);
    padding: 14px 12px 14px 18px;
  }

  .work-item.has-badge {
    grid-template-areas:
      "badge badge badge"
      "date name tag"
      "pub name tag";
  }

  .work-item > *,
  .work-item.has-badge::before { grid-area: auto; }
  .work-item .work-date { grid-area: date; }
  .work-item .work-pub { grid-area: pub; }
  .work-item .work-name { grid-area: name; }
  .work-item .work-tag { grid-area: tag; }
  .work-item.has-badge::before { grid-area: badge; }

  .work-name { font-size: 17px; line-height: 1.2; }
  .work-date,
  .work-pub { font-size: 10px; }

  .page-archive .blog-post:nth-of-type(n + 3) {
    grid-template-columns: 86px minmax(0, 1fr);
    grid-template-areas:
      "header title"
      "header excerpt"
      "header footer";
    gap: 6px var(--space-3);
    padding: 18px 12px 18px 18px;
  }

  .page-archive .blog-post:nth-of-type(n + 3) > * { grid-area: auto; }
  .page-archive .blog-post:nth-of-type(n + 3) .blog-post-header { grid-area: header; }
  .page-archive .blog-post:nth-of-type(n + 3) .blog-post-title { grid-area: title; }
  .page-archive .blog-post:nth-of-type(n + 3) .blog-post-excerpt { grid-area: excerpt; }
  .page-archive .blog-post:nth-of-type(n + 3) .blog-post-footer { grid-area: footer; }
  .page-archive .blog-post:nth-of-type(n + 3) .blog-post-excerpt {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    font-size: 16px;
    line-height: 1.45;
  }
  .page-archive .blog-post:nth-of-type(n + 3) .blog-post-footer { margin-block-start: var(--space-2); }
}

/* Archive features use the same ruled, square plates as the front page. */
.page-archive .selected-work-lead {
  border-radius: 0;
  border: 0;
  border-block-start: 3px solid var(--spot);
}
.page-archive .selected-work-card {
  border-radius: 0;
  border: 0;
  border-block-start: 1px solid var(--rule);
  padding-inline: 0;
  box-shadow: none;
}
.page-archive .selected-work-lead:has(a:hover),
.page-archive .selected-work-card:has(a:hover) { transform: none; }
