/* ============================================================================
   WASTELAND — an intelligence bulletin.

   WHY THIS REPLACES THE PREVIOUS SHEET RATHER THAN REFINING IT.
   The old design was competent and wearing a uniform: amber on near-black,
   uppercase monospace eyebrows over every section, a `SYS::ONLINE` badge and a
   pulsing `LIVE` dot that reported nothing, a dithered particle range behind the
   subscribe form, and the same italic-accent-word headline trick three times on
   one page. Individually defensible; together they are the house style of every
   generated security site, which is precisely the complaint.

   Two decisions carry the replacement, and everything else follows from them.

   1. THE GROUND IS PAPER. Dark was picked from the category ("cyber"), not from
      the use scene. The reader here is a defender reading a 900-word brief at a
      desk during the working day. Paper is also the single fastest way to stop
      reading as generated, because the generated version of this site is always
      black. Ink-on-paper is a harder brief to hide behind.

   2. MONO IS FOR DATA ONLY. CVE identifiers, dates, CVSS scores, counts. Never a
      section label, never a button, never a decorative eyebrow. Monospace worn as
      a costume for "technical" was doing most of the work of making the old sheet
      look machine-made.

   One accent, an oxidised red, and it only ever marks severity — so it can never
   drift into decoration. Emphasis elsewhere comes from weight, size and rules.

   COMPATIBILITY CONTRACT. Every selector the Python renderers emit is covered
   here, including two that had no rules at all before (`.why-callout`,
   `.sources-line` — injected by post_process_article() on every brief). The
   `:root` custom-property NAMES are load-bearing beyond this file: subscriptions.py
   embeds its own inline stylesheet for /unsubscribe that references --accent, --bg,
   --bg-raised, --font-display, --font-mono, --fs-h3, --fs-mono, --hairline,
   --hairline-2, --ink, --ink-dim and --s3..--s9 directly. Renaming any of those
   silently breaks a page that never imports this sheet, so they are all kept and
   re-pointed at the new values instead.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,300;0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;1,6..72,300;1,6..72,400;1,6..72,500&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

:root{
  /* --- ground --- */
  --paper:#f1f2f0;
  --paper-2:#e6e8e5;
  --paper-3:#d7dad6;
  --ink:#101519;
  --ink-2:#3d474f;
  --ink-3:#5f666e;
  --rule:#cbd0cb;
  --rule-strong:#99a09a;
  --signal:#123fbf;
  --crit:#a51f16;
  --signal-wash:#e4e9f7;
  --crit-wash:#f6e6e4;

  /* --- legacy names, kept because /unsubscribe's inline CSS reads them --- */
  --bg:var(--paper);
  --bg-raised:var(--paper-2);
  --bg-2:var(--paper-2);
  --ink-dim:var(--ink-2);
  --ink-faint:var(--ink-3);
  --ink-mute:var(--ink-2);
  --ink-soft:var(--ink-2);
  --hairline:var(--rule);
  --hairline-2:var(--rule-strong);
  --accent:var(--signal);
  --accent-2:var(--signal);
  --accent-3:var(--rule-strong);
  --accent-soft:var(--signal-wash);
  --accent-strong:var(--signal);
  --danger:var(--crit);
  --paper-tone:var(--paper);

  --font-display:'Bricolage Grotesque','Helvetica Neue',Arial,sans-serif;
  --font-mono:'Geist Mono',ui-monospace,'SFMono-Regular','Courier New',monospace;

  /* Display tops out well under the old 5rem: at Newsreader's weight a 5rem
     line is a shout, and the lead story has to sit next to a subscribe box
     without flattening it. */
  --fs-hero:clamp(2.1rem,1.15rem + 3.5vw,3.9rem);
  --fs-h1:clamp(1.8rem,1.25rem + 2.2vw,2.9rem);
  --fs-h2:clamp(1.35rem,1.1rem + 1vw,1.9rem);
  --fs-h3:clamp(1.12rem,1rem + 0.55vw,1.4rem);
  --fs-lede:clamp(1.05rem,0.98rem + 0.42vw,1.28rem);
  --fs-body:clamp(1.02rem,0.99rem + 0.2vw,1.12rem);
  --fs-mono:clamp(0.72rem,0.68rem + 0.16vw,0.8rem);
  --fs-mono-s:0.68rem;

  --gutter:clamp(20px,4.5vw,72px);
  --maxw:1320px;
  /* the reading measure: ~68 characters of Newsreader at body size */
  --measure:43rem;
  --s1:4px;--s2:8px;--s3:12px;--s4:16px;--s5:24px;
  --s6:32px;--s7:48px;--s8:clamp(44px,8vw,80px);--s9:clamp(56px,10vw,120px);
  --rule-w:1px;
}

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
html{-webkit-text-size-adjust:100%;}
body{
  background:var(--paper);color:var(--ink);font-family:var(--font-display);
  font-size:var(--fs-body);line-height:1.55;min-height:100vh;overflow-x:hidden;
  font-optical-sizing:auto;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
}
a{color:inherit;text-decoration:none;}
ul,ol{list-style:none;}
img,svg{display:block;max-width:100%;}
button,input,select,textarea{font:inherit;color:inherit;border-radius:0;}
h1,h2,h3,h4,p{margin:0;overflow-wrap:break-word;}
::selection{background:var(--ink);color:var(--paper);}
@keyframes pulse{50%{opacity:0.35;}}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:0.001ms!important;animation-iteration-count:1!important;
    transition-duration:0.001ms!important;}
}

/* A single shared data voice. Anything wearing this is a measurement. */
.data,.status-strip .cell,.row-tag,.sev-label,.col-date,.brief-head .id,
.brief-head .date,.featured .num,.featured .date,.issue .num,.issue .date-line,
.issue-dark .num,.issue-dark .date-line,.featured-issue .num,.featured-issue .date,
.chip .n,.console-foot,.article-head .meta,.pager-nav .dir{
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;
  letter-spacing:0.02em;
}

/* ---------- skip link ---------- */
.skip-link{position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--ink);color:var(--paper);padding:10px 16px;
  font-family:var(--font-mono);font-size:var(--fs-mono);}
.skip-link:focus{left:0;}
:focus-visible{outline:2px solid var(--signal);outline-offset:2px;}

/* ---------- masthead ---------- */
.masthead{border-bottom:1px solid var(--ink);display:flex;align-items:baseline;
  gap:clamp(12px,2.4vw,32px);flex-wrap:wrap;
  max-width:var(--maxw);margin:0 auto;padding:18px var(--gutter) 12px;}
.masthead .brand{font-size:clamp(1.55rem,1.1rem + 1.6vw,2.4rem);font-weight:600;
  letter-spacing:-0.028em;line-height:1;order:0;}
/* The wordmark's full stop was set in the accent as a logo flourish. Red is
   severity here and nothing else, so it becomes ink -- a period, not a dot. */
.masthead .brand i{font-style:normal;color:var(--ink);}
.masthead .left{order:1;font-style:italic;color:var(--ink-3);font-size:1rem;
  display:flex;align-items:baseline;gap:8px;}
/* The pulsing status LED is gone from the markup; if any cached page still
   emits it, it collapses rather than reappearing as decoration. */
.masthead .left .dot{display:none;}
.masthead .right{order:2;margin-left:auto;display:flex;
  gap:clamp(14px,2vw,26px);align-items:baseline;}
.masthead .right a{font-size:0.98rem;padding-bottom:2px;
  border-bottom:1px solid transparent;transition:border-color 160ms ease;}
.masthead .right a:hover{border-bottom-color:var(--ink);}
.masthead .right a.on{border-bottom-color:var(--signal);font-weight:500;}

/* ---------- dateline (was: the SYS::ONLINE / LIVE status strip) ----------
   Same slot, same live counts -- those are real numbers off get_intel_articles()
   and get_issues(). What is gone is the chrome that reported nothing. */
.status-strip{border-bottom:1px solid var(--rule);background:var(--paper-2);}
.status-strip{display:flex;flex-wrap:wrap;gap:5px 26px;
  max-width:var(--maxw);margin:0 auto;padding:9px var(--gutter);}
.status-strip .cell{font-size:var(--fs-mono);color:var(--ink-3);
  display:flex;align-items:baseline;gap:7px;}
.status-strip .cell .label{text-transform:none;letter-spacing:0.02em;}
.status-strip .cell .val{color:var(--ink);font-weight:600;}
.status-strip .cell:nth-child(3){display:none;}
.status-strip .live{display:none;}
.status-strip .live .dot{display:none;}
@media (min-width:520px){.status-strip .cell:nth-child(3){display:flex;}}

/* ---------- the reading column ----------
   The brief and issue pages emit .brief-head / .brief-lede / .brief-body /
   .pager-nav as DIRECT children of <main> -- there is no wrapper div to hang a
   gutter on. The old sheet handled that by giving each block its own
   `max-width + margin-inline:auto + padding-inline`, and the first cut of this
   rewrite dropped it, which put every article's text flush against the left edge
   of the viewport on the live site. Restored as one shared rule so the next
   article-shaped page cannot miss it. */
.brief-head,.brief-lede,.brief-body,.pager-nav,.article-head,.issue-body,
.doc-page,.confirm-page,.page-head,.toolbar,.console-foot,.featured-issue,
.issues-grid,.section-head{
  width:100%;max-width:var(--maxw);margin-inline:auto;
  padding-inline:var(--gutter);}
/* ONE measure, in rem, shared by every block in the reading column.
   It was `ch` per block, and `ch` resolves against each element's OWN font-size --
   so the lede (larger type) computed a different width from the body, each block
   centred itself at a different width, and the live article had four different
   left edges: measured at 381 / 385 / 399 / 328px. A reading column with a ragged
   left margin is the one thing a text page cannot have. rem is font-size-invariant,
   so every block below starts on the same line. */
.brief-head,.brief-lede,.brief-body,.issue-body,.doc-page,.article-head,
.pager-nav,.confirm-page{max-width:min(100%,var(--measure));}

/* ---------- shared containers ---------- */
.container,.intel-wrap,.section-block,.hero-inner,.week-strip-inner,
.archive-preview-inner,.sub-band-inner{
  max-width:var(--maxw);margin:0 auto;padding-left:var(--gutter);padding-right:var(--gutter);}

/* ============================================================================
   FRONT PAGE
   The lead story IS the hero. The old page spent its first screen on a slogan
   and pushed 2,300 briefs below the fold; the slogan was the least valuable
   thing on the site and the briefs are the product.
   ========================================================================= */
.hero{position:relative;border-bottom:2px solid var(--ink);}
/* The dither/scanline/horizon artwork is deleted from the markup. These rules
   stay so a cached page renders as clean paper instead of stray gradients. */
.hero-scene,.scene-gradient,.scene-dither,.scene-tint,.scene-horizon,
.hero-scanlines,.hero-scrim{display:none!important;}
.hero-inner{display:grid;grid-template-columns:1fr;gap:32px;
  padding-top:clamp(28px,3.6vw,50px);padding-bottom:clamp(26px,3.2vw,42px);}
.hero-copy{border-bottom:1px solid var(--rule);padding-bottom:28px;}
.hero-copy h1{font-size:var(--fs-hero);font-weight:600;line-height:1.03;
  letter-spacing:-0.032em;text-wrap:balance;margin-bottom:18px;}
.hero-copy .deck{font-size:var(--fs-lede);line-height:1.5;color:var(--ink-2);
  font-weight:300;max-width:62ch;}

/* The one kicker in the system. Named, not sprinkled: it marks the lead story
   and nothing else, which is what separates a kicker from an eyebrow habit. */
.label-strip{font-family:var(--font-mono);font-size:var(--fs-mono);font-weight:600;
  letter-spacing:0.08em;text-transform:uppercase;color:var(--signal);
  margin-bottom:14px;display:flex;align-items:center;gap:9px;}
.label-strip .pulse{display:none;}

form{display:flex;margin-top:20px;border:1px solid var(--ink);max-width:34rem;}
.hero-copy form input,.sub-band form input{flex:1;min-width:0;border:0;
  background:transparent;padding:11px 13px;font-family:var(--font-display);
  font-size:1rem;color:var(--ink);}
.hero-copy form input::placeholder,.sub-band form input::placeholder{color:var(--ink-3);}
.hero-copy form input:focus,.sub-band form input:focus{outline:2px solid var(--signal);
  outline-offset:-2px;}
.hero-copy form button,.sub-band form button{border:0;border-left:1px solid var(--ink);
  background:var(--ink);color:var(--paper);padding:11px 17px;
  font-family:var(--font-mono);font-size:var(--fs-mono);font-weight:600;
  letter-spacing:0.06em;text-transform:uppercase;cursor:pointer;white-space:nowrap;
  transition:background 180ms cubic-bezier(.2,.7,.3,1);}
.hero-copy form button:hover,.sub-band form button:hover{background:var(--signal);}
.hero-copy form button:disabled,.sub-band form button:disabled{
  background:var(--ink-3);cursor:not-allowed;}
.reader-note{margin-top:12px;font-size:0.86rem;color:var(--ink-3);font-style:italic;}
.reader-note a{border-bottom:1px solid var(--rule);}
.form-status{margin-top:10px;font-size:0.9rem;color:var(--ink-2);min-height:1.2em;}
.form-status.success{color:var(--ink);font-weight:500;}
.form-status.error{color:var(--signal);font-weight:500;}

/* ---------- featured card (latest issue), the right rail ---------- */
.featured{border:1px solid var(--ink);padding:clamp(18px,2vw,26px);
  background:var(--paper);align-self:start;}
.featured .kicker{font-family:var(--font-mono);font-size:var(--fs-mono-s);
  font-weight:600;letter-spacing:0.08em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:10px;display:flex;align-items:center;gap:8px;}
.featured .kicker .pulse{display:none;}
.featured .num{color:var(--signal);font-weight:600;}
.featured h2{font-size:var(--fs-h3);font-weight:600;line-height:1.22;
  letter-spacing:-0.02em;margin-bottom:10px;}
.featured .teaser{font-size:0.98rem;color:var(--ink-2);font-weight:300;
  line-height:1.5;font-style:italic;}
.featured .foot{margin-top:18px;padding-top:13px;border-top:1px solid var(--rule);
  display:flex;flex-wrap:wrap;gap:10px 18px;align-items:baseline;
  justify-content:space-between;}
.featured .date{font-size:var(--fs-mono);color:var(--ink-3);}
.featured .cta{font-weight:500;border-bottom:1.5px solid var(--signal);padding-bottom:1px;}
.featured .cta:hover{background:var(--signal-wash);}

/* ---------- section heads ---------- */
.section-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:18px;flex-wrap:wrap;padding:clamp(34px,4vw,58px) 0 12px;}
.section-head h2{font-size:var(--fs-h2);font-weight:600;letter-spacing:-0.025em;}
.section-head .more,.more{font-family:var(--font-mono);font-size:var(--fs-mono);
  color:var(--ink-3);border-bottom:1px solid var(--rule);padding-bottom:2px;}
.section-head .more:hover,.more:hover{color:var(--ink);border-bottom-color:var(--ink);}

/* ---------- latest-briefs strip ---------- */
.week-strip{border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
  background:var(--paper-2);}
.week-strip-inner{display:grid;grid-template-columns:1fr;gap:0;
  padding-top:0;padding-bottom:0;}
.week-strip .item{padding:16px 0;border-bottom:1px solid var(--rule);}
.week-strip-inner>.item:last-child{border-bottom:0;}
/* The class marker sits in a <small>, not a .label -- the first cut of this rule
   targeted .label, matched nothing, and shipped "…$128,539.57 PaymentRansomware"
   to the live page as one run-on string. Verified against the rendered markup. */
.week-strip .item small{display:block;font-family:var(--font-mono);
  font-size:var(--fs-mono-s);letter-spacing:0.06em;text-transform:uppercase;
  color:var(--ink-3);margin-top:6px;}
/* The strip's own caption, not one of the four items. */
.week-strip-inner>.label{font-family:var(--font-mono);font-size:var(--fs-mono-s);
  letter-spacing:0.08em;text-transform:uppercase;color:var(--ink-3);
  align-self:center;padding:16px 0;}
.week-strip .item:hover{text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;}
@media (min-width:760px){
  .week-strip-inner{grid-template-columns:repeat(4,1fr);gap:0 clamp(20px,2.4vw,36px);}
  .week-strip .item{border-bottom:0;border-right:1px solid var(--rule);
    padding-right:clamp(16px,2vw,28px);}
  .week-strip-inner>.item:last-child{border-right:0;}
}

/* ============================================================================
   THE INDEX. 2,300 briefs is the asset, so density is the aesthetic.
   Severity reads as weight and one red mark, not as a five-segment amber meter
   pretending to be an instrument.
   ========================================================================= */
.intel-wrap,.home-intel-preview{padding-bottom:clamp(30px,4vw,54px);}
table.tbl{width:100%;border-collapse:collapse;}
table.tbl thead{display:none;}
table.tbl tbody tr{display:block;padding:15px 0;border-bottom:1px solid var(--rule);}
table.tbl tbody tr:hover{background:var(--paper-2);}
table.tbl td{display:block;padding:0;}
table.tbl td.title{font-size:1.04rem;line-height:1.35;margin:6px 0 4px;
  max-width:72ch;}
table.tbl tbody tr:hover td.title{text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;}
.col-date{font-size:var(--fs-mono);color:var(--ink-3);white-space:nowrap;}
.row-tag{font-size:var(--fs-mono-s);letter-spacing:0.06em;text-transform:uppercase;
  color:var(--ink-3);white-space:nowrap;}

/* severity, table context */
.row-sev{display:inline-flex;align-items:center;gap:8px;white-space:nowrap;}
.sev-bar{display:inline-flex;align-items:center;gap:3px;}
.sev-cell{width:6px;height:6px;border:1px solid var(--rule-strong);
  background:transparent;display:inline-block;}
.sev-cell.on{background:var(--ink-3);border-color:var(--ink-3);}
.sev-label{font-size:var(--fs-mono-s);font-weight:600;letter-spacing:0.08em;
  text-transform:uppercase;color:var(--ink-2);}
.row-sev.sev-crit .sev-cell.on{background:var(--crit);border-color:var(--crit);}
.row-sev.sev-crit .sev-label{color:var(--crit);}
.row-sev.sev-high .sev-cell.on{background:var(--ink-2);border-color:var(--ink-2);}
.row-sev.sev-high .sev-label{color:var(--ink-2);}
.row-sev.sev-med .sev-cell.on{background:var(--ink-3);border-color:var(--ink-3);}
.row-sev.sev-med .sev-label{color:var(--ink-3);}

@media (min-width:860px){
  table.tbl thead{display:table-header-group;}
  table.tbl thead th{text-align:left;font-family:var(--font-mono);
    font-size:var(--fs-mono-s);font-weight:600;letter-spacing:0.1em;
    text-transform:uppercase;color:var(--ink-3);
    padding:0 14px 8px 0;border-bottom:1px solid var(--rule-strong);}
  table.tbl thead th:last-child{text-align:right;padding-right:0;}
  table.tbl tbody tr{display:table-row;padding:0;}
  table.tbl td{display:table-cell;padding:13px 14px 13px 0;vertical-align:baseline;}
  table.tbl td:last-child{text-align:right;padding-right:0;}
  table.tbl td.title{margin:0;}
  .col-sev{width:132px;}
  .col-class{width:118px;}
  .col-date{width:92px;}
}

/* ---------- /intel listing head + tools ---------- */
.page-head{padding:clamp(30px,3.6vw,50px) 0 0;}
.page-head .section-h,.page-head .left-h h1{font-size:var(--fs-h1);font-weight:600;
  letter-spacing:-0.028em;}
.page-head .lede{margin-top:10px;font-size:var(--fs-lede);color:var(--ink-2);
  font-weight:300;max-width:64ch;}
.page-head .meta{margin-top:10px;font-family:var(--font-mono);
  font-size:var(--fs-mono);color:var(--ink-3);}
.toolbar{display:flex;flex-wrap:wrap;gap:12px 16px;align-items:center;
  padding:20px 0 14px;border-bottom:1px solid var(--rule);}
.search{flex:1;min-width:220px;border:1px solid var(--rule-strong);
  background:var(--paper);padding:9px 12px;font-family:var(--font-display);
  font-size:0.98rem;}
.search::placeholder{color:var(--ink-3);}
.search:focus{outline:2px solid var(--signal);outline-offset:-2px;}
.chips{display:flex;flex-wrap:wrap;gap:8px;}
.chip{border:1px solid var(--rule-strong);background:transparent;
  padding:7px 12px;cursor:pointer;font-family:var(--font-mono);
  font-size:var(--fs-mono-s);letter-spacing:0.06em;text-transform:uppercase;
  color:var(--ink-2);display:inline-flex;align-items:center;gap:7px;
  transition:background 160ms ease,border-color 160ms ease,color 160ms ease;}
.chip:hover{border-color:var(--ink);color:var(--ink);}
.chip[aria-pressed="true"],.chip.on{background:var(--ink);border-color:var(--ink);
  color:var(--paper);}
.chip .n{color:inherit;opacity:0.65;}
.console-foot{padding:20px 0 0;font-size:var(--fs-mono);color:var(--ink-3);}

/* ============================================================================
   ARTICLE PAGES. The old sheet carried the long-form body rules THREE times --
   .brief-body, .issue-body byte-identical, plus a third near-copy for .doc-page.
   One rule set now, three selectors, so a fix to reading typography cannot land
   on briefs and miss issues again.
   ========================================================================= */
.brief-head,.article-head{padding:clamp(30px,3.6vw,50px) 0 0;
  border-bottom:1px solid var(--rule);padding-bottom:22px;}
.brief-head h1,.article-head h1{font-size:var(--fs-h1);font-weight:600;
  line-height:1.08;letter-spacing:-0.03em;text-wrap:balance;max-width:26ch;}
.article-head .kicker{font-family:var(--font-mono);font-size:var(--fs-mono);
  font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:var(--signal);
  margin-bottom:12px;}
.brief-head .meta-row,.article-head .meta{margin-top:14px;display:flex;
  flex-wrap:wrap;gap:8px 20px;align-items:baseline;
  font-size:var(--fs-mono);color:var(--ink-3);}
.brief-head .meta-row .sev{font-family:var(--font-mono);font-size:var(--fs-mono-s);
  font-weight:600;letter-spacing:0.08em;text-transform:uppercase;color:var(--ink-2);}
.brief-head .meta-row .sev.sev-crit{color:var(--signal);}
.brief-head .meta-row .sev.sev-crit::before{content:"";display:inline-block;
  width:6px;height:6px;background:var(--signal);margin-right:7px;vertical-align:0.1em;}
.brief-head .meta-row .sev.sev-high::before,
.brief-head .meta-row .sev.sev-med::before{content:"";display:inline-block;
  width:6px;height:6px;border:1px solid var(--ink-3);margin-right:7px;
  vertical-align:0.1em;}
/* No local max-width here: a second, narrower one made this block centre 16px
   right of every other block in the column. The shared --measure owns the width. */
.brief-lede{margin-top:22px;font-size:var(--fs-lede);line-height:1.5;
  color:var(--ink-2);font-weight:300;}

.brief-body,.issue-body,.doc-page{padding:clamp(22px,2.6vw,34px) 0 0;}
.brief-body p,.issue-body p,.doc-page p{margin:0 0 1.15em;}
.brief-body h2,.issue-body h2,.doc-page h2{font-size:var(--fs-h2);font-weight:600;
  letter-spacing:-0.022em;line-height:1.2;margin:2em 0 0.55em;}
.brief-body h3,.issue-body h3,.doc-page h3{font-size:var(--fs-h3);font-weight:600;
  letter-spacing:-0.015em;margin:1.7em 0 0.45em;}
.brief-body h1,.issue-body h1{font-size:var(--fs-h1);font-weight:600;
  letter-spacing:-0.03em;margin:1.4em 0 0.5em;}
.brief-body h4,.issue-body h4,.brief-body h5,.issue-body h5,
.brief-body h6,.issue-body h6{font-size:1.02rem;font-weight:600;
  margin:1.5em 0 0.4em;}
.brief-body a,.issue-body a,.doc-page a{border-bottom:1px solid var(--rule-strong);
  transition:border-color 140ms ease,background 140ms ease;}
.brief-body a:hover,.issue-body a:hover,.doc-page a:hover{
  border-bottom-color:var(--signal);background:var(--signal-wash);}
.brief-body ul,.issue-body ul,.doc-page ul,
.brief-body ol,.issue-body ol,.doc-page ol{margin:0 0 1.15em;padding-left:1.4em;}
.brief-body li,.issue-body li,.doc-page li{margin:0 0 0.45em;position:relative;}
.brief-body ul li::before,.issue-body ul li::before,.doc-page ul li::before{
  content:"";position:absolute;left:-1.05em;top:0.62em;width:5px;height:5px;
  background:var(--rule-strong);}
.brief-body ol,.issue-body ol,.doc-page ol{list-style:decimal;}
.brief-body ol li::before,.issue-body ol li::before,.doc-page ol li::before{content:none;}
.brief-body strong,.issue-body strong,.doc-page strong{font-weight:600;}
.brief-body blockquote,.issue-body blockquote{margin:1.5em 0;padding:0 0 0 1.3em;
  border-left:1px solid var(--rule-strong);font-style:italic;color:var(--ink-2);}
.brief-body code,.issue-body code{font-family:var(--font-mono);font-size:0.86em;
  background:var(--paper-2);padding:1px 5px;border:1px solid var(--rule);}
.brief-body pre,.issue-body pre{margin:1.4em 0;padding:14px 16px;
  background:var(--paper-2);border:1px solid var(--rule);overflow-x:auto;}
.brief-body pre code,.issue-body pre code{background:none;border:0;padding:0;
  font-size:0.84em;line-height:1.5;}
.brief-body hr,.issue-body hr{border:0;border-top:1px solid var(--rule);margin:2.2em 0;}
.brief-body img,.issue-body img{margin:1.5em 0;border:1px solid var(--rule);}
.brief-body table,.issue-body table{width:100%;border-collapse:collapse;margin:1.5em 0;
  font-size:0.96rem;}
.brief-body th,.issue-body th{text-align:left;font-weight:600;
  border-bottom:1px solid var(--rule-strong);padding:8px 12px 8px 0;}
.brief-body td,.issue-body td{border-bottom:1px solid var(--rule);
  padding:9px 12px 9px 0;vertical-align:baseline;}

/* Injected after sanitisation by post_process_article(). Both classes have been
   emitted on every brief for months with NO rules anywhere in the old sheet, so
   the pull-quote the writing was building toward rendered as an ordinary
   paragraph. Styling them is a straight correction, not a new feature. */
.why-callout{margin:1.8em 0;padding:18px 20px;background:var(--paper-2);
  border-left:2px solid var(--signal);font-size:1.06rem;line-height:1.5;}
.why-callout strong{display:block;font-family:var(--font-mono);
  font-size:var(--fs-mono-s);font-weight:600;letter-spacing:0.09em;
  text-transform:uppercase;color:var(--signal);margin-bottom:7px;}
.sources-line{margin-top:2.2em;padding-top:14px;border-top:1px solid var(--rule);
  font-size:0.9rem;color:var(--ink-3);}
.sources-line em{font-style:italic;}

/* ---------- pager ---------- */
.pager-nav{display:grid;grid-template-columns:1fr;gap:14px;
  margin-top:clamp(38px,4.5vw,62px);padding-top:22px;border-top:1px solid var(--ink);}
.pager-nav a,.pager-nav .disabled{display:block;padding:14px 0;
  border-bottom:1px solid var(--rule);}
.pager-nav .disabled{opacity:0.4;}
.pager-nav .dir{display:block;font-size:var(--fs-mono-s);letter-spacing:0.08em;
  text-transform:uppercase;color:var(--ink-3);margin-bottom:5px;}
.pager-nav .title-line{font-size:1.02rem;line-height:1.35;}
.pager-nav a:hover .title-line{text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:3px;}
@media (min-width:700px){
  .pager-nav{grid-template-columns:1fr 1fr;gap:0 clamp(20px,3vw,44px);}
  .pager-nav .prev{text-align:left;}
  .pager-nav .next{text-align:right;}
}

/* ============================================================================
   ARCHIVE
   ========================================================================= */
.featured-issue{padding:clamp(28px,3.4vw,46px) 0 0;}
.featured-issue .card{display:grid;grid-template-columns:1fr;gap:20px;
  border:1px solid var(--ink);padding:clamp(20px,2.4vw,32px);}
.featured-issue .meta{display:flex;flex-wrap:wrap;gap:8px 18px;align-items:baseline;
  font-size:var(--fs-mono);color:var(--ink-3);margin-bottom:12px;}
.featured-issue .meta .pulse{display:none;}
.featured-issue .num{color:var(--signal);font-weight:600;}
.featured-issue .left h2,.featured-issue h2{font-size:var(--fs-h2);font-weight:600;
  line-height:1.16;letter-spacing:-0.025em;text-wrap:balance;}
.featured-issue .teaser{font-size:var(--fs-lede);color:var(--ink-2);font-weight:300;
  line-height:1.5;font-style:italic;}
.featured-issue .cta{display:inline-block;margin-top:16px;font-weight:500;
  border-bottom:1.5px solid var(--signal);padding-bottom:1px;}
.featured-issue .cta:hover{background:var(--signal-wash);}
@media (min-width:860px){
  .featured-issue .card{grid-template-columns:1.35fr 1fr;gap:0 clamp(28px,3.4vw,56px);}
  .featured-issue .right{border-left:1px solid var(--rule);
    padding-left:clamp(24px,2.8vw,44px);}
}

.issues-grid{padding:clamp(30px,3.6vw,50px) 0 0;}
.issues{display:grid;grid-template-columns:1fr;}
.issue{padding:20px 0;border-bottom:1px solid var(--rule);}
.issue .num{font-size:var(--fs-mono);color:var(--signal);font-weight:600;}
.issue h3{margin-top:7px;font-size:var(--fs-h3);font-weight:500;line-height:1.26;
  letter-spacing:-0.015em;}
.issue .date-line{margin-top:7px;font-size:var(--fs-mono);color:var(--ink-3);}
.issue .arrow{display:none;}
.issue:hover h3{text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;}
@media (min-width:700px){
  .issues{grid-template-columns:1fr 1fr;gap:0 clamp(22px,2.6vw,40px);}
  .issue{border-bottom:1px solid var(--rule);}
}
@media (min-width:1040px){.issues{grid-template-columns:repeat(3,1fr);}}

/* "Past issues" band on the homepage. Was a dark inverted slab; on paper it is
   a rule and a change of ground, which is enough to separate a section. */
.archive-preview{border-top:2px solid var(--ink);background:var(--paper-2);
  margin-top:clamp(34px,4vw,58px);}
.archive-preview-inner{padding-top:clamp(26px,3vw,42px);
  padding-bottom:clamp(30px,3.4vw,48px);}
.archive-preview .archive-h{display:flex;align-items:baseline;
  justify-content:space-between;gap:18px;flex-wrap:wrap;
  border-bottom:1px solid var(--rule-strong);padding-bottom:12px;}
.archive-preview .archive-h h2{font-size:var(--fs-h2);font-weight:600;
  letter-spacing:-0.025em;}
.issues-dark{display:grid;grid-template-columns:1fr;}
.issue-dark{padding:20px 0;border-bottom:1px solid var(--rule);}
.issue-dark .num{font-size:var(--fs-mono);color:var(--signal);font-weight:600;}
.issue-dark h3{margin-top:7px;font-size:var(--fs-h3);font-weight:500;
  line-height:1.26;letter-spacing:-0.015em;}
.issue-dark .date-line{margin-top:7px;font-size:var(--fs-mono);color:var(--ink-3);}
.issue-dark .arrow{display:none;}
.issue-dark:hover h3{text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:3px;}
@media (min-width:760px){
  .issues-dark{grid-template-columns:repeat(3,1fr);gap:0 clamp(22px,2.6vw,40px);}
  .issue-dark{border-bottom:0;border-right:1px solid var(--rule);
    padding-right:clamp(18px,2.2vw,32px);}
  .issues-dark>.issue-dark:last-child{border-right:0;}
}

/* ---------- subscribe band (archive pages) ---------- */
.sub-band{border-top:2px solid var(--ink);margin-top:clamp(38px,4.5vw,64px);}
.sub-band-inner{padding-top:clamp(26px,3vw,42px);padding-bottom:clamp(26px,3vw,42px);
  display:grid;gap:16px;}
.sub-band .label{font-size:var(--fs-h3);font-weight:600;letter-spacing:-0.02em;}
.sub-band .form-status{margin-top:8px;}

/* ---------- doc pages ---------- */
.doc-page{padding-top:clamp(30px,3.6vw,50px);}
.doc-page h1{font-size:var(--fs-h1);font-weight:600;letter-spacing:-0.03em;
  line-height:1.1;margin-bottom:0.5em;}
.doc-page h1+p{font-size:var(--fs-lede);color:var(--ink-2);font-weight:300;
  margin-bottom:1.6em;}

/* ---------- confirm ---------- */
.confirm-page{padding:clamp(44px,6vw,90px) 0;}
.confirm-page h1{font-size:var(--fs-h1);font-weight:600;letter-spacing:-0.03em;
  line-height:1.1;margin-bottom:0.5em;}
.confirm-page p{font-size:var(--fs-lede);color:var(--ink-2);font-weight:300;}
.confirm-cta{display:inline-block;margin-top:26px;background:var(--ink);
  color:var(--paper);padding:12px 22px;font-family:var(--font-mono);
  font-size:var(--fs-mono);font-weight:600;letter-spacing:0.06em;
  text-transform:uppercase;transition:background 180ms cubic-bezier(.2,.7,.3,1);}
.confirm-cta:hover{background:var(--signal);}

/* ---------- colophon ---------- */
.site-foot{margin-top:clamp(48px,6vw,88px);border-top:1px solid var(--ink);
  max-width:var(--maxw);margin-left:auto;margin-right:auto;
  padding:22px var(--gutter) 46px;
  display:flex;flex-wrap:wrap;gap:12px 28px;align-items:baseline;
  justify-content:space-between;font-size:0.9rem;color:var(--ink-3);}
.site-foot span{font-style:italic;}
.site-foot a{font-family:var(--font-mono);font-size:var(--fs-mono);
  border-bottom:1px solid transparent;}
.site-foot a:hover{color:var(--ink);border-bottom-color:var(--rule-strong);}

/* ---------- front-page two-column, last so it wins ---------- */
@media (min-width:860px){
  .hero-inner{grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
    gap:0 clamp(28px,3.6vw,60px);}
  .hero-copy{border-bottom:0;border-right:1px solid var(--rule);padding-bottom:0;
    padding-right:clamp(22px,2.6vw,42px);}
}
@media (min-width:620px){
  .masthead{flex-wrap:nowrap;}
}
