/* Step Up AVL — "The Broadsheet".
   Design system for the homepage, the four section pages, and the shared
   masthead/footer shell. Articles (files/) and the Desk (desk/) keep their own
   sheets for now and join this file in later phases.

   Colors are sampled from the Step Up AVL logo. Source of truth for the tokens
   and the section specs: _docs/design/broadsheet-2026-07/README.md */

/* ------------------------------------------------------------------- typefaces
   Served from this origin, not fonts.googleapis.com. `font-display: optional` is
   what holds CLS at zero, and its cost is that a face missing its ~100ms window is
   not used at all for that load. From Google the font could not START downloading
   until a stylesheet on one third-party host had been fetched and parsed to reveal
   a URL on a second: two DNS lookups, two TLS handshakes, serialized. Preloaded
   from here it begins during HTML parse on an open connection, so the same
   guarantee lands on the real typeface far more often. Provenance, subsetting and
   licences: assets/fonts/README.md. */
@font-face {
  font-family: "Newsreader";
  src: url("fonts/newsreader.woff2") format("woff2-variations");
  font-weight: 400 800;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: "Newsreader";
  src: url("fonts/newsreader-italic.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: italic;
  font-display: optional;
}
@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo.woff2") format("woff2-variations");
  font-weight: 400 800;
  font-style: normal;
  font-display: optional;
}

/* ---------------------------------------------------------------- font fallbacks
   Metric-matched stand-ins for the two web fonts, and the single largest CLS fix
   this site has. Measured 2026-07-28: web-font swap was 100% of the layout shift
   on every page with no JS mounts, which is ~70 of 82 - blocking fonts.googleapis
   took why-this-exists from 0.392 to 0.000, by-the-time-you-see-me from 0.362 to
   0.000. Nothing else on those pages can move.

   Newsreader is markedly NARROWER than Georgia (0.4002em vs 0.4375em average
   advance, weighted by English letter frequency), so unadjusted Georgia sets the
   same copy in fewer lines and every block below it jumps when the real font
   lands. size-adjust closes that; the ascent/descent overrides keep the line box
   the same height so the jump is not simply traded for a vertical one.

   Numbers are computed, not chosen: scratch script reads unitsPerEm, the typo or
   hhea ascent/descent pair the browser would use, and the frequency-weighted mean
   advance from pdf-tool/fonts.json (which already carries both families as TTF for
   the PDF builder) and from the system fallback. Recompute if either font is
   updated.

   Each face names ONE local font on purpose. A platform without Georgia or Arial
   falls through to the next entry in the stack unadjusted, which is exactly the
   behaviour we had before; listing several locals under one set of overrides would
   apply Georgia's correction to a font that is not Georgia and could make a page
   worse. Android, which has neither, is still unimproved. */
@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia");
  size-adjust: 91.49%;
  ascent-override: 80.34%;
  descent-override: 28.96%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Archivo Fallback";
  src: local("Arial");
  size-adjust: 101.82%;
  ascent-override: 86.23%;
  descent-override: 20.62%;
  line-gap-override: 0%;
}

:root {
  /* Main-site palette */
  --paper:        #F6F3EC;
  --ink:          #1D2B2D;
  --avl-green:    #2C7569;
  --deep-green:   #216F57;
  --bar-1:        #6ACCA6;
  --bar-2:        #35A076;
  --bar-3:        #216F57;
  --gold:         #DEB249;
  /* --gold is a dot/underline color; at 1.9:1 on paper it cannot carry text.
     Small gold LABELS use this instead (5.0:1). */
  --gold-text:    #7A5C14;
  /* Rust used for the "Local reporting" tag on the news rail (core independent
     WNC outlets). Darkened from --article-red for small-text contrast on paper
     (~6:1). */
  --localmedia:   #9E4423;

  /* Article reading mode (used from phase 3 on; declared here so the
     tokens live in one place) */
  --article-red:  #AB422D;
  --charcoal:     #26221E;
  /* --article-red is tuned for dark-on-light and cannot come back the other way: on
     --charcoal it reads 2.67:1. The site-up CTA is the one place the rust sits on the
     charcoal block, so that block uses this instead (4.76:1, clears AA for the 17.5px
     arrow as well as the 40px tag). Darkening --article-red for AA on paper is what
     made this necessary: it had been 3.21:1, which passed the 3:1 large-text bar the
     40px tag needed, and 2.67 does not. A repair can create the next defect. */
  --article-red-on-dark: #F05C40;
  --spruce:       #223B33;
  --callout-tint: #F1EAD9;
  --cta-cream:    #E9E2D4;

  /* Text */
  --body-text:    #2C3733;
  /* Same value as --ink, under a name no article shadows. Every article's inline
     <style> redefines :root { --ink: #221d17 } for its own warm palette, so a
     shared sheet cannot reach the Broadsheet ink through var(--ink). Use this
     when a rule in article.css / article-legacy.css must resolve to the real
     ink regardless of the page it lands on. */
  --ink-deep:     #1D2B2D;
  --text-secondary: #5C6B66;
  --text-tertiary:  #33403C;

  /* Rules, panels, cards */
  --hairline:   #CFD7D0;
  --panel-rule: #DDE3DC;
  --panel-bg:   #EAEFE9;
  --panel-bg-2: #EFF3EE;
  --card-bg:    #FCFBF4;

  /* Footer */
  --foot-body:  #A9B3AE;
  --foot-link:  #C9CFC9;
  --foot-label: #7E8B85;

  /* WNC Desk sub-brand */
  --desk-indigo: #2A265C;
  --desk-sheet:  #FBF8F1;
  --desk-panel:  #F0EBDE;
  --desk-label:  #2F4A57;   /* was #3D5B6A; the mono labels read washed out */
  --desk-ink:    #2A2620;
  --desk-meta:   #4E4940;   /* was #5B554A; Courier at label sizes reads faint */
  /* Courier New has no medium weight, so a mono label can only get darker, not
     heavier. This is the ink for mono metadata (datelines, dates, captions). */
  --desk-mono:   #3B372F;
  --desk-rule:   #E0D9C8;
  --signed:      #516B3C;
  --pending:     #B28340;

  /* The Fallback entries sit second, ahead of the plain stack: they ARE Georgia and
     Arial, wearing metrics that match the web font. The unadjusted names stay behind
     them for platforms that have neither. See the @font-face block above. */
  --serif: "Newsreader", "Newsreader Fallback", Georgia, "Times New Roman", serif;
  --sans:  "Archivo", "Archivo Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:  "Courier New", ui-monospace, SFMono-Regular, Menlo, monospace;

  --measure: 1140px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--body-text);
  font-family: var(--serif);
  font-optical-sizing: auto;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--avl-green); text-decoration: none; }
a:hover { color: var(--deep-green); }

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 24px; }

.skip-link {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--paper);
  padding: 10px 16px; z-index: 10;
}
.skip-link:focus { left: 12px; top: 12px; }

/* ------------------------------------------------------------ trust strip */

.trust {
  border-bottom: 1px solid var(--ink);
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.trust .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding-top: 9px; padding-bottom: 9px; flex-wrap: wrap;
}
.trust a { color: var(--avl-green); }
.trust-sep { color: var(--hairline); margin: 0 6px; }

/* ---------------------------------------------------------------- masthead */

.masthead .wrap {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  padding-top: 26px;
  padding-bottom: 22px;
}

/* One line under the nameplate saying what the site is about, for the reader who
 * arrives from a search result and has never heard of us. Full width of the
 * masthead grid, so it centres under the wordmark and not under the brand column. */
.masthead-motto {
  grid-column: 1 / -1;
  margin: 10px 0 0;
  font-family: var(--serif);
  font-style: italic;
  font-size: 15px;
  color: var(--text-tertiary);
  text-align: center;
  text-wrap: pretty;
}

.mast-follow {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.mast-follow .follow-label { display: block; margin-bottom: 9px; }
.mast-follow a {
  display: inline-flex; align-items: center; gap: 6px;
  margin-right: 14px; color: var(--avl-green);
  letter-spacing: 0.06em;
}
.mast-follow svg { width: 13px; height: 13px; flex: none; }

/* align-items: baseline stands the bars on the wordmark's BASELINE rather than
 * its descender line. A flex item with no text baselines at its bottom margin
 * edge, which is exactly where the bars end, so this needs no magic number and
 * survives a change of type size or face. */
.brand-lockup {
  display: inline-flex; align-items: baseline; gap: 12px;
  position: relative; color: var(--ink);
}
.brand-lockup:hover { color: var(--ink); }

/* Three ascending bars under a gold dot (variant 1F, adopted 2026-07-10;
 * reference drawing _docs/design/broadsheet-2026-07/logo-1f-masthead.png).
 * The dot FLOATS clear of the tallest bar by ~0.07 of its height, and straddles
 * that bar's right edge, overlapping it by about half the dot. It does not rest
 * on the bar and it does not sit beside it.
 *
 * ONE geometry, scaled by --u (the bar width). Every CSS drawing of the mark
 * -- masthead .brand-mark, .masthead.compact, .site-foot, the phone masthead,
 * and .quiz-mark -- now shares this block and overrides only --u. Ratios:
 * box 4.25u x 6.125u, bars 2.25 / 3.5 / 4.75 u tall, step 1.375u, dot 1u
 * straddling the right edge. The two remaining hand-drawings of the mark, mark()
 * in scripts/build-share-cards.py and assets/logo-mark.svg, reproduce the SAME
 * ratios; keep all three in step. */
.brand-mark, .quiz-mark {
  --u: 8px;
  position: relative; flex: none;
  width: calc(var(--u) * 4.25); height: calc(var(--u) * 6.125);
}
.brand-mark i, .quiz-mark i {
  position: absolute; bottom: 0; width: var(--u); display: block; border-radius: 0;
}
.brand-mark i:nth-child(1), .quiz-mark i:nth-child(1) { left: 0;                     height: calc(var(--u) * 2.25); background: var(--bar-1); }
.brand-mark i:nth-child(2), .quiz-mark i:nth-child(2) { left: calc(var(--u) * 1.375); height: calc(var(--u) * 3.5);  background: var(--bar-2); }
.brand-mark i:nth-child(3), .quiz-mark i:nth-child(3) { left: calc(var(--u) * 2.75);  height: calc(var(--u) * 4.75); background: var(--bar-3); }
.brand-mark b, .quiz-mark b {
  position: absolute; top: 0; right: 0;
  width: var(--u); height: var(--u); border-radius: 50%;
  background: var(--gold);
}

.wordmark {
  font-family: var(--serif);
  font-weight: 700;
  font-size: 58px;
  line-height: 0.92;
  letter-spacing: -0.02em;
}
.wordmark .avl { color: var(--avl-green); }

.mast-action { justify-self: end; }

.btn-solid {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--avl-green); color: var(--paper);
  font-family: var(--sans); font-weight: 600; font-size: 12.5px;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 11px 18px; border-radius: 2px;
  transition: background 0.15s ease;
}
.btn-solid:hover { background: var(--deep-green); color: var(--paper); }

.btn-outline {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--avl-green); color: var(--avl-green);
  font-family: var(--sans); font-weight: 600; font-size: 12px;
  padding: 7px 13px; border-radius: 2px;
  transition: background 0.15s ease, color 0.15s ease;
}
.btn-outline:hover { background: var(--avl-green); color: var(--paper); }

.btn-desk {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--desk-indigo); color: var(--desk-sheet);
  border: 1px solid var(--desk-indigo);
  font-family: var(--sans); font-weight: 600; font-size: 12px;
  padding: 7px 13px; border-radius: 2px;
}
.btn-desk:hover { background: #221E4C; color: var(--desk-sheet); }

/* -------------------------------------------------------------- nav rule */

.navrule {
  border-top: 1px solid var(--ink);
  border-bottom: 3px double var(--ink);
}
.navrule .wrap {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 4px;
  padding-top: 11px; padding-bottom: 11px;
}
.navrule a {
  font-family: var(--sans); font-weight: 600; font-size: 12px;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink); padding: 2px 0;
}
.navrule a:hover { color: var(--avl-green); }
.navrule a[aria-current="page"] {
  box-shadow: 0 5px 0 -3px var(--gold);
}
.navrule .dot { color: var(--hairline); margin: 0 14px; }

/* ------------------------------------------------- inner-page compact header */

/* The inner-page header sticks to the top on scroll. The trust strip above it
 * scrolls away; the 3px double rule moves onto the header itself so the rule
 * travels with it (the standalone .navrule-thin would otherwise slide under). */
.masthead.compact {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--paper);
  border-bottom: 3px double var(--ink);
}
.masthead.compact + .navrule-thin { display: none; }

.masthead.compact .wrap {
  grid-template-columns: auto 1fr;
  padding-top: 16px; padding-bottom: 14px;
}
/* The 1F drawing at ~0.63 scale: bar 3 is 24, the dot clears it by 2 and adds 5,
 * so the box is 31 tall; the dot overhangs bar 3's right edge by 3. */
.masthead.compact .brand-mark { --u: 5px; }
.masthead.compact .wordmark { font-size: 23px; }
.masthead.compact .inner-nav {
  justify-self: end;
  display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
}
.masthead.compact .inner-nav a {
  font-family: var(--sans); font-weight: 600; font-size: 11px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink);
}
.masthead.compact .inner-nav a:hover { color: var(--avl-green); }
.masthead.compact .inner-nav a[aria-current="page"] {
  box-shadow: 0 5px 0 -3px var(--gold);
}
.masthead.compact .inner-nav .btn-solid { color: var(--paper); box-shadow: none; }


/* ------------------------------------------------------------ lead section */

/* :has(> .lead-main) scopes this two-column grid to the article hero callout,
 * which always contains .lead-main. A bare `.lead` (e.g. a desk brief's intro
 * paragraph) has no .lead-main, so the grid can't leak onto it. */
.lead:has(> .lead-main) {
  /* 1.5fr, not the 1.9fr this ran at before 2026-08-08: the right column holds two
     numerical cards now rather than one paragraph, and at 365px both were wrapping
     hard while the headline column sat half empty. */
  display: grid; grid-template-columns: 1.5fr 1fr; gap: 34px;
  padding: 32px 0 34px;
  border-bottom: 1px solid var(--hairline);
}
.lead-main {
  padding-right: 34px;
  border-right: 1px solid var(--hairline);
}

.kicker {
  font-family: var(--sans); font-weight: 600; font-size: 11px;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--avl-green); margin: 0 0 12px;
}

.lead-main h1 {
  font-family: var(--serif); font-weight: 600; font-size: 38px;
  line-height: 1.08; letter-spacing: -0.01em;
  color: var(--ink); margin: 0 0 14px;
}
/* Accent word in a headline: same rust italic the page-head h1 uses. */
.lead-main h1 em { font-style: italic; font-weight: 500; color: var(--article-red); }
/* The :not()s matter: a bare `.lead-intro p` outranks `.kicker` and silently blew the
 * 11px kicker up to 18px, and it did the same to .lead-foot's 12px and its auto margin
 * -- the footnote rendered at body size and refused to settle at the foot of the
 * column, because (0,2,1) here beats a bare (0,1,0) class rule wherever it sits. */
.lead-intro > p:not(.kicker):not(.lead-foot) { font-size: 18px; line-height: 1.55; margin: 0 0 18px; }
.lead-actions {
  /* Both lead buttons ride one row and stay side by side, phones included.
     align-items:stretch makes the shorter button match the taller one's height. */
  display: flex; flex-wrap: nowrap; align-items: stretch; gap: 14px;
}
.lead-actions .btn-outline { box-sizing: border-box; }
.lead-more {
  /* inline-block, not the inherited inline-flex: the flex `gap` would open a
     6px hole either side of the injected org count. */
  display: inline-block;
  font-size: 14px; font-weight: 600; text-transform: none; letter-spacing: 0;
  padding: 10px 18px;
}
.lead-actions .btn-outline:not(.lead-more) {
  font-size: 14px; font-weight: 600; text-transform: none; letter-spacing: 0;
  padding: 10px 18px; white-space: nowrap;
}

/* Desktop only, switched on in the min-width block below. It exists to fill the foot
 * of the headline column once the badge moves to the rail, and on a phone there is no
 * such column and no such gap, so it would just be a fourth line of small print. */
.lead-foot { display: none; }

/* No gold rule down the side (dropped 2026-08-08, user's call): the stat block and the
 * live-count card are a matched pair of numbers now, and a bar on only the top one
 * argued they were different things. */
.lead-side p.lead-stat {
  font-family: var(--serif); font-weight: 700; font-size: 52px;
  line-height: 1; color: var(--deep-green); margin: 0;
}
.lead-side p { font-size: 16px; line-height: 1.5; margin: 10px 0 6px; }
.lead-side p.lead-note {
  font-family: var(--sans); font-size: 10.5px; letter-spacing: 0.04em;
  color: var(--text-secondary); margin: 0;
}

/* DESKTOP ONLY. The live-count badge leaves the left column and becomes the second
 * card in the stat rail, under 200,000+, so the page has one place for numbers.
 * min-width, not the max-width the rest of this file uses, and every rule the move
 * needs lives inside it: below 900px the lead stacks and the badge is simply the last
 * thing inside .lead-main, exactly where the markup puts it and exactly as the phone
 * has always rendered it.
 * display:contents dissolves .lead-main so .lead-intro and the badge become grid items
 * in their own right. .lead-intro then spans BOTH rows, which is the load-bearing bit:
 * it makes row 1 the height of the stat block alone, so the badge sits directly under
 * 200,000+ instead of dropping level with the bottom of the headline column. */
@media (min-width: 901px) {
  .lead:has(> .lead-main) { row-gap: 22px; }
  .lead-main { display: contents; }
  .lead-intro {
    grid-column: 1; grid-row: 1 / span 2;
    padding-right: 34px;
    border-right: 1px solid var(--hairline);
    /* Flex column purely so the footnote can take `margin-top: auto` and settle at the
       foot of the stretched column instead of stranding the whitespace below itself. */
    display: flex; flex-direction: column;
  }
  .lead-foot {
    display: block; margin: auto 0 0; padding-top: 14px;
    border-top: 1px solid var(--hairline);
    font-family: var(--sans); font-size: 12px; line-height: 1.5;
    color: var(--text-secondary);
  }
  .lead-side { grid-column: 2; grid-row: 1; }
  .lead .snap-bull {
    /* align-self:end, so whichever column is taller the two end flush and each side
       reads as a top block and a bottom block with the slack in the middle. With
       `start` the slack collects under the badge and the block loses its bottom edge. */
    grid-column: 2; grid-row: 2; align-self: end; margin: 0;
    /* A card, not a strip: the rail is about 365px, where the eyebrow, the number and
       the sentence cannot share a row. */
    flex-direction: column; align-items: flex-start; gap: 5px;
  }
  /* display:table, not block: the link carries a gold underline, and a block box would
     stretch that rule the full width of the card and read as a divider. */
  .lead .sb-go { display: table; white-space: normal; margin: 9px 0 0; }
}

/* -------------------------------------------------------- section scaffolding */

.section { padding: 30px 0 34px; border-bottom: 1px solid var(--hairline); }
.section:last-of-type { border-bottom: 0; }

.section-label {
  font-family: var(--sans); font-weight: 600; font-size: 11px;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-tertiary); margin: 0 0 14px;
}
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
}
.section-head h2 {
  font-family: var(--serif); font-weight: 600; font-size: 27px;
  color: var(--ink); margin: 0; letter-spacing: -0.01em;
}
.section-sub { font-size: 15px; color: var(--text-secondary); margin: 0; }

/* ------------------------------------------------------ organization spotlight */

/* The "AVL Steps Up" banner is NOT on the Broadsheet homepage. The name now
 * lives only in the footer's "On the name" line and the colophon.
 * (was: the celebratory banner for the orgs that already have.
   Distinct from the "Step Up AVL" wordmark, which is the site's identity. */
.spotlight-head .eyebrow {
  font-family: var(--sans); font-weight: 600; font-size: 11px;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-tertiary); margin-bottom: 18px;
}
.spotlight-duo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 28px;
}
.spotlight-card {
  background: var(--card-bg);
  border: 1px solid var(--panel-rule);
  border-top: 3px solid var(--avl-green);
  padding: 18px 20px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.spotlight-card:hover {
  border-color: var(--avl-green);
  box-shadow: 0 8px 20px -14px rgba(29, 43, 45, 0.4);
}
.spotlight-card h3 {
  font-family: var(--serif); font-weight: 600; font-size: 24px;
  margin: 0 0 3px; letter-spacing: -0.01em;
}
.spotlight-card h3 a { color: var(--ink); }
.spotlight-card h3 a:hover { color: var(--deep-green); }
.spotlight-card .city {
  font-family: var(--sans); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: #4A5A54; margin-bottom: 10px;
}
.spotlight-card .lede { font-size: 16px; line-height: 1.5; margin: 0 0 9px; }

.duo-stats { font-family: var(--sans); font-size: 13px; color: var(--ink); margin: 0 0 4px; }
.duo-stats .bigstat strong {
  font-family: var(--serif); font-weight: 700; font-size: 17px; color: var(--deep-green);
}
.duo-stats .stat-sep { color: var(--text-secondary); margin: 0 8px; }

.org-note {
  font-family: var(--sans); font-size: 10.5px; letter-spacing: 0.05em;
  color: var(--text-secondary); margin: 0 0 18px;
}

.ctas { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  font-family: var(--sans); font-size: 12.5px; font-weight: 600; }
.ctas .btn.donate {
  background: var(--avl-green); color: var(--paper);
  padding: 8px 15px; border-radius: 2px;
}
.ctas .btn.donate:hover { background: var(--deep-green); color: var(--paper); }
.ctas .btn.volunteer {
  color: var(--avl-green); border: 1px solid var(--avl-green);
  padding: 7px 14px; border-radius: 2px;
}
.ctas .btn.volunteer:hover { background: var(--avl-green); color: var(--paper); }
.ctas .btn.learn {
  color: var(--ink); margin-left: 12px;
  border-bottom: 1px solid var(--gold); padding-bottom: 1px;
}
.ctas .btn.learn:hover { color: var(--deep-green); border-bottom: 2px solid var(--gold); }

/* --------------------------------------------- start here + WNC Desk teaser */

.home-duo {
  display: grid; grid-template-columns: 1fr 1.5fr; gap: 40px;
  padding: 30px 0 38px;
}

.start-cards { display: grid; gap: 14px; }
.start-card {
  background: var(--panel-bg-2);
  border: 1px solid #D5DCD4;
  border-top: 3px solid var(--avl-green);
  padding: 16px 18px;
  transition: border-color 0.15s ease;
}
.start-card:hover { border-color: var(--avl-green); }
.start-card .e {
  display: block; font-family: var(--sans); font-size: 10px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--avl-green); margin-bottom: 6px;
}
.start-card .t {
  display: block; font-family: var(--serif); font-weight: 600; font-size: 18px;
  color: var(--ink); line-height: 1.25;
}
.start-card .c {
  display: block; font-family: var(--sans); font-size: 13px;
  color: var(--text-secondary); margin-top: 5px;
}

.desk-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 14px;
}
/* Shared by the Desk teaser and the Featured-reads strip: a 12px ink label with
 * an 11px muted caption under it. Both are Archivo; neither is a serif heading. */
.head-label {
  font-family: var(--sans); font-weight: 700; font-size: 12px;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink); margin: 0;
}
.head-sub {
  font-family: var(--sans); font-size: 11px; line-height: 1.45;
  color: var(--text-secondary); margin: 3px 0 0;
}
.desk-cards { display: grid; gap: 12px; }
.desk-card {
  display: block; background: var(--card-bg);
  border: 1px solid var(--panel-rule);
  border-left: 3px solid var(--desk-indigo);
  padding: 13px 16px;
  transition: border-color 0.15s ease;
}
.desk-card:hover { border-color: var(--desk-indigo); }
.desk-card .jur {
  display: block; font-family: var(--sans); font-size: 9.5px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--desk-label);
}
.desk-card .h {
  display: block; font-family: var(--serif); font-weight: 600; font-size: 17px;
  color: var(--ink); line-height: 1.25; margin-top: 3px;
}

/* ------------------------------------------------------------ featured reads */

.reads-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px;
}
.read-card {
  display: block; background: var(--card-bg);
  border: 1px solid var(--panel-rule);
  border-top: 3px solid var(--avl-green);
  padding: 16px 18px 18px;
  transition: border-color 0.15s ease;
}
.read-card:hover { border-color: var(--avl-green); }
.read-card .rk {
  font-family: var(--sans); font-weight: 600; font-size: 10px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--avl-green);
}
.read-card .rt {
  display: block; font-family: var(--serif); font-weight: 600; font-size: 19px;
  color: var(--ink); line-height: 1.28; margin: 7px 0 8px;
}
.read-card .rd { font-size: 13.5px; line-height: 1.55; color: var(--text-secondary); }

/* ------------------------------------------------------------------- footer */

.site-foot {
  background: var(--ink); color: var(--foot-body);
  margin-top: 48px; padding: 40px 0 30px;
  font-family: var(--sans); font-size: 13.5px; line-height: 1.6;
}
.site-foot .wrap {
  display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 34px;
}
.site-foot .wordmark { font-size: 26px; color: var(--paper); }
.site-foot .wordmark .avl { color: var(--bar-1); }
.site-foot .brand-lockup { color: var(--paper); margin-bottom: 12px; }
/* 1F at ~0.58 scale: bar 3 is 22, dot 5 clearing it by 2. */
.site-foot .brand-mark { --u: 5px; }
.foot-col h3 {
  font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--foot-body); font-weight: 600; margin: 0 0 12px;
}
.foot-col a { display: block; color: var(--foot-link); margin-bottom: 8px; }
.foot-col a:hover { color: var(--paper); }
.foot-col a.emph { font-weight: 600; color: var(--paper); }
.foot-disclaimer { margin: 0 0 6px; max-width: 42ch; }
.foot-legal { color: var(--foot-body); font-size: 12px; margin-top: 14px; }
.foot-soc { display: inline-flex; align-items: center; gap: 7px; }
.foot-soc svg { width: 13px; height: 13px; flex: none; }

/* --------------------------------------------------------------- the mark
   Easter egg in the homepage footer's lower left, linking to /specimens (the
   unlisted machine archive). A censor bar with words underneath: the archive's
   own masthead gag shrunk to footnote size. At rest it reads as a printing
   defect or a stray rule; hover/focus slides the bar back and the title
   appears. The amber is the archive's colour, deliberately foreign to the
   Broadsheet palette, which is what makes the eye stop on it.
   Markup lives in index.html ONLY (the other three footers do not carry it).
   Dedicated class names, not bare ones, per the bare-class collision rule. */
.foot-col a.foot-egg {
  position: relative; display: inline-block;
  margin: 18px 0 0; padding: 2px 0;
  line-height: 1; text-decoration: none;
  /* Tilt the whole mark, not just the bar: rotating them separately leaves the
     text peeking out at the ends, and the archive's own masthead tilts the
     redaction block the same way. */
  transform: rotate(-2deg);
}
.foot-egg-text {
  font-family: var(--mono);
  font-size: 11px; letter-spacing: 0.04em; color: #86948E;
  transition: color 0.2s 0.06s;
}
.foot-egg-bar {
  position: absolute; left: -4px; top: 50%; margin-top: -7px;
  height: 16px; width: calc(100% + 8px);
  background: #E0A53F; border-radius: 1.5px;
  transition: width 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
/* Retreats to a tick in the bar's own left overhang (left:-4px), so the phrase
   reads clean while a scrap of the censor bar stays behind. */
.foot-col a.foot-egg:hover .foot-egg-bar,
.foot-col a.foot-egg:focus-visible .foot-egg-bar { width: 5px; }
.foot-col a.foot-egg:hover .foot-egg-text,
.foot-col a.foot-egg:focus-visible .foot-egg-text { color: #E0A53F; }
@media (prefers-reduced-motion: reduce) {
  .foot-egg-bar, .foot-egg-text { transition: none; }
}

/* --------------------------------------------------------- page head (inner) */

.page-head { padding: 34px 0 26px; border-bottom: 1px solid var(--ink); }
.page-head h1 {
  font-family: var(--serif); font-weight: 600; font-size: 42px;
  letter-spacing: -0.01em; color: var(--ink); margin: 0 0 10px;
}
.page-head .standfirst {
  font-size: 19px; font-style: italic; color: var(--text-secondary);
  margin: 0; max-width: 68ch; line-height: 1.5;
}

/* ------------------------------------------------ organizations page (rows) */

/* A decision-support directory (DELTA-v13): what have you got to give, then the
 * nine organizations under their cause and its headline figure, then guidance
 * rather than a dead end. No filter row; every org is on the page. */

.page-head h1 em { font-style: italic; font-weight: 500; color: var(--article-red); }

.give-strip {
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  border: 1px solid var(--ink);
  margin: 26px 0 30px;
}
.give-cell { padding: 16px 20px; border-right: 1px solid var(--hairline); }
.give-cell:last-child { border-right: 0; }
.give-q {
  font-family: var(--serif); font-size: 20px; font-weight: 600;
  color: var(--ink); margin: 0 0 3px;
}
.give-q em { font-style: italic; color: var(--deep-green); }
.give-a {
  font-family: var(--sans); font-size: 13px; line-height: 1.45;
  color: var(--text-secondary); margin: 0;
}
.give-a a { font-weight: 600; }

.cause-head {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 8px;
  margin: 34px 0 2px;
}
.cause-head:first-child { margin-top: 0; }
.cause-kicker {
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--article-red);
}
.cause-count { font-family: var(--serif); font-size: 22px; font-weight: 600; color: var(--ink); }
.cause-spacer { flex: 1; }
.cause-stat { font-family: var(--sans); font-size: 11px; color: var(--text-secondary); }

/* The crawlable org list generated into #grid (audit B5). renderGrid() replaces it as
   soon as the directory paints, so this is only ever seen without JS or for the moment
   before the JSON lands. Styled as a plain readable list rather than hidden: hidden
   content is discounted by search engines, which would give back the whole point. */
.org-fallback { list-style: none; margin: 0; padding: 0; }
.org-fallback li {
  padding: 12px 0; border-bottom: 1px solid var(--panel-rule);
  font-family: var(--serif); font-size: 18px;
}
.org-fallback span {
  display: block; font-family: var(--sans); font-size: 12px; color: var(--text-secondary);
}

.org-row {
  display: grid; grid-template-columns: 1fr 250px; gap: 36px;
  padding: 22px 0;
  border-bottom: 1px solid var(--panel-rule);
}
.org-name { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.org-name h3 {
  font-family: var(--serif); font-weight: 600; font-size: 26px; margin: 0;
}
.org-name h3 a { color: var(--ink); }
.org-name h3 a:hover { color: var(--deep-green); }
.org-tag {
  font-family: var(--sans); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-secondary);
}
.org-mission {
  font-size: 16px; line-height: 1.55; color: var(--body-text);
  margin: 8px 0 10px; max-width: 64ch;
}
.org-doing {
  font-family: var(--sans); font-size: 13.5px; line-height: 1.5;
  color: var(--text-secondary); margin: 0;
}
.org-doing b { color: var(--text-tertiary); font-weight: 600; }

.org-rail {
  border-left: 3px solid var(--gold);
  padding-left: 18px;
  display: flex; flex-direction: column; justify-content: space-between; gap: 12px;
}
.org-stat {
  font-family: var(--serif); font-size: 24px; font-weight: 700;
  color: var(--deep-green); line-height: 1.1; margin: 0 0 6px;
}
.org-stat span {
  font-family: var(--sans); font-size: 12px; font-weight: 400;
  color: var(--text-secondary);
}
.org-rail .org-note { margin: 6px 0 0; }
.org-rail .ctas { gap: 8px; font-size: 12.5px; }
.org-rail .ctas .btn.donate,
.org-rail .ctas .btn.volunteer { padding: 8px 13px; }
.org-rail .ctas .btn.learn { margin-left: 0; padding: 8px 0; }

.org-closer {
  background: var(--panel-bg);
  border-top: 3px solid var(--avl-green);
  padding: 18px 22px;
  margin: 34px 0 0;
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
.closer-h { font-family: var(--serif); font-size: 20px; font-weight: 600; color: var(--ink); margin: 0 0 3px; }
.closer-p { font-family: var(--sans); font-size: 13.5px; line-height: 1.5; color: var(--text-secondary); margin: 0; max-width: 70ch; }
.org-closer .btn-outline { font-size: 13px; padding: 9px 16px; white-space: nowrap; }

.empty { padding: 40px 0; color: var(--text-secondary); font-style: italic; }

/* ----------------------------------------------------------------- news page */

/* Story-clustered digest (design bundle, DELTA-v11): two densities, geography
 * demoted to a tag, and one Context link per cluster into our own explainer. */

.news-updated {
  font-family: var(--sans); font-size: 12px; color: var(--text-secondary);
  margin: 0 0 18px;
}
.news-empty { font-family: var(--sans); font-size: 12px; color: var(--text-secondary); }

/* ------- if you read one thing */

.news-picks {
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 20px 0 22px;
  margin-bottom: 26px;
}
.picks-kicker {
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--article-red); margin: 0 0 14px;
}
.picks-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 32px; }
.pick { border-left: 3px solid var(--article-red); padding-left: 14px; }
.pick-h {
  display: block; font-family: var(--serif); font-size: 18px; font-weight: 600;
  line-height: 1.3; color: var(--ink); margin-bottom: 5px;
}
.pick-h:hover { color: var(--avl-green); }
.pick-ctx {
  font-family: var(--sans); font-size: 13px; line-height: 1.45;
  color: var(--text-secondary); margin: 0 0 6px;
}
.pick-meta {
  font-family: var(--sans); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-secondary); margin: 0;
}

/* ------- story clusters */

.news-clusters { display: grid; grid-template-columns: 1fr 1fr; gap: 0 48px; }
.cluster { margin-bottom: 30px; }
.cluster-head {
  display: flex; justify-content: space-between; align-items: baseline;
  border-bottom: 2px solid var(--ink); padding-bottom: 7px; margin-bottom: 4px;
}
.cluster-name {
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink);
}
.cluster-count { font-family: var(--sans); font-size: 10px; color: var(--text-secondary); }

.news-row { padding: 10px 0; border-bottom: 1px solid var(--panel-rule); }
.news-row.last { border-bottom: 0; }
.news-h {
  display: block; font-family: var(--serif); font-size: 15.5px;
  font-weight: 600; line-height: 1.35; color: var(--ink);
}
.news-h:hover { color: var(--avl-green); }
.news-meta {
  font-family: var(--sans); font-size: 10px; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-secondary); margin: 3px 0 0;
}
.news-meta .scope.local { color: var(--avl-green); }
.news-meta .scope.national { color: var(--text-secondary); }
.news-meta .scope.localmedia { color: var(--localmedia); font-weight: 600; }

.cluster-more { margin-top: 0; }
.cluster-more-toggle {
  display: block; background: none; border: 0; padding: 10px 0 0; cursor: pointer;
  font-family: var(--sans); font-size: 12px; font-weight: 700;
  letter-spacing: 0.04em; color: var(--avl-green); text-align: left;
}
.cluster-more-toggle:hover { text-decoration: underline; }

.cluster-ctx {
  display: inline-block; font-family: var(--sans); font-size: 12.5px;
  font-weight: 600; color: var(--avl-green); padding-top: 10px;
}

/* ------- earlier coverage */

.earlier-toggle {
  display: block; margin: 0 auto; max-width: 360px; width: 100%;
  background: none; border: 1px solid var(--avl-green); border-radius: 2px;
  color: var(--avl-green); font-family: var(--sans); font-size: 13px;
  font-weight: 600; padding: 13px; cursor: pointer;
}
.earlier-toggle:hover { background: var(--panel-bg); }

.earlier-panel { border-top: 2px solid var(--ink); padding-top: 10px; }
.earlier-label {
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-secondary); margin: 18px 0 4px;
}
.earlier-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 48px; }
.earlier-row { padding: 9px 0; border-bottom: 1px solid var(--panel-rule); }
.earlier-row a {
  font-family: var(--serif); font-size: 14.5px; font-weight: 600; color: var(--ink);
}
.earlier-row a:hover { color: var(--avl-green); }
.earlier-meta {
  font-family: var(--sans); font-size: 10px; text-transform: uppercase;
  color: var(--text-secondary);
}
.earlier-collapse {
  display: block; margin: 22px auto 0; background: none; border: 0; cursor: pointer;
  font-family: var(--sans); font-size: 13px; font-weight: 600; color: var(--avl-green);
}

/* --------------------------------------------------------------- issues page */

.learn-starts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px; padding: 28px 0;
}
.learn-start {
  display: block; background: var(--panel-bg-2);
  border: 1px solid #D5DCD4; border-top: 3px solid var(--avl-green);
  padding: 18px 20px; transition: border-color 0.15s ease;
}
.learn-start:hover { border-color: var(--avl-green); }
.ls-eyebrow {
  display: block; font-family: var(--sans); font-weight: 600; font-size: 10px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--avl-green);
}
.ls-title {
  display: block; font-family: var(--serif); font-weight: 600; font-size: 20px;
  color: var(--ink); line-height: 1.25; margin: 7px 0 5px;
}
.ls-sub { display: block; font-family: var(--sans); font-size: 13px; color: var(--text-secondary); }

.lf-search { padding-bottom: 14px; }
/* Card-cream fill + an ink-tertiary border lift the field off the paper page
 * (it used to be --paper on --paper behind a whisper hairline, all but invisible);
 * the inline magnifier reads it as a search box at a glance. */
.lf-search input {
  width: 100%; font-family: var(--sans); font-size: 14px; color: var(--ink);
  background: var(--card-bg) url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235C6B66' stroke-width='2' stroke-linecap='round'><circle cx='11' cy='11' r='7'/><line x1='21' y1='21' x2='16.65' y2='16.65'/></svg>") no-repeat 12px center;
  background-size: 15px 15px;
  border: 1px solid var(--text-tertiary);
  border-radius: 2px; padding: 10px 12px 10px 36px;
}
.lf-search input::placeholder { color: var(--text-secondary); opacity: 1; }
.lf-search input:focus { outline: 2px solid var(--avl-green); outline-offset: 1px; }
.lf-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.lf-label {
  font-family: var(--sans); font-size: 10.5px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--text-secondary); min-width: 60px;
}
.chip {
  font-family: var(--sans); font-size: 12px; font-weight: 600;
  background: none; border: 1px solid var(--hairline); border-radius: 2px;
  padding: 6px 12px; color: var(--ink); cursor: pointer;
}
.chip:hover { border-color: var(--avl-green); color: var(--avl-green); }
.chip.active { background: var(--avl-green); border-color: var(--avl-green); color: var(--paper); }
.chip-n { opacity: 0.7; margin-left: 4px; }
.lf-count {
  font-family: var(--sans); font-size: 11px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-secondary); margin: 8px 0 20px;
}

.resource-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 22px; padding-bottom: 20px;
}
.resource-card {
  background: var(--card-bg); border: 1px solid var(--panel-rule);
  border-top: 3px solid var(--avl-green);
  padding: 16px 18px 18px; cursor: pointer;
  transition: border-color 0.15s ease;
  display: flex; flex-direction: column;
}
.resource-card:hover { border-color: var(--avl-green); }
.rc-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.rc-topics { display: flex; gap: 6px; }
.rc-topic {
  font-family: var(--sans); font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-secondary);
}
.rc-format {
  font-family: var(--sans); font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-text);
}
.resource-card h3 { margin: 8px 0; }
.rc-title {
  font-family: var(--serif); font-weight: 600; font-size: 19px;
  color: var(--ink); line-height: 1.28;
}
.resource-card:hover .rc-title { color: var(--avl-green); }
.resource-card p { font-size: 13.5px; line-height: 1.55; color: var(--text-secondary); margin: 0 0 8px; }
.rc-snippet mark { background: var(--callout-tint); color: var(--ink); }
.rc-date {
  font-family: var(--sans); font-size: 10.5px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--text-secondary); margin-bottom: 10px;
}
.rc-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: auto; padding-top: 8px;
}
.rc-open, .rc-pdf {
  font-family: var(--sans); font-size: 12px; font-weight: 600;
  letter-spacing: 0.04em; color: var(--avl-green);
}

/* the collapsible library map keeps its own compact styling */
.learn-map { border: 1px solid var(--panel-rule); background: var(--card-bg); margin: 0 0 26px; }
.learn-map > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px;
  padding: 14px 18px; font-family: var(--sans); font-weight: 600; font-size: 13px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink);
}
.learn-map > summary::-webkit-details-marker { display: none; }
.learn-map .lm-count { margin-left: auto; letter-spacing: 0.04em; text-transform: none;
  font-weight: 400; color: var(--text-secondary); }
.learn-map .lm-chev { flex: none; transition: transform 0.2s; color: var(--text-secondary); }
.learn-map[open] > summary .lm-chev { transform: rotate(90deg); }
.learn-map[open] > summary { border-bottom: 1px solid var(--panel-rule); }
.lm-body { padding: 4px 14px 10px; }
.lm-branch { border-bottom: 1px solid var(--panel-rule); }
.lm-branch:last-child { border-bottom: 0; }
.lm-branch > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 10px;
  padding: 11px 6px; font-family: var(--serif); font-weight: 600; font-size: 17px; color: var(--ink);
}
.lm-branch > summary::-webkit-details-marker { display: none; }
.lm-branch > summary:hover { color: var(--avl-green); }
.lm-dot { width: 10px; height: 10px; flex: none; }
.lm-btot { margin-left: auto; font-family: var(--sans); font-size: 12px;
  color: var(--text-secondary); font-weight: 400; }
.lm-bchev { flex: none; color: var(--text-secondary); transition: transform 0.2s; }
.lm-branch[open] > summary .lm-bchev { transform: rotate(90deg); }
.lm-sub {
  font-family: var(--sans); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--text-secondary); margin: 12px 0 4px 22px;
}
.lm-link {
  display: flex; align-items: baseline; gap: 8px; padding: 6px 10px 6px 22px;
  border-left: 2px solid transparent; color: var(--ink);
}
.lm-link:hover, .lm-link:focus-visible {
  background: var(--panel-bg-2); color: var(--avl-green);
  border-left-color: var(--avl-green); outline: none;
}
.lm-name { font-size: 15px; line-height: 1.3; }
.lm-role { font-family: var(--sans); font-size: 12px; color: var(--text-secondary); }

.issue-groups {
  display: grid; grid-template-columns: 1fr 1fr; gap: 34px; padding: 8px 0 28px;
}

/* ---------------------------------------------------- quiz: test what you know */

/* v8 "feature box": a full-width newspaper panel between the org spotlight and
 * the Start here / WNC Desk row. Spec: DELTA-v8-quiz.md. */

.quiz { padding: 30px 0 34px; border-bottom: 1px solid var(--ink); }
.quiz-box { border: 1px solid var(--ink); background: var(--paper); }

/* ------- header band */

.quiz-band {
  border-bottom: 3px double var(--ink);
  padding: 22px 30px 18px;
  text-align: center;
}
.quiz-crest {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin-bottom: 12px;
}
.quiz-crest .rule { flex: 1; max-width: 120px; height: 1px; background: var(--hairline); }
/* The mark again, at the compact scale. Geometry is the shared .brand-mark,
 * .quiz-mark base rule above; here we only set the unit. */
.quiz-mark { --u: 5px; }
.quiz-band h2 {
  font-family: var(--serif); font-weight: 600; font-size: 32px;
  line-height: 1.15; letter-spacing: -0.01em; color: var(--ink); margin: 0 0 8px;
}
.quiz-band h2 em { font-style: italic; font-weight: 500; color: var(--article-red); }
.quiz-band p {
  font-family: var(--serif); font-style: italic; font-size: 16px;
  color: var(--text-secondary); margin: 0;
}

/* ------- body: 2 columns */

.quiz-body { display: grid; grid-template-columns: 1fr 340px; }
.quiz-ask { padding: 26px 34px 30px; border-right: 1px solid var(--hairline); }
.quiz-side {
  background: var(--card-bg); padding: 26px 30px 30px;
  display: flex; flex-direction: column; justify-content: space-between; gap: 20px;
}

.quiz-eyebrow {
  font-family: var(--sans); font-size: 11px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--avl-green);
  margin: 0 0 12px;
}
.quiz-q {
  font-family: var(--serif); font-weight: 500; font-size: 25px; line-height: 1.25;
  color: var(--ink); margin: 0 0 22px; text-wrap: pretty;
}

/* ------- guessing state */

.quiz-slider { width: 100%; margin: 6px 0 8px; accent-color: var(--avl-green); }
.quiz-range-lbls {
  display: flex; justify-content: space-between;
  font-family: var(--sans); font-size: 11.5px; color: var(--text-secondary);
}
.quiz-readout {
  font-family: var(--serif); color: var(--deep-green); text-align: center;
  line-height: 1.05;
}
.quiz-readout .qr-pre { font-size: 22px; }
.quiz-readout .qr-num { font-size: 52px; font-weight: 700; }
.quiz-readout .qr-suf { font-size: 18px; }
.quiz-readout-lbl {
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--avl-green);
  text-align: center; max-width: 200px; margin: 12px auto 0;
  padding-bottom: 8px; border-bottom: 2px solid var(--gold);
}

/* ------- revealed state: guess vs. real, on one scale */

.quiz-bars { margin: 4px 0 0; }
.quiz-bar + .quiz-bar { margin-top: 18px; }
.quiz-bar-top {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; margin-bottom: 6px;
}
.quiz-bar-lbl {
  font-family: var(--sans); font-size: 11px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-secondary);
}
.quiz-bar-val { font-family: var(--sans); font-weight: 700; color: var(--text-tertiary); }
.quiz-bar-track { height: 16px; background: var(--panel-bg); }
.quiz-bar-fill { height: 100%; background: #8C9B93; }
.quiz-bar.real .quiz-bar-lbl { font-weight: 700; color: var(--article-red); }
.quiz-bar.real .quiz-bar-val {
  font-family: var(--serif); font-weight: 700; font-size: 16px; color: var(--article-red);
}
.quiz-bar.real .quiz-bar-fill { background: var(--article-red); }
.quiz-verdict {
  font-family: var(--serif); font-style: italic; font-size: 15.5px;
  color: var(--text-tertiary); margin: 20px 0 0;
}

/* ------- flip cards (no slider): the answer carries the reveal */

.quiz-answer {
  font-family: var(--serif); font-weight: 700; font-size: 44px; line-height: 1;
  color: var(--article-red); margin: 0;
}

/* ------- side column, revealed */

.quiz-note { font-family: var(--serif); font-size: 15px; line-height: 1.55; color: var(--body-text); margin: 0; }
.quiz-source { font-family: var(--sans); font-size: 10.5px; line-height: 1.5; color: var(--text-secondary); margin: 12px 0 0; }
.quiz-story { font-family: var(--sans); font-size: 12px; font-weight: 600; display: inline-block; margin-top: 10px; }

/* ------- buttons */

.quiz-reveal, .quiz-next {
  font-family: var(--sans); font-size: 14px; font-weight: 600; cursor: pointer;
  border-radius: 2px; padding: 14px; width: 100%;
}
.quiz-reveal { background: var(--avl-green); color: var(--paper); border: 0; }
.quiz-reveal:hover { background: var(--deep-green); }
.quiz-next {
  background: none; color: var(--avl-green); border: 1px solid var(--avl-green);
}
.quiz-next:hover { background: var(--panel-bg); }

@media (max-width: 760px) {
  .quiz-body { grid-template-columns: 1fr; }
  .quiz-ask { border-right: 0; border-bottom: 1px solid var(--hairline); padding: 22px 20px 26px; }
  .quiz-side { padding: 22px 20px 26px; }
  .quiz-band { padding: 20px 18px 16px; }
  .quiz-band h2 { font-size: 26px; }
  .quiz-q { font-size: 21px; }
}

/* --------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  .lead:has(> .lead-main) { grid-template-columns: 1fr; }
  .lead-main { border-right: 0; border-bottom: 1px solid var(--hairline); padding: 28px 0; }
  .lead-side { padding: 28px 0; }
  .home-duo { grid-template-columns: 1fr; gap: 30px; }
  .picks-grid { grid-template-columns: 1fr; gap: 20px; }
  .news-clusters { grid-template-columns: 1fr; }
  .earlier-grid { grid-template-columns: 1fr; }
  .issue-groups { grid-template-columns: 1fr; }
  .site-foot .wrap { grid-template-columns: 1fr 1fr; }
  .give-strip { grid-template-columns: 1fr; }
  .give-cell { border-right: 0; border-bottom: 1px solid var(--hairline); }
  .give-cell:last-child { border-bottom: 0; }
  .org-row { grid-template-columns: 1fr; gap: 18px; }
  .org-rail { border-left: 0; border-top: 3px solid var(--gold); padding: 14px 0 0; }
}

@media (max-width: 760px) {
  .wrap { padding: 0 18px; }
  /* Phone masthead: nameplate, motto, then the follow row. The markup order is
   * follow / brand / action, so reorder rather than rewrite the HTML.
   * :not(.compact) throughout: the inner-page header has no motto and no follow
   * row, and its markup runs brand / nav. Giving its lockup an order pushed the
   * logo BELOW the nav on every inner page. Scope, or it reorders that too. */
  .masthead:not(.compact) .wrap {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: 0;
  }
  /* 1F at phone scale, against the 42px wordmark. */
  .masthead:not(.compact) .brand-lockup { order: 1; gap: 9px; }
  .masthead:not(.compact) .brand-lockup .brand-mark { --u: 6px; }
  .masthead-motto { order: 2; font-size: 13.5px; line-height: 1.45; max-width: 300px; }
  /* The row loses its "Follow along" label here and becomes three centred links. */
  .mast-follow { order: 3; margin-top: 8px; font-size: 12px; letter-spacing: 0; }
  .mast-follow .follow-label { display: none; }
  .mast-follow a { margin: 0 8px; text-transform: none; font-weight: 600; }
  .mast-action { justify-self: start; }
  .wordmark { font-size: 42px; }
  .navrule .wrap { gap: 10px 0; }
  .navrule .dot { margin: 0 8px; }
  .page-head h1 { font-size: 33px; }
  .lead-main h1 { font-size: 30px; }
  .site-foot .wrap { grid-template-columns: 1fr; gap: 26px; }
  /* The brand and the nav stack here, so the row gap and padding are what make a
   * sticky header tall. Trim both. */
  /* Brand over nav, both centred on the column, so the sticky header reads as one
   * centred stack rather than two left-ragged rows. */
  .masthead.compact .wrap {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 10px;
    padding-top: 12px;
    padding-bottom: 10px;
  }
  /* Four labels on one line at 375px: tighten the gap and the tracking. */
  .masthead.compact .inner-nav { justify-self: center; justify-content: center; gap: 11px; }
  .masthead.compact .inner-nav a { letter-spacing: 0.07em; }
  /* The filled "Use my research" button wrapped the inner nav onto a second row,
   * which made a sticky header a third of a phone screen tall. Drop it here: the
   * footer's Explore column carries the link on every page, and every article
   * already offers the research block below its CTA. */
  .masthead.compact .inner-nav .btn-solid { display: none; }
}

/* The trust strip's two links wrap mid-phrase on a phone, which reads as one
 * ragged sentence. Earlier this stacked each item on its own line, which cost
 * three lines above the masthead. Instead: one centred line that wraps between
 * items, each link unbreakable, dots kept as the separators. The location tag
 * goes: it clips at 390px and the masthead motto now names the region anyway. */
@media (max-width: 640px) {
  .trust { font-size: 10px; letter-spacing: 0.1em; }
  .trust .wrap {
    justify-content: center;
    text-align: center;
    gap: 4px 7px;
  }
  .trust .wrap > div:first-child { display: contents; }
  .trust .wrap > div:last-child { display: none; }
  .trust a { white-space: nowrap; }
  .trust-sep { margin: 0; }
}

/* --------------------------------------------- homepage research tail (mobile) */

/* Desktop keeps the masthead button; this block only exists for phones. */
.research-tail { display: none; }

/* ------------------------------------------------- mobile legibility floor */

/* The Broadsheet's labels are small caps at 9.5-11px with wide tracking. That
 * reads on a desktop sheet and goes faint on a phone. Below 760px every label
 * comes up to at least 11.5px and the tracking eases; nothing else moves. */
@media (max-width: 760px) {
  /* The masthead's filled button wrapped the homepage header; the link moves to
     the tail of the page, below Featured reads. */
  .mast-action { display: none; }
  .research-tail {
    display: block;
    text-align: center;
    border-top: 1px solid var(--hairline);
    padding: 26px 0 34px;
  }
  .research-tail .cap {
    font-family: var(--sans);
    font-size: 12.5px;
    color: var(--text-secondary);
    margin: 0 0 14px;
  }

  .trust { font-size: 11px; letter-spacing: 0.08em; }
  .start-card .e { font-size: 11.5px; letter-spacing: 0.08em; }
  .pick-meta, .cluster-count, .news-meta, .earlier-meta { font-size: 11.5px; letter-spacing: 0.03em; }
  .picks-kicker { font-size: 12px; }
  .ls-eyebrow { font-size: 11.5px; letter-spacing: 0.08em; }
  .lf-label, .lm-sub { font-size: 11.5px; }
  .rc-topic, .rc-format { font-size: 11px; letter-spacing: 0.08em; }
  .rc-date { font-size: 11.5px; }
  .lead-side p.lead-note { font-size: 11.5px; }
  .org-note { font-size: 11.5px; letter-spacing: 0.03em; }
  .org-tag { font-size: 11.5px; letter-spacing: 0.06em; }
  .head-sub { font-size: 12px; }
  .desk-card .jur { font-size: 11px; letter-spacing: 0.1em; }
  .read-card .rk { font-size: 11px; letter-spacing: 0.1em; }
  .cause-stat { font-size: 12px; }
  .follow-label, .reads-count { font-size: 12px; }
  .foot-col h3 { font-size: 11.5px; }
  .foot-legal { font-size: 12.5px; }
}

/* Article byline strip -- canonical across every files/ article (2026-07-12).
   Replaced the two drifted per-article inline bylines (old "By ... <a>" kicker
   form + new uppercased plain form). Reads the article-local warm palette vars
   (--rust/--rule/--ink), with Broadsheet fallbacks for any sheet that lacks one.
   Layout: brand mark + uppercase "BY <NAME> ·" left, rust site link right,
   rust rule above, grey hairline below. The .brand-mark geometry is the shared
   block up top; only --u (bar unit) is overridden here for the small strip. */
.article-byline {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  margin: 26px 0 0; padding: 11px 0;
  border-top: 2px solid var(--rust, #AB422D);
  border-bottom: 1px solid var(--rule, #c9bda6);
  font-family: "Archivo", system-ui, sans-serif;
}
.article-byline .by {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 12px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink, #221d17);
}
.article-byline .brand-mark { --u: 3px; }
.article-byline a {
  font-size: 12px; font-weight: 700; letter-spacing: 0.06em;
  color: var(--rust, #AB422D); text-decoration: none;
}
.article-byline a:hover { text-decoration: underline; }

/* ---------------------------------------------------------- CLS reservations
   app.js fills these regions after data/*.json arrives. Empty at first paint,
   they occupy nothing, so when they fill everything below them jumps: measured
   2026-07-28, the footer moved 414px on news and 751px on issues, and the
   homepage spotlight section moved 663px.

   Heights are MEASURED, not guessed, from the rendered mounts at 375 and 1280
   (scratch script mount-heights.py). They will drift as content volume changes:
   more news items, more library cards. A reservation that is too small leaves
   part of the shift; too large leaves a gap under the section. Re-measure after
   any large content change.

   The two mounts that ship `hidden` (#quiz, #news-picks) cannot be reserved this
   way, because display:none takes them out of layout entirely. They still shift
   on reveal. The real fix for all of this is to stop fetching what the build
   already knows: inline the JSON as a script island and render before first
   paint, which removes the blank space as well as the shift.

   Each value is the SMALLEST height its mount takes anywhere in that width band,
   never the average and never the height at one convenient viewport. Overshoot and
   undershoot are not symmetric: reserving too little leaves part of the shift, and
   that is the failure we are already living with, but reserving too much leaves a
   permanently empty strip under the section that no CLS number will ever report.
   A first cut sized #spotlight at its 375px height, 737px, and opened a 370px hole
   at 759px, where the duo has gone two-up and needs 367. Bands are set at the real
   layout breaks: .spotlight-duo is auto-fit minmax(320px, 1fr), so it turns two-up
   near 716px, not at the site's 760px. */
#spotlight:empty       { min-height: 294px; }
#featured-reads:empty  { min-height: 219px; }
#learn-filters:empty   { min-height: 139px; }
#resource-grid:empty   { min-height: 552px; }
#news-clusters:empty   { min-height: 1659px; }
/* :empty, not a plain rule: this one is the section itself, so the reservation has
   to disappear the moment it has content or it would set a floor under the rendered
   card too. app.js sets hidden on every path that renders nothing.

   Deliberately UNDER-sized. The deck is shuffled on every load, so the height here
   depends on which of the seven cards is drawn as well as on width (386-421px at
   1280, 557-634px below 760px). Reserving the tallest would make the page shrink
   when a short card lands, and a reservation that overshoots buys an upward shift
   instead of preventing a downward one. Reserve the floor and accept the remainder. */
#quiz:empty      { min-height: 380px; }
#news-picks:empty { min-height: 238px; }

@media (max-width: 1100px) {
  #featured-reads:empty { min-height: 264px; }
  #resource-grid:empty  { min-height: 629px; }
  #news-clusters:empty  { min-height: 1722px; }
}
@media (max-width: 900px) {
  #news-clusters:empty  { min-height: 2669px; }
}
@media (max-width: 700px) {
  #spotlight:empty      { min-height: 550px; }
}
@media (max-width: 760px) {
  #quiz:empty     { min-height: 550px; }
  #news-picks:empty { min-height: 327px; }
  #featured-reads:empty { min-height: 638px; }
  #resource-grid:empty  { min-height: 1612px; }
  #news-clusters:empty  { min-height: 3502px; }
}
@media (max-width: 430px) {
  #spotlight:empty      { min-height: 737px; }
}
@media (max-width: 380px) {
  #news-picks:empty     { min-height: 554px; }
}

/* ---------------------------------------------------------------- SNAP series badge
   The homepage pointer at /snap, in the lead column under the two lead buttons.
   Design note (2026-08-08): the number leads and the number MOVES -- it is stamped
   every build from the caseload feed by seo-build's inject_snap_trend, so this badge
   does not go stale the week the news does, which is the failure mode of a "new series"
   banner. The dashed rust rule is the only dashed border on the site: it is what makes a
   small element read as pinned on rather than laid out. */
.snap-bull {
  display: flex; align-items: center; gap: 16px; margin: 20px 0 0;
  background: var(--callout-tint);
  border: 2px dashed var(--article-red); border-radius: 3px;
  padding: 12px 16px; font-family: var(--sans);
  transition: background 0.15s ease;
}
.snap-bull:hover { background: var(--cta-cream); }
.sb-tag {
  flex: none; align-self: flex-start;
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-text);
}
.sb-num {
  flex: none; font-family: var(--serif); font-size: 33px; font-weight: 700;
  line-height: 1; color: var(--article-red);
}
.sb-txt { flex: 1 1 auto; font-size: 14px; line-height: 1.45; color: var(--body-text); }
.sb-txt b { color: var(--ink); }
.sb-go {
  white-space: nowrap; font-weight: 700; font-size: 11.5px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--article-red);
  border-bottom: 2px solid var(--gold); padding-bottom: 1px;
}
@media (max-width: 760px) {
  /* The eyebrow takes its own row and the number sits beside the sentence, so the
     badge stays two lines instead of four on a phone. */
  .snap-bull { flex-wrap: wrap; gap: 4px 12px; padding: 12px 14px; }
  .sb-num { font-size: 28px; }
  .sb-tag { order: -1; flex: 1 1 100%; }
}
@media (prefers-reduced-motion: reduce) { .snap-bull { transition: none; } }
