/* ==========================================================================
   FISCAL ALLIANCE FOUNDATION — DESIGN SYSTEM
   "The Ledger" — an editorial, data-forward system for a policy foundation
   that is equal parts newsroom, research library, and advocacy engine.

   Every block below maps to a Strapi component. See README.md.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */
:root {
  /* ── FAF established palette ──────────────────────────────────────────
     Taken from the Foundation's existing white-paper system (and matching
     faf-design-tokens.yml). These are not new colors — the site now speaks
     the same language as the published studies and email templates. */
  --blue:        #1479BF;   /* faf-blue     — primary, from the logo */
  --blue-dk:     #0D5A93;   /* faf-dark                              */
  --blue-dp:     #093D63;   /* faf-deeper   — dark surfaces          */
  --blue-lt:     #E8F4FD;   /* faf-light                             */
  --blue-pale:   #A8D0EA;   /* faf-pale                              */
  --accent:      #5BAEE0;   /* faf-accent   — highlight on dark      */

  /* Text */
  --ink:         #0F1A2E;   /* text-dark  */
  --ink-2:       #2C3E50;   /* text-mid   */
  --ink-3:       #4A5D74;   /* interpolated step */
  --ink-4:       #6B7A90;   /* text-light */

  /* Dark surface. FAF's deep blue rather than a near-black — it keeps the
     logo sitting naturally on hero, footer, and CTA bands. */
  --surface:     #093D63;
  --surface-dp:  #06283F;   /* deeper step for layering within dark areas */

  /* Paper — cool, matching gray-light in the established system */
  --paper:       #F4F7FC;
  --paper-2:     #E9EFF7;
  --paper-3:     #D9E3EF;
  --white:       #FFFFFF;

  /* Signal — the established alert red. Reserved for giving + urgency,
     the one warm note against an otherwise blue field. */
  --signal:      #B23A32;
  --signal-dk:   #8F2E27;
  --signal-lt:   #FBEDEC;

  /* Chapter theming. Overridden by [data-chapter] — one token swap
     re-skins every chapter surface on the page. */
  --chapter:     var(--blue);
  --chapter-dk:  var(--blue-dk);
  --chapter-lt:  var(--blue-lt);
  --chapter-ink: var(--surface-dp);

  /* Lines — derived from faf-deeper, as in the established system */
  --line:        rgba(9, 61, 99, .12);
  --line-2:      rgba(9, 61, 99, .26);
  --line-inv:    rgba(255, 255, 255, .18);

  /* Type */
  --f-display: "Newsreader", "Iowan Old Style", Georgia, serif;
  --f-sans:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --f-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Fluid type scale.
     Every size is rem-based so it tracks the reader's own browser font-size
     setting — never px, which ignores it. The small end carries a gentle vw
     term so micro-labels stay legible on a phone and don't look undersized on
     a large display; the top end scales harder. */
  --t-3xs:  clamp(0.5625rem, 0.06vw + 0.548rem, 0.625rem);   /*  9 → 10px */
  --t-2xs:  clamp(0.625rem,  0.08vw + 0.605rem, 0.6875rem);  /* 10 → 11px */
  --t-xs:   clamp(0.75rem,   0.10vw + 0.725rem, 0.8125rem);  /* 12 → 13px */
  --t-sm:   clamp(0.8125rem, 0.10vw + 0.788rem, 0.875rem);   /* 13 → 14px */
  --t-base: 1rem;
  --t-lg:   clamp(1rem,      0.15vw + 0.963rem, 1.0625rem);  /* 16 → 17px */
  --t-xl:   clamp(1.125rem, 0.4vw + 1.03rem, 1.3125rem);
  --t-h4:   clamp(1.25rem, 0.6vw + 1.11rem, 1.5rem);
  --t-h3:   clamp(1.5rem, 1.1vw + 1.24rem, 2.125rem);
  --t-h2:   clamp(1.875rem, 2.2vw + 1.35rem, 3rem);
  --t-h1:   clamp(2.25rem, 4.4vw + 1.2rem, 4.25rem);
  --t-mega: clamp(2.75rem, 7vw + 0.8rem, 6rem);

  /* Header. The stuck height is the anchor for every sticky offset below it —
     the library filter bars, the article rail, and scroll-padding for hash
     links — so it lives here rather than being repeated as a magic number. */
  --logo:       92px;
  --logo-stuck: 66px;
  --hdr-h:       112px;
  --hdr-h-stuck: 84px;

  /* Space */
  --gut:  clamp(1.25rem, 3.5vw, 2.5rem);
  --sec:  clamp(3.5rem, 8vw, 7rem);
  --max:  1280px;
  --measure: 68ch;

  /* Motion */
  --ease: cubic-bezier(.22, .68, .28, 1);
  --dur: .5s;

  --radius: 4px;
  --shadow: 0 1px 2px rgba(9,61,99,.05), 0 8px 24px -12px rgba(9,61,99,.18);
  --shadow-lg: 0 2px 4px rgba(9,61,99,.06), 0 24px 48px -20px rgba(9,61,99,.26);
}

/* Vermont chapter theme — Green Mountain green. The chapter reads as its
   own entity while the FAF blue persists in the network bar + footer. */
[data-chapter="vermont"] {
  --chapter:      var(--blue);
  --chapter-dk:   var(--blue-dk);
  --chapter-lt:   var(--blue-lt);
  --chapter-ink:  var(--surface-dp);
  --chapter-hero: var(--surface);   /* standard deep blue, as on the national hero */
}
[data-chapter="massachusetts"] {
  --chapter:     #0D5A93;
  --chapter-dk:  #093D63;
  --chapter-lt:  #E8F4FD;
  --chapter-ink: #06283F;
}

/* --------------------------------------------------------------------------
   2. RESET + BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--hdr-h-stuck) + 34px);
  /* Reserve the scrollbar track permanently. Three things here lock scrolling
     — the drawer, the lightbox, and the bio modal — and without a stable
     gutter each one widens the page by the scrollbar and shunts it sideways. */
  scrollbar-gutter: stable;
}

body {
  font-family: var(--f-sans);
  font-size: var(--t-lg);
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  font-feature-settings: "kern", "liga", "cv11";
}

img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

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

h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.018em;
  text-wrap: balance;
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); line-height: 1.25; }

p { text-wrap: pretty; }

::selection { background: var(--chapter); color: #fff; }

:focus-visible {
  outline: 2.5px solid var(--signal);
  outline-offset: 3px;
  border-radius: 2px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: var(--gut); top: -100px; z-index: 999;
  background: var(--surface); color: #fff; padding: .75rem 1.25rem;
  font: 600 var(--t-sm)/1 var(--f-sans); border-radius: var(--radius);
  transition: top .2s;
}
.skip:focus { top: .75rem; }

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gut);
}
.wrap--narrow { max-width: 980px; }
.wrap--text   { max-width: 760px; }

.section { padding-block: var(--sec); }

/* --- Section separation -------------------------------------------------
   The two paper tones sit close together on purpose, but stacked without an
   edge the page reads as one continuous field. Three devices fix that, in
   ascending strength: a hairline at every junction, a struck rule that starts
   each heading, and one dark band to break the run of light sections. */

/* A hairline at every section junction. Where the tone flips to or from ink,
   the contrast is already absolute and a rule would only muddy the edge. */
main > .section + .section,
main > .section + .ctaband { border-top: 1px solid var(--line); }
main > .section--ink + .section,
main > .section + .section--ink,
main > .section--ink + .ctaband { border-top-color: transparent; }

/* Struck rule + heading block. This is `shared.section-header` in Strapi: it
   marks where a section begins without adding a word of explanatory copy. */
.sechead { max-width: 42rem; margin-bottom: clamp(2rem, 4vw, 3rem); }
.sechead--row {
  max-width: none; display: flex; align-items: flex-end;
  justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
}
/* The mark is painted as a gradient rather than a sized box so the flex variant
   can span a whole flex row — forcing the heading onto the next line — while
   still showing only a 2.75rem stroke. One paint rule serves both variants. */
.sechead::before {
  content: ""; display: block; width: 2.75rem; height: 3px;
  margin-bottom: clamp(1.1rem, 2vw, 1.6rem);
  background: linear-gradient(to right, var(--sechead-mark, var(--chapter)) 0 2.75rem, transparent 2.75rem);
}
.sechead--row::before { flex-basis: 100%; width: 100%; }
.section--ink { --sechead-mark: var(--accent); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }

.section--ink   { background: var(--surface); color: var(--paper); }
.section--paper2{ background: var(--paper-2); }
.section--chapter { background: var(--chapter); color: #fff; }

.section--ink h1, .section--ink h2, .section--ink h3 { color: #fff; }

/* Content + sidebar. Wider than the article rail — sized for a form. */
.split { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
@media (min-width: 960px) {
  .split { grid-template-columns: minmax(0, 1fr) 380px; }
  .split--center { align-items: center; }
}

/* Grid helpers */
.grid { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); }
.g-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.g-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); }
.g-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

/* --------------------------------------------------------------------------
   4. TYPE UTILITIES
   -------------------------------------------------------------------------- */

/* The "ledger" voice — mono, uppercase, tracked. Used for every eyebrow,
   metadata line, stat label, and taxonomy tag across the site. */
.eyebrow {
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--chapter);
  display: flex;
  align-items: center;
  gap: .75rem;
  margin-bottom: 1.25rem;
}
.eyebrow::after {
  content: "";
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: .3;
  max-width: 80px;
}
.eyebrow--center { justify-content: center; }
.eyebrow--center::before {
  content: ""; flex: 1; height: 1px; background: currentColor;
  opacity: .3; max-width: 80px;
}
.eyebrow--plain { display: inline-block; margin-bottom: .75rem; }
.eyebrow--plain::after { display: none; }
.section--ink .eyebrow { color: var(--accent); }

.lede {
  font-size: clamp(1.125rem, 1vw + .95rem, 1.375rem);
  line-height: 1.55;
  color: var(--ink-2);
  max-width: var(--measure);
}
.section--ink .lede { color: rgba(255,255,255,.78); }

.meta {
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  letter-spacing: .06em;
  color: var(--ink-4);
  text-transform: uppercase;
}

.serif-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

/* --------------------------------------------------------------------------
   5. BUTTONS  →  Strapi: shared.cta-button
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  min-height: 48px;
  padding: .8rem 1.5rem;
  font-family: var(--f-sans);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: .01em;
  border-radius: var(--radius);
  border: 1.5px solid transparent;
  transition: background .25s var(--ease), color .25s var(--ease),
              border-color .25s var(--ease), transform .25s var(--ease);
  will-change: transform;
  text-align: center;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--primary { background: var(--chapter); color: #fff; }
.btn--primary:hover { background: var(--chapter-dk); }

.btn--give { background: var(--signal); color: #fff; }
.btn--give:hover { background: var(--signal-dk); }

.btn--ghost { border-color: var(--line-2); color: var(--ink); }
.btn--ghost:hover { border-color: var(--surface); background: var(--surface); color: var(--paper); }

.btn--inv { border-color: rgba(255,255,255,.4); color: #fff; }
.btn--inv:hover { background: #fff; color: var(--ink); border-color: #fff; }

.btn--solid-inv { background: #fff; color: var(--ink); }
.btn--solid-inv:hover { background: var(--paper-2); }

.btn--lg { min-height: 56px; padding: 1rem 2rem; font-size: var(--t-base); }
.btn--block { width: 100%; }

/* Arrow-link: the quiet tertiary action */
.alink {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--t-sm); font-weight: 600; color: var(--chapter);
  padding-block: .35rem;
}
.alink svg { transition: transform .3s var(--ease); flex: none; }
.alink:hover svg { transform: translateX(4px); }
.section--ink .alink { color: var(--accent); }

/* --------------------------------------------------------------------------
   6. ANNOUNCEMENT BAR  →  Strapi: global.announcementBar
   -------------------------------------------------------------------------- */
.announce {
  background: var(--surface);
  color: #fff;
  font-size: var(--t-sm);
  position: relative;
  z-index: 60;
}
.announce--urgent { background: var(--signal-dk); }
.announce__in {
  display: flex; align-items: center; gap: 1rem;
  min-height: 46px; padding-block: .5rem;
}
.announce__tag {
  font-family: var(--f-mono); font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  background: rgba(255,255,255,.16); padding: .3rem .5rem; border-radius: 3px;
  flex: none;
}
.announce__msg { flex: 1; min-width: 0; }
.announce__msg a { text-decoration: underline; text-underline-offset: 3px; font-weight: 600; }

/* Rotating headline bar. Only one item carries .is-on, so with scripting off
   the first is the whole bar and the rest never render — the markup degrades
   to exactly the single-message bar this replaced. */
.announce__item { display: none; }
.announce__item.is-on { display: inline; animation: annfade .5s var(--ease) both; }
.announce__item a { text-decoration: none; }
.announce__item a:hover .announce__ttl { text-decoration: underline; text-underline-offset: 3px; }
.announce__kind {
  font-family: var(--f-mono); font-size: var(--t-2xs); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; opacity: .66;
  margin-right: .5rem; white-space: nowrap;
}
.announce__go { opacity: .7; margin-left: .3rem; }
@keyframes annfade { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .announce__item.is-on { animation: none; }
}
.announce__x {
  flex: none; width: 32px; height: 32px; display: grid; place-items: center;
  border-radius: 50%; opacity: .7; transition: .2s;
}
.announce__x:hover { opacity: 1; background: rgba(255,255,255,.12); }

/* --------------------------------------------------------------------------
   7. HEADER  →  Strapi: global.primaryNav
   -------------------------------------------------------------------------- */
/* Phones give up a lot of a short viewport to persistent chrome, so the mark
   grows less there than on desktop — still larger than before, 12px cheaper.
   Every sticky offset reads the same tokens, so this needs no other edits. */
@media (max-width: 640px) {
  :root { --logo: 80px; --logo-stuck: 60px; --hdr-h: 100px; --hdr-h-stuck: 78px; }
}

.hdr {
  position: sticky; top: 0; z-index: 50;
  background: rgba(244,247,252,.88);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .3s, background .3s;
}
.hdr.is-stuck { box-shadow: 0 1px 20px rgba(10,26,43,.09); }

.hdr__in {
  display: flex; align-items: center; gap: 1rem;
  min-height: var(--hdr-h);
  transition: min-height .28s var(--ease);
}
/* Condensed once scrolled: the logo is large on arrival, then gets out of the
   way. This is what buys the extra size without a permanently bulky bar. */
.hdr.is-stuck .hdr__in { min-height: var(--hdr-h-stuck); }

/* — Logo lockup. The roundel already carries the wordmark, so no adjacent
     text is set; on a chapter page it grows a chapter tag. — */
.lockup { display: flex; align-items: center; gap: .85rem; flex: none; }
.lockup__mark {
  width: var(--logo); height: var(--logo); flex: none; border-radius: 50%;
  transition: width .28s var(--ease), height .28s var(--ease);
}
.hdr.is-stuck .lockup__mark { width: var(--logo-stuck); height: var(--logo-stuck); }
.lockup__rule { width: 1px; height: 40px; background: var(--line-2); }
.lockup__chapter {
  font-family: var(--f-display); font-size: 1.5rem; line-height: 1;
  color: var(--chapter); letter-spacing: -.02em;
}

/* — Primary nav — */
.nav { display: none; margin-left: auto; }
.nav__list { display: flex; align-items: center; gap: .25rem; list-style: none; padding: 0; }
.nav__link {
  display: flex; align-items: center; gap: .35rem;
  padding: .55rem .6rem; font-size: .9375rem; font-weight: 500;
  border-radius: var(--radius); transition: background .2s, color .2s;
  white-space: nowrap;
}
.nav__link:hover, .nav__item.is-open .nav__link { background: var(--paper-2); color: var(--chapter); }
.nav__link[aria-current="page"] { color: var(--chapter); font-weight: 600; }
.nav__link svg { transition: transform .25s var(--ease); opacity: .5; }
.nav__item.is-open .nav__link svg { transform: rotate(180deg); }

.nav__item { position: relative; }

/* Dropdown */
.drop {
  position: absolute; top: calc(100% + 10px); left: -.5rem;
  min-width: 260px; background: var(--white);
  border: 1px solid var(--line); border-radius: 8px;
  box-shadow: var(--shadow-lg); padding: .5rem;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
  list-style: none; margin: 0;
}
.nav__item.is-open .drop { opacity: 1; visibility: visible; transform: translateY(0); }
.drop a {
  display: block; padding: .65rem .75rem; border-radius: var(--radius);
  font-size: .9375rem; transition: background .18s, color .18s;
}
.drop a:hover { background: var(--paper-2); color: var(--chapter); }
.drop a small {
  display: block; font-size: var(--t-xs); color: var(--ink-4);
  font-weight: 400; margin-top: .15rem;
}
.drop__head {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-4);
  padding: .6rem .75rem .35rem;
}
.drop hr { border: 0; border-top: 1px solid var(--line); margin: .4rem .75rem; }

/* — Persistent conversion actions (Donate / Sign Up / Newsroom) — */
.hdr__actions { display: none; align-items: center; gap: .5rem; flex: none; }
.hdr__actions .btn { min-height: 42px; padding: .55rem 1.1rem; }

.burger {
  margin-left: auto; width: 46px; height: 46px; flex: none;
  display: grid; place-items: center; border-radius: var(--radius);
  border: 1px solid var(--line);
}
.burger span {
  display: block; width: 20px; height: 1.5px; background: var(--ink);
  position: relative; transition: .3s var(--ease);
}
.burger span::before, .burger span::after {
  content: ""; position: absolute; left: 0; width: 20px; height: 1.5px;
  background: var(--ink); transition: .3s var(--ease);
}
.burger span::before { top: -6px; }
.burger span::after  { top: 6px; }
body.nav-open .burger span { background: transparent; }
body.nav-open .burger span::before { top: 0; transform: rotate(45deg); }
body.nav-open .burger span::after  { top: 0; transform: rotate(-45deg); }

@media (min-width: 1080px) {
  .nav { display: block; }
  .hdr__actions { display: flex; }
  .burger { display: none; }
}

/* — Mobile drawer — */
.drawer {
  position: fixed; inset: 0; z-index: 100;
  background: var(--paper); overflow-y: auto;
  transform: translateX(100%); transition: transform .38s var(--ease);
  padding-bottom: 8rem;
  visibility: hidden;
}
body.nav-open .drawer { transform: translateX(0); visibility: visible; }
body.nav-open { overflow: hidden; }

.drawer__top {
  display: flex; align-items: center; min-height: 74px;
  border-bottom: 1px solid var(--line); margin-bottom: 1rem;
}
.drawer__x {
  margin-left: auto; width: 46px; height: 46px; display: grid; place-items: center;
  border: 1px solid var(--line); border-radius: var(--radius); font-size: 1.5rem; line-height: 1;
}
.drawer__group { border-bottom: 1px solid var(--line); }

/* Parent-site link at the head of a chapter drawer. Deliberately styled as a
   card rather than a menu row so it reads as "leave here", not "another
   section of this page". */
.drawer__home {
  display: flex; align-items: center; gap: .8rem;
  padding: .9rem 1rem; margin-bottom: 1rem;
  background: var(--surface); color: #fff; border-radius: 6px;
}
.drawer__home img { border-radius: 50%; flex: none; }
.drawer__home b { display: block; font-size: var(--t-sm); font-weight: 600; }
.drawer__home small {
  display: block; font-family: var(--f-mono); font-size: var(--t-2xs);
  letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.6);
  margin-top: .15rem;
}
.drawer__home svg { margin-left: auto; flex: none; }
.drawer__toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  padding: 1.15rem 0; font-family: var(--f-display); font-size: 1.5rem; letter-spacing: -.02em;
  text-align: left;
}
.drawer__toggle svg { transition: transform .3s var(--ease); opacity: .45; flex: none; }
.drawer__group.is-open .drawer__toggle svg { transform: rotate(180deg); }
/* A top-level drawer item with no submenu — mirrors a plain nav link so the
   drawer can match the desktop nav exactly on any page. */
.drawer__link {
  display: block; width: 100%; padding: 1.15rem 0;
  font-family: var(--f-display); font-size: 1.5rem; letter-spacing: -.02em;
}
.drawer__link[aria-current="page"] { color: var(--chapter); }

.drawer__sub {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease);
}
.drawer__group.is-open .drawer__sub { grid-template-rows: 1fr; }
.drawer__sub > div { overflow: hidden; }
.drawer__sub a {
  display: block; padding: .7rem 0 .7rem 1rem; font-size: 1rem;
  color: var(--ink-2); border-left: 2px solid var(--line);
}
.drawer__sub a:last-child { padding-bottom: 1.25rem; }
.drawer__actions { display: grid; gap: .75rem; margin-top: 2rem; }

/* — Mobile sticky action bar. Keeps giving one thumb-tap away. — */
.mbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  display: grid; grid-template-columns: 1fr 1fr; gap: .6rem;
  padding: .6rem var(--gut) calc(.6rem + env(safe-area-inset-bottom));
  background: rgba(244,247,252,.94);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--line);
  transform: translateY(110%); transition: transform .35s var(--ease);
}
.mbar.is-on { transform: translateY(0); }
.mbar .btn { min-height: 46px; font-size: var(--t-sm); }
@media (min-width: 1080px) { .mbar { display: none; } }
body.nav-open .mbar { transform: translateY(110%); }

/* --------------------------------------------------------------------------
   8. CHAPTER NETWORK BAR
   The device that makes a chapter feel like a distinct entity *and* an
   unmistakable part of the parent organization.
   -------------------------------------------------------------------------- */
.netbar {
  background: var(--surface-dp); color: rgba(255,255,255,.72);
  font-size: var(--t-sm); position: relative; z-index: 55;
}
.netbar__in {
  display: flex; align-items: center; gap: .75rem;
  min-height: 44px; padding-block: .4rem;
}
/* The route back to the parent site. Made an obvious, whole-area target with
   an arrow rather than a buried inline link — on a chapter page this is the
   single most important piece of wayfinding. */
.netbar__home {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .1em;
  text-transform: uppercase; display: inline-flex; align-items: center; gap: .5rem;
  min-width: 0; color: #fff;
  padding: .35rem .6rem; margin-left: -.6rem; border-radius: 100px;
  transition: background .2s;
}
.netbar__home img { width: 18px; height: 18px; border-radius: 50%; flex: none; }
.netbar__home span { white-space: nowrap; }
.netbar__arrow { flex: none; transition: transform .25s var(--ease); }
.netbar__home:hover { background: rgba(255,255,255,.14); }
.netbar__home:hover .netbar__arrow { transform: translateX(3px); }
/* On narrow screens the parent-org line is the message that matters; the
   state switcher is redundant with the drawer's Network group, so it drops. */
.netbar__pre { display: none; }
.netbar__states { display: none; gap: .25rem; margin-left: auto; flex: none; }
@media (min-width: 620px) {
  .netbar__pre { display: inline; }
  .netbar__states { display: flex; }
}
.netbar__state {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .1em;
  padding: .3rem .55rem; border-radius: 3px; transition: .2s;
  border: 1px solid transparent;
}
.netbar__state:hover { background: rgba(255,255,255,.12); color: #fff; }
.netbar__state.is-on { background: var(--chapter); color: #fff; }

/* --------------------------------------------------------------------------
   9. HERO  →  Strapi: shared.hero
   -------------------------------------------------------------------------- */
.hero { position: relative; overflow: hidden; background: var(--surface); color: #fff; }

/* A chapter's hero leads with the chapter color instead of FAF deep blue —
   the strongest single signal that you've arrived somewhere local. The parent
   network bar directly above stays FAF blue, so the relationship still reads.
   Applies to any chapter, not just Vermont. */
[data-chapter] .hero { background: var(--chapter-hero, var(--chapter)); }
[data-chapter] .hero .eyebrow { color: #fff; }
[data-chapter] .hero .eyebrow::after,
[data-chapter] .hero .eyebrow::before { opacity: .45; }
[data-chapter] .hero .crumb { color: rgba(255, 255, 255, .68); }
[data-chapter] .hero__sub { color: rgba(255, 255, 255, .86); }
/* The emphasis colour is FAF light blue, which fights a green field. On a
   chapter hero it becomes a pale tint of that chapter's own colour instead. */
[data-chapter] .hero__title em { color: color-mix(in srgb, #fff 68%, var(--chapter)); }
/* The glow reads as haze on a mid-tone field, so deepen it instead. */
[data-chapter] .hero__glow {
  background: radial-gradient(circle, color-mix(in srgb, var(--chapter-ink) 60%, transparent) 0%, transparent 66%);
}
.hero__in { position: relative; z-index: 2; padding-block: clamp(3.5rem, 9vw, 7rem); }

/* Ledger-rule backdrop: faint horizontal rules + vertical column marks.
   Reads as ruled accounting paper without being literal. */
.hero__rules {
  position: absolute; inset: 0; z-index: 0; opacity: .5;
  background-image:
    repeating-linear-gradient(to bottom, rgba(255,255,255,.055) 0 1px, transparent 1px 46px),
    repeating-linear-gradient(to right, rgba(255,255,255,.04) 0 1px, transparent 1px 8.333%);
  mask-image: radial-gradient(120% 100% at 70% 0%, #000 20%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 100% at 70% 0%, #000 20%, transparent 78%);
}
/* Ghosted brand background (currency + New England map).
   mix-blend-mode: luminosity keeps only the image's light and dark and takes
   hue from the hero beneath it — so the source art's violet resolves to FAF
   blue with no recolouring, and it would re-tint automatically on a chapter
   page. Masked so it never sits behind the headline. */
.hero__photo {
  position: absolute; inset: 0; z-index: 0;
  background: url("../img/covers/hero-bg.jpg") center right / cover no-repeat;
  mix-blend-mode: luminosity;
  opacity: .52;
  filter: contrast(1.3);          /* the source is low-contrast; lift the engraving */
  mask-image: linear-gradient(100deg, rgba(0,0,0,.12) 0%, rgba(0,0,0,.5) 32%, #000 68%);
  -webkit-mask-image: linear-gradient(100deg, rgba(0,0,0,.12) 0%, rgba(0,0,0,.5) 32%, #000 68%);
  pointer-events: none;
}
@media (max-width: 860px) {
  /* Narrow screens crop into the busiest part of the art, so pull it back. */
  .hero__photo { opacity: .3; background-position: 72% center; }
}

/* Interior heroes are far shorter than the homepage, so the same crop lands on
   a different part of the art — bias toward the map side and ease it back a
   little so it stays texture rather than picture. */
.phero .hero__photo { opacity: .42; background-position: 62% 42%; }

/* Chapter pages never carry the national artwork — their hero is the chapter's
   own. Explicit so a future chapter cannot inherit it by accident. */
[data-chapter] .hero__photo { display: none; }

/* Vermont's own hero art: the State House at Montpelier, from the Historic
   American Buildings Survey (Library of Congress). A federal work, so public
   domain — no attribution or share-alike obligation. Selector specificity ties
   with the rule above, so this must stay after it. The archival print is
   already high in contrast, so it needs less of a lift than the engraving on
   the national hero. */
[data-chapter="vermont"] .hero__photo {
  display: block;
  background-image: url("../img/covers/hero-vt.webp");
  background-position: center 36%;
  /* The national hero lifts a pale engraving; this one is a high-contrast
     silver print, so it needs holding back instead — the building should read
     as a watermark behind the headline, never as a photograph competing with
     the sign-up card sitting on top of it. */
  filter: contrast(.92) brightness(1.05);
  opacity: .17;
}
@media (max-width: 860px) {
  [data-chapter="vermont"] .hero__photo { opacity: .12; background-position: 58% 36%; }
}

.hero__glow {
  position: absolute; z-index: 1; width: 70vw; height: 70vw; max-width: 780px; max-height: 780px;
  right: -14vw; top: -26vw; border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--chapter) 55%, transparent) 0%, transparent 66%);
  filter: blur(28px); pointer-events: none;
}

/* The roundel as an embossed seal, struck into the lower-left of the hero the
   way a seal is struck into a document — the ghosted artwork is masked toward
   the right, so this corner is the quiet one. soft-light keeps only the mark's
   light and shade, so it reads as pressed into the field rather than pasted on
   top, and it re-tints itself on a chapter hero with no override. */
.hero__seal {
  position: absolute; z-index: 0; pointer-events: none;
  left: -6rem; top: -4rem;
  width: clamp(24rem, 27vw, 34rem); aspect-ratio: 1;
  background: url("../img/faf-logo.png") center / contain no-repeat;
  mix-blend-mode: soft-light;
  opacity: .35;
}
/* Contrast note: soft-light at .35 with a white source lifts the hero field
   from #093D63 to at most #115378. Against that worst case the hero sub-copy
   (white at 76%) still measures 5.6:1 and the pale emphasis colour 5.1:1, so
   the mark costs nothing in legibility. The ghosted artwork is masked to
   almost nothing on this side, so the seal is not competing with it either. */
@media (max-width: 959px) {
  /* Stacked layout puts the headline over the middle of the mark, so shrink it
     and push it off the corner rather than let it sit behind the type. */
  .hero__seal { width: 19rem; left: -7rem; top: -5rem; opacity: .26; }
}
@media (max-width: 620px) { .hero__seal { display: none; } }

.hero__title { font-size: var(--t-h1); max-width: 17ch; }
/* faf-pale rather than faf-accent: the accent measures only 4.6:1 on the deep
   blue, and the ghosted artwork behind the headline erodes that further. Pale
   lifts it to ~6.9:1 while still reading as a tint rather than plain white. */
.hero__title em { font-style: normal; color: var(--blue-pale); }
.hero__sub {
  margin-top: 1.5rem; max-width: 60ch;
  font-size: clamp(1.0625rem, .8vw + .9rem, 1.3125rem);
  line-height: 1.6; color: rgba(255,255,255,.76);
}
.hero__cta { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2.25rem; }

/* Hero split: copy + featured item */
.hero__split {
  display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: end;
}
@media (min-width: 960px) {
  .hero__split { grid-template-columns: 1.15fr .85fr; }
}

/* Page hero (interior, lighter) */
.phero { background: var(--surface); color: #fff; position: relative; overflow: hidden; }
.phero__in { position: relative; z-index: 2; padding-block: clamp(2.75rem, 6vw, 5rem); }
.phero h1 { max-width: 20ch; }
.phero .lede { margin-top: 1.25rem; color: rgba(255,255,255,.76); }

/* Breadcrumb */
.crumb {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255,255,255,.55); margin-bottom: 1.5rem;
}
.crumb a:hover { color: #fff; }
.crumb span { opacity: .45; }

/* --------------------------------------------------------------------------
   10. STAT BAND  →  Strapi: shared.stat-block
   Full-bleed hairline grid. The "Why It Matters" workhorse.
   -------------------------------------------------------------------------- */
.stats {
  display: grid; grid-template-columns: repeat(2, 1fr);
  border-top: 1px solid var(--line); border-left: 1px solid var(--line);
}
/* Brighter than the general inverted hairline so the cells read as a grid
   over the ghosted hero artwork. */
.stats--inv { border-color: rgba(255, 255, 255, .4); }
@media (min-width: 720px) { .stats { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .stats--4 { grid-template-columns: repeat(4, 1fr); } }

.stat {
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: clamp(1.25rem, 2.5vw, 2rem);
  display: flex; flex-direction: column; gap: .5rem;
  min-height: 130px;
}
/* Labels sit on a shared baseline only once the cells are wide enough that
   the alignment reads as intentional rather than as a gap. */
@media (min-width: 720px) { .stat { min-height: 160px; } .stat__lbl { margin-top: auto; } }
.stats--inv .stat { border-color: rgba(255, 255, 255, .4); }
.stat__num {
  font-family: var(--f-display); font-size: clamp(2.25rem, 4vw, 3.5rem);
  font-weight: 700;   /* the figure is the point of the cell — let it carry weight */
  line-height: .95; letter-spacing: -.028em; font-variant-numeric: tabular-nums;
  color: var(--chapter);
}
.stats--inv .stat__num { color: #fff; }
.stat__lbl { font-size: var(--t-sm); line-height: 1.45; color: var(--ink-2); }
.stats--inv .stat__lbl { color: rgba(255,255,255,.9); }
/* The ghosted artwork is at its lightest under the stat band, which was
   washing out the white figures and their source notes. A scrim restores a
   predictable backdrop while still letting the texture read through. */
.hero .stats--inv {
  background: linear-gradient(to bottom, rgba(6, 40, 63, .42), rgba(6, 40, 63, .62));
  backdrop-filter: saturate(115%);
}
.stat__src {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .08em;
  color: var(--ink-4); text-transform: uppercase;
}
.stats--inv .stat__src { color: rgba(255,255,255,.75); }

/* --------------------------------------------------------------------------
   11. GENERATIVE COVERS  →  content-item.featuredImage fallback
   FAF has no photo library. Every content type gets a distinct, on-brand
   cover generated in CSS — so the newsroom never needs stock photography,
   and a real featuredImage simply overrides it when one exists.
   -------------------------------------------------------------------------- */
.cover {
  --cv-accent: rgba(224, 163, 60, .9);   /* gold highlight, blue covers */
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  background: var(--surface); border-radius: var(--radius);
  display: grid; place-items: center;
}
/* Real cover art overrides the generated motif. Document covers are portrait
   and put the title high, so they crop from a focal point rather than centre —
   the inline object-position on each image is the focal point, which maps to a
   focalPoint field on content-item.featuredImage in Strapi. */
/* Absolutely positioned so the box has a definite height. A percentage height
   cannot resolve against the parent's aspect-ratio, so height:100% would fall
   back to auto and the image would overflow and be clipped. */
.cover img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%;
}
.cover--art, .cover--doc { background: var(--paper-2); }
.cover--art .cover__mark, .cover--doc .cover__mark { display: none; }
/* Real covers carry their own "STUDY" / "WHITE PAPER" masthead, so the type
   chip is both redundant and lands on top of the title. The card's meta row
   below still shows state, topic, and date. */
.cover--art .cover__type, .cover--doc .cover__type { display: none; }

/* Banner art images: fit the whole image instead of cropping. */
.cover--art img {
  object-fit: contain;
  object-position: center;
}

/* Portrait report covers can't survive a 16:10 crop — the title is the whole
   design. Show the sheet complete, sitting on the card surface, instead. */
.cover--doc img {
  object-fit: contain;
  object-position: center;
  padding: .625rem;
  filter: drop-shadow(0 2px 10px rgba(9, 61, 99, .22));
}
.cover__mark {
  position: absolute; inset: 0; opacity: .9;
}
.cover__type {
  position: absolute; left: .875rem; bottom: .875rem; z-index: 3;
  font-family: var(--f-mono); font-size: var(--t-2xs); font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: #fff;
  background: rgba(6,40,63,.6); backdrop-filter: blur(6px);
  padding: .35rem .6rem; border-radius: 3px;
  border: 1px solid rgba(255,255,255,.18);
}

/* Study / Report — stacked bar chart motif */
.cover--study .cover__mark {
  background:
    linear-gradient(to top, rgba(20,121,191,.85) 0 32%, transparent 32%) 6% 100%/9% 62% no-repeat,
    linear-gradient(to top, rgba(20,121,191,.65) 0 54%, transparent 54%) 20% 100%/9% 62% no-repeat,
    linear-gradient(to top, var(--cv-accent)     0 78%, transparent 78%) 34% 100%/9% 62% no-repeat,
    linear-gradient(to top, rgba(20,121,191,.5)  0 44%, transparent 44%) 48% 100%/9% 62% no-repeat,
    linear-gradient(to top, rgba(20,121,191,.75) 0 92%, transparent 92%) 62% 100%/9% 62% no-repeat,
    linear-gradient(to top, rgba(20,121,191,.4)  0 60%, transparent 60%) 76% 100%/9% 62% no-repeat,
    linear-gradient(to top, rgba(20,121,191,.6)  0 36%, transparent 36%) 90% 100%/9% 62% no-repeat,
    linear-gradient(145deg, #0B4670, #06283F);
}
/* Polling — dot matrix */
.cover--poll .cover__mark {
  background:
    radial-gradient(circle at center, var(--cv-accent) 32%, transparent 33%) 0 0/12.5% 20%,
    linear-gradient(145deg, #0C4A76, #072D48);
  mask-image: linear-gradient(115deg, #000 42%, rgba(0,0,0,.22) 42%);
  -webkit-mask-image: linear-gradient(115deg, #000 42%, rgba(0,0,0,.22) 42%);
}
/* Legal — column / rule motif */
.cover--legal .cover__mark {
  background:
    linear-gradient(to right, transparent 0 46%, rgba(255,255,255,.5) 46% 54%, transparent 54%) 50% 22%/70% 5% no-repeat,
    linear-gradient(to right, rgba(255,255,255,.28) 0 6%, transparent 6% 22%) 50% 62%/70% 46% no-repeat,
    linear-gradient(145deg, #0A4269, #052437);
}
/* Op-Ed — quotation rules */
.cover--oped .cover__mark {
  background:
    repeating-linear-gradient(to bottom, rgba(255,255,255,.26) 0 2px, transparent 2px 14px) 12% 26%/44% 40% no-repeat,
    repeating-linear-gradient(to bottom, var(--cv-accent) 0 2px, transparent 2px 14px) 12% 76%/26% 16% no-repeat,
    linear-gradient(145deg, #0D4E7C, #06283F);
}
/* Press release — masthead rule */
.cover--press .cover__mark {
  background:
    linear-gradient(to right, rgba(255,255,255,.85) 0 100%) 8% 24%/34% 3px no-repeat,
    repeating-linear-gradient(to bottom, rgba(255,255,255,.2) 0 1px, transparent 1px 11px) 8% 46%/84% 44% no-repeat,
    linear-gradient(145deg, #093D63, #05223A);
}
/* Perspective / blog — topo contour */
.cover--persp .cover__mark {
  background:
    repeating-radial-gradient(circle at 78% 88%, transparent 0 16px, rgba(255,255,255,.16) 16px 17px),
    linear-gradient(145deg, #0B4570, #062A44);
}
/* Event */
.cover--event .cover__mark {
  background:
    linear-gradient(to right, rgba(255,255,255,.14) 0 1px, transparent 1px) 0 0/25% 100%,
    linear-gradient(to bottom, rgba(255,255,255,.14) 0 1px, transparent 1px) 0 0/100% 33.33%,
    linear-gradient(145deg, #0C4874, #062B45);
}
/* Chapter-tinted cover for Vermont content. The accent switches to white so
   it survives the hue rotation that maps the blue field to green. */
.cover--vt { /* retained as a hook; Vermont now uses the standard blue covers */ }

/* --------------------------------------------------------------------------
   11b. VIDEO  →  content-item (contentType: Video) / shared.video-embed
   A click-to-load facade: only the poster loads with the page, and the real
   YouTube player is injected on press. That keeps YouTube's ~1MB of script and
   its cookies off every page view — which matters for speed and for a
   501(c)(3) that publishes a donor privacy policy.
   -------------------------------------------------------------------------- */
.vid {
  position: relative; display: block; width: 100%; padding: 0;
  aspect-ratio: 16 / 9; overflow: hidden; cursor: pointer;
  border: 0; border-radius: var(--radius); background: var(--surface-dp);
}
.vid img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; transition: transform .6s var(--ease), filter .35s;
}
.vid:hover img { transform: scale(1.045); filter: brightness(.88); }
.vid iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.vid__play {
  position: absolute; inset: 0; display: grid; place-items: center;
  pointer-events: none;
}
.vid__play i {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--signal); display: grid; place-items: center;
  box-shadow: 0 6px 24px rgba(9, 61, 99, .45);
  transition: transform .3s var(--ease), background .3s;
}
.vid:hover .vid__play i { transform: scale(1.08); background: var(--signal-dk); }
.vid__play i::before {
  content: ""; width: 0; height: 0; margin-left: 5px;
  border-left: 18px solid #fff;
  border-block: 11px solid transparent;
}
.vid--sm .vid__play i { width: 46px; height: 46px; }
.vid--sm .vid__play i::before { border-left-width: 13px; border-block-width: 8px; margin-left: 4px; }

.vid__time {
  position: absolute; right: .6rem; bottom: .6rem; z-index: 2;
  font-family: var(--f-mono); font-size: var(--t-2xs); color: #fff;
  background: rgba(6, 40, 63, .82); padding: .25rem .45rem; border-radius: 3px;
}
.vid.is-playing .vid__play, .vid.is-playing .vid__time { display: none; }

/* Lightbox player.
   Cards live in grids as small as ~200px tall, so playing in place is not
   watchable. The lightbox gives every video the largest 16:9 player the
   window allows, wherever it was clicked from. The iframe is created on open
   and destroyed on close — which stops playback and keeps YouTube's scripts
   and cookies off the page the rest of the time. */
.lbx {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: clamp(1rem, 4vw, 2.5rem);
  background: rgba(6, 40, 63, .93);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  opacity: 0; visibility: hidden;
  transition: opacity .28s var(--ease), visibility .28s;
}
.lbx.is-open { opacity: 1; visibility: visible; }

.lbx__inner {
  /* the larger of the two constraints wins, so the player fills the window */
  width: min(94vw, calc(82vh * 16 / 9));
  display: grid; gap: .75rem;
}
.lbx__frame {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  background: #000; border-radius: 6px; overflow: hidden;
  box-shadow: 0 40px 80px -20px rgba(0, 0, 0, .6);
  transform: scale(.97); transition: transform .28s var(--ease);
}
.lbx.is-open .lbx__frame { transform: scale(1); }
.lbx__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.lbx__bar { display: flex; align-items: center; gap: 1rem; color: #fff; }
.lbx__title {
  font-family: var(--f-display); font-size: var(--t-h4); line-height: 1.25;
  letter-spacing: -.015em; min-width: 0;
}
.lbx__x {
  flex: none; margin-left: auto;
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 44px; padding: .5rem 1rem; border-radius: 100px;
  border: 1px solid rgba(255,255,255,.35); color: #fff;
  font-size: var(--t-sm); font-weight: 600; transition: .2s;
}
.lbx__x:hover { background: #fff; color: var(--ink); border-color: #fff; }
body.lbx-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .lbx, .lbx__frame { transition: none; }
  .lbx__frame { transform: none; }
}

/* Video card = facade + caption below */
.vcard { display: flex; flex-direction: column; gap: .875rem; }
.vcard__title {
  font-family: var(--f-display); font-size: var(--t-h4);
  line-height: 1.22; letter-spacing: -.015em;
}
.vcard--sm .vcard__title { font-size: 1.0625rem; line-height: 1.3; }
.vcard:hover .vcard__title { color: var(--chapter); }
.section--ink .vcard:hover .vcard__title,
[data-chapter] .section--ink .vcard:hover .vcard__title { color: var(--blue-pale); }

/* Rail of secondary videos beside a featured one */
.vrail { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
@media (min-width: 640px)  { .vrail { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) { .vrail { grid-template-columns: 1fr; } }

.vfeature { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); align-items: start; }
@media (min-width: 1040px) { .vfeature { grid-template-columns: 1.5fr 1fr; } }

/* --------------------------------------------------------------------------
   12. CARDS  →  content-item teaser
   -------------------------------------------------------------------------- */
.card { display: flex; flex-direction: column; gap: 1rem; position: relative; }
.card__cover { overflow: hidden; border-radius: var(--radius); }
.card__cover .cover { transition: transform .55s var(--ease); }
.card:hover .card__cover .cover { transform: scale(1.035); }
.card__meta { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.card__title {
  font-family: var(--f-display); font-size: var(--t-h4);
  line-height: 1.2; letter-spacing: -.015em;
}
.card__title a::after { content: ""; position: absolute; inset: 0; }
.card:hover .card__title { color: var(--chapter); }
.card__excerpt { font-size: var(--t-sm); line-height: 1.6; color: var(--ink-3); }

/* Cards on dark surfaces.
   The card was designed against paper: its meta grey (2.6:1 here) and its
   FAF-blue hover (2.4:1 — darker than the resting title) both fail on the
   deep blue. On dark, metadata goes light and hover moves to faf-pale so the
   rollover gets brighter rather than dimmer. */
.hero .card__title,
.section--ink .card__title { color: #fff; }
.hero .card:hover .card__title,
.section--ink .card:hover .card__title,
.hero .feature:hover .feature__title { color: var(--blue-pale); }
.hero .meta,
.section--ink .meta { color: rgba(255, 255, 255, .72); }
.hero .card__excerpt,
.section--ink .card__excerpt { color: rgba(255, 255, 255, .78); }

/* Hero feature carousel — the five most recent items in Our Work.
   Every slide sits in the same grid cell, so the frame is as tall as the
   tallest one and the hero never reflows as it cycles. */
.hcar { display: flex; flex-direction: column; gap: 1.25rem; }
.hcar__track { display: grid; }
.hcar__slide {
  grid-area: 1 / 1;
  opacity: 0; pointer-events: none; visibility: hidden;
  transition: opacity .5s var(--ease), visibility 0s linear .5s;
}
.hcar__slide.is-on {
  opacity: 1; pointer-events: auto; visibility: visible;
  transition: opacity .5s var(--ease), visibility 0s;
}
.hcar__dots { display: flex; align-items: center; gap: .625rem; }
.hcar__dot {
  position: relative; flex: none; padding: 0;
  width: 9px; height: 9px; border-radius: 50%;
  background: rgba(255, 255, 255, .3);
  transition: background .3s var(--ease), transform .3s var(--ease);
}
/* Comfortable tap target without inflating the dot itself. */
.hcar__dot::before { content: ""; position: absolute; inset: -11px; }
.hcar__dot:hover { background: rgba(255, 255, 255, .6); }
.hcar__dot.is-on { background: #fff; transform: scale(1.25); }
.hcar__dot:focus-visible { outline: 2px solid var(--blue-pale); outline-offset: 4px; }
@media (prefers-reduced-motion: reduce) {
  .hcar__slide, .hcar__dot { transition: none; }
}

/* Tag chip */
.tag {
  display: inline-flex; align-items: center; gap: .35rem;
  font-family: var(--f-mono); font-size: var(--t-2xs); font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase;
  padding: .3rem .5rem; border-radius: 3px;
  background: var(--chapter-lt); color: var(--chapter-dk);
}
.tag--state { background: var(--surface); color: #fff; }
.tag--vt { background: var(--blue); color: #fff; }
.tag--ma { background: #1E5FA8; color: #fff; }
.tag--ghost { background: transparent; border: 1px solid var(--line-2); color: var(--ink-3); }

/* Featured card — the hero item */
.feature {
  display: grid; gap: clamp(1.5rem, 3vw, 2.5rem);
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--white); border: 1px solid var(--line);
  border-radius: 8px; box-shadow: var(--shadow);
  position: relative;
}
@media (min-width: 760px) { .feature { grid-template-columns: 1fr 1fr; align-items: center; } }
.feature__title { font-size: var(--t-h3); letter-spacing: -.02em; }
.feature__title a::after { content: ""; position: absolute; inset: 0; }
.feature:hover .feature__title { color: var(--chapter); }

/* Dense list view — Claude-publications pattern. Scans fast at volume. */
.itemlist { border-top: 1px solid var(--line); }
.item {
  display: grid; gap: .35rem 1.5rem; align-items: baseline;
  padding: 1.35rem 0; border-bottom: 1px solid var(--line);
  position: relative; transition: background .2s;
}
.item:hover { background: color-mix(in srgb, var(--chapter-lt) 60%, transparent); }
@media (min-width: 860px) {
  .item {
    grid-template-columns: 1fr 190px 120px;
    padding-inline: 1rem; margin-inline: -1rem;
  }
}
.item__title { font-family: var(--f-display); font-size: 1.1875rem; line-height: 1.3; letter-spacing: -.012em; }
.item__title a::after { content: ""; position: absolute; inset: 0; }
.item:hover .item__title { color: var(--chapter); }
.item__tags { display: flex; gap: .4rem; flex-wrap: wrap; }
.item__date { font-family: var(--f-mono); font-size: var(--t-xs); color: var(--ink-4); letter-spacing: .05em; }
@media (min-width: 860px) { .item__date { text-align: right; } }

/* --------------------------------------------------------------------------
   13. FILTER BAR  →  drives the State / Topic / Type taxonomy
   -------------------------------------------------------------------------- */
.filters {
  position: sticky; top: var(--hdr-h-stuck); z-index: 30;
  background: rgba(244,247,252,.93);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  padding-block: .875rem;
}
.filters__row { display: flex; align-items: center; gap: .5rem; }
.filters__row + .filters__row { margin-top: .625rem; }
.filters__lbl {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-4); flex: none; width: 46px;
}
.chips {
  display: flex; gap: .4rem; overflow-x: auto; scrollbar-width: none;
  -ms-overflow-style: none; padding-block: 2px; flex: 1;
  scroll-snap-type: x proximity;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex: none; scroll-snap-align: start;
  font-size: var(--t-sm); font-weight: 500; white-space: nowrap;
  padding: .45rem .85rem; border-radius: 100px;
  border: 1px solid var(--line-2); color: var(--ink-2);
  transition: .2s var(--ease); min-height: 36px;
}
.chip:hover { border-color: var(--ink); }
.chip.is-on { background: var(--surface); border-color: var(--surface); color: #fff; }
.chip--state.is-on { background: var(--chapter); border-color: var(--chapter); }
.chip__n { font-family: var(--f-mono); font-size: var(--t-2xs); opacity: .6; margin-left: .35rem; }

/* --------------------------------------------------------------------------
   13b. LIBRARY — OPTION B
   Content type is promoted to tabs (it is how people actually arrive: "I want
   the studies"). State and Topic drop to secondary facets. Every option shows
   a live count computed against the *other* active filters, so a zero-result
   combination is visible before you click it — the main flaw in the flat
   three-row scheme.
   -------------------------------------------------------------------------- */
.tabsbar { border-bottom: 1px solid var(--line); background: var(--paper); }
.tabs {
  display: flex; gap: .25rem; overflow-x: auto; scrollbar-width: none;
  scroll-snap-type: x proximity;
}
.tabs::-webkit-scrollbar { display: none; }
.tab {
  flex: none; scroll-snap-align: start; white-space: nowrap;
  display: inline-flex; align-items: baseline; gap: .45rem;
  padding: 1rem .875rem; min-height: 52px;
  font-size: .9375rem; font-weight: 500; color: var(--ink-3);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .2s, border-color .2s;
}
.tab:hover { color: var(--ink); }
.tab.is-on { color: var(--chapter); border-bottom-color: var(--chapter); font-weight: 600; }
.tab__n, .chip__n {
  font-family: var(--f-mono); font-size: var(--t-2xs); color: var(--ink-4);
  font-weight: 400;
}
.tab.is-on .tab__n { color: var(--chapter); }
.tab[disabled], .chip[disabled] { opacity: .35; pointer-events: none; }

.libbar {
  position: sticky; top: var(--hdr-h-stuck); z-index: 30;
  background: rgba(244,247,252,.94);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line); padding-block: .75rem;
}
.libbar__in { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.fgroup { display: flex; align-items: center; gap: .6rem; min-width: 0; flex: 1 1 auto; }
.fgroup__lbl {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-4); flex: none;
}
.chip--more { border-style: dashed; color: var(--ink-4); }
.chip.is-extra { display: none; }
.chips.show-all .chip.is-extra { display: inline-flex; }
/* Expanded, the row stops being a scroller and wraps, so every topic is on
   screen at once — a hidden-scrollbar overflow row silently clipped the last
   chips with no affordance that more existed. */
.chips.show-all {
  flex-wrap: wrap; overflow-x: visible;
  scroll-snap-type: none; row-gap: .4rem;
}
.fgroup:has(.chips.show-all) { align-items: flex-start; }
.fgroup:has(.chips.show-all) .fgroup__lbl { padding-top: .65rem; }

.sortsel { flex: none; margin-left: auto; }
.sortsel select {
  min-height: 36px; padding: .3rem 1.75rem .3rem .7rem;
  border: 1px solid var(--line-2); border-radius: 100px;
  background: transparent; font-size: var(--t-sm); cursor: pointer;
}

.libhead {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding-block: 1.5rem .5rem;
}
.libhead .results__count { padding: 0; }

/* Active filters, each individually removable */
.pills { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.pill {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .3rem .5rem .3rem .7rem; border-radius: 100px;
  background: var(--chapter-lt); color: var(--chapter-dk);
  font-size: var(--t-xs); font-weight: 500; min-height: 30px;
}
.pill b { font-weight: 600; }
.pill__x {
  display: grid; place-items: center; width: 18px; height: 18px;
  border-radius: 50%; background: var(--chapter); color: #fff;
  font-size: 11px; line-height: 1;
}
.pill__x:hover { background: var(--chapter-dk); }
.pill--clear {
  background: transparent; color: var(--ink-4);
  text-decoration: underline; text-underline-offset: 3px; padding-inline: .4rem;
}
.pill--clear:hover { color: var(--ink); }

@media (max-width: 720px) {
  .libbar__in { gap: .65rem; }
  .fgroup { flex: 1 1 100%; }
  /* On a phone no facet row fits on one line, and the scroller hides its own
     scrollbar — so State and the collapsed Topic row both wrap here too. */
  .chips {
    flex-wrap: wrap; overflow-x: visible;
    scroll-snap-type: none; row-gap: .4rem;
  }
  .fgroup { align-items: flex-start; }
  .fgroup__lbl { padding-top: .65rem; }
  /* Wrapped, the bar is several rows tall — pinned to the top it would eat a
     third of a phone screen for the whole scroll, so it scrolls away instead. */
  .libbar { position: static; }
  .sortsel { margin-left: 0; flex: 1 1 100%; }
  .sortsel select { width: 100%; border-radius: var(--radius); }
}

.results__count {
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-4);
  padding-block: 1.5rem .5rem;
}
.is-hidden { display: none !important; }

/* Load-more control for the library. The count sits above the button so the
   number is read before the action it belongs to. */
.loadmore {
  display: grid; justify-items: center; gap: .9rem;
  margin-top: clamp(2rem, 4vw, 3rem);
}
.loadmore__note {
  font-family: var(--f-mono); font-size: var(--t-2xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4);
}

.empty {
  padding: 4rem 1rem; text-align: center; color: var(--ink-4);
  border: 1px dashed var(--line-2); border-radius: 8px; margin-top: 2rem;
}

/* --------------------------------------------------------------------------
   14. PILLARS  →  "What We Do" / issue tiles  →  shared.issue-tile
   -------------------------------------------------------------------------- */
.pillar {
  display: block; position: relative;
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--white); border: 1px solid var(--line);
  border-radius: 6px; overflow: hidden;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s;
}
.pillar::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--chapter); transform: scaleY(0); transform-origin: top;
  transition: transform .4s var(--ease);
}
.pillar:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--line-2); }
.pillar:hover::before { transform: scaleY(1); }
.pillar__ico {
  width: 40px; height: 40px; margin-bottom: 1.25rem;
  color: var(--chapter);
}
.pillar__ico svg { width: 100%; height: 100%; stroke-width: 1.25; }
.pillar h3 { font-size: var(--t-h4); margin-bottom: .6rem; }
.pillar p { font-size: var(--t-sm); line-height: 1.65; color: var(--ink-3); }
.pillar__more {
  display: inline-flex; align-items: center; gap: .4rem; margin-top: 1.1rem;
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .12em;
  text-transform: uppercase; color: var(--chapter);
}

/* --------------------------------------------------------------------------
   15. CARTOGRAM  →  "Serving New England" chapter directory
   One stacked tile per live chapter, founding chapter first. States without a
   chapter are not drawn at all — an empty tile reads as a stalled launch.
   -------------------------------------------------------------------------- */
.carto {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "ma"
    "vt";
  gap: 10px;
  /* Definite width: the tile map sits in a `justify-self: center` grid item,
     so a percentage here would resolve against a shrink-to-fit box. */
  width: 300px;
  max-width: 100%;
}
.carto__st {
  position: relative; display: flex; flex-direction: column; justify-content: space-between;
  min-height: 108px; padding: .9rem 1rem;
  border-radius: 6px; border: 1.5px dashed var(--line-2);
  color: var(--ink-4); transition: .3s var(--ease);
}
.carto__st[data-live="1"] {
  border-style: solid; border-color: transparent;
  background: var(--surface); color: #fff;
}
.carto__st[data-live="1"]:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.carto__st[data-live="1"][data-st="vt"] { background: var(--blue); }
.carto__st[data-live="1"][data-st="ma"] { background: #0D5A93; }
.carto__ab {
  font-family: var(--f-display); font-size: clamp(1.5rem, 4vw, 2rem); line-height: 1;
  letter-spacing: -.02em;
}
.carto__nm {
  font-family: var(--f-mono); font-size: var(--t-3xs); letter-spacing: .12em;
  text-transform: uppercase; opacity: .8;
}
.carto__st[data-st="ma"] { grid-area: ma; }
.carto__st[data-st="vt"] { grid-area: vt; }
.carto__st[data-live="1"] .carto__ab::after {
  content: ""; position: absolute; right: .7rem; top: .8rem;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px rgba(224,163,60,.25);
}

/* Chapter card (list form of the same data) */
.chcard {
  position: relative; display: flex; flex-direction: column; gap: .75rem;
  padding: clamp(1.35rem, 2.5vw, 1.75rem);
  border: 1px solid var(--line); border-radius: 6px; background: var(--white);
  transition: .3s var(--ease);
}
.chcard:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.chcard__flag { width: 34px; height: 4px; border-radius: 2px; background: var(--surface); }
.chcard--vt .chcard__flag { background: var(--blue); }
.chcard--ma .chcard__flag { background: #0D5A93; }
.chcard h3 { font-size: var(--t-h4); }
.chcard h3 a::after { content: ""; position: absolute; inset: 0; }
.chcard p { font-size: var(--t-sm); color: var(--ink-3); line-height: 1.6; }

/* --------------------------------------------------------------------------
   16. PEOPLE  →  author / leadership
   -------------------------------------------------------------------------- */
.person { display: flex; flex-direction: column; gap: .9rem; }
.person__ph {
  aspect-ratio: 1; border-radius: 6px; overflow: hidden;
  background: linear-gradient(150deg, var(--blue-dk), var(--surface-dp));
  display: grid; place-items: center; position: relative;
}
.person__ph img { width: 100%; height: 100%; object-fit: cover; }
.person__init {
  font-family: var(--f-display); font-size: clamp(2rem, 5vw, 2.75rem);
  color: rgba(255,255,255,.9); letter-spacing: .02em;
}
/* The scanline texture exists to give the monogram fallback some life — it
   only muddies a real photograph, so it drops out when one is present. */
.person__ph::after {
  content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(to bottom, rgba(255,255,255,.05) 0 1px, transparent 1px 12px);
}
.person__ph:has(img)::after { content: none; }
.person__ph img { position: absolute; inset: 0; }
.person h3 { font-size: 1.125rem; letter-spacing: -.01em; }
.person__role {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .12em;
  text-transform: uppercase; color: var(--chapter); margin-top: .3rem;
}
.person__bio { font-size: var(--t-sm); line-height: 1.6; color: var(--ink-3); margin-top: .5rem; }
/* Board members give a short testimonial on the live site — worth keeping. */
.person__quote {
  margin-top: .75rem; padding-left: .9rem;
  border-left: 2px solid var(--chapter);
  font-family: var(--f-display); font-size: 1rem; line-height: 1.45;
  color: var(--ink-2);
}
.person--vt .person__ph { background: linear-gradient(150deg, var(--blue-dk), var(--surface-dp)); }

/* Full biography. With JS it is lifted into the modal; without JS it simply
   stays on the page and the short card summary steps aside, so the whole bio
   is readable either way. */
.person__full > * + * { margin-top: .75rem; }
.has-js .person__full { display: none; }
html:not(.has-js) .person__bio,
html:not(.has-js) .person > div > .person__quote { display: none; }

.person__more {
  display: none; align-items: center; gap: .4rem; margin-top: .75rem; padding: 0;
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--chapter); text-align: left;
}
.has-js .person__more { display: inline-flex; }
.person__more svg { transition: transform .3s var(--ease); }
/* The card is the target; the button carries the semantics. */
.person { position: relative; }
.person__more::after { content: ""; position: absolute; inset: 0; }
.person:hover .person__more svg { transform: translateX(3px); }
.person__more:focus-visible { outline: none; }
.person:has(.person__more:focus-visible) {
  outline: 2px solid var(--chapter); outline-offset: 6px; border-radius: 4px;
}

/* --------------------------------------------------------------------------
   16b. BIO MODAL  →  full biography for a person card
   -------------------------------------------------------------------------- */
.bmod {
  /* A dialog centres itself on `margin: auto`, which the global reset zeroes. */
  margin: auto;
  width: min(680px, calc(100vw - 2rem)); max-height: min(85vh, 900px);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border: 0; border-radius: 8px; background: var(--white);
  color: var(--ink); box-shadow: var(--shadow-lg); overflow: auto;
  overscroll-behavior: contain;
}
.bmod::backdrop { background: rgba(9, 61, 99, .55); }
/* Scroll lock, shared by every modal on the site. */
body.bio-open, body.modal-open { overflow: hidden; }
.bmod__x {
  position: absolute; top: .9rem; right: .9rem; z-index: 1;
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; color: var(--ink-3); background: var(--paper-2);
  transition: .25s var(--ease);
}
.bmod__x:hover { background: var(--line); color: var(--ink); }
.bmod__hd {
  display: flex; align-items: center; gap: 1.1rem;
  padding-bottom: 1.25rem; margin-bottom: 1.25rem;
  border-bottom: 1px solid var(--line);
}
.bmod__ph {
  flex: none; width: 84px; aspect-ratio: 1; border-radius: 6px; overflow: hidden;
  background: linear-gradient(150deg, var(--blue-dk), var(--surface-dp));
}
.bmod__ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bmod__name { font-size: var(--t-h4); letter-spacing: -.01em; }
.bmod__body { font-size: var(--t-sm); line-height: 1.7; color: var(--ink-2); }
.bmod__body > * + * { margin-top: 1rem; }
.bmod__body .person__quote { font-size: 1.0625rem; }
.bmod__body .person__quote cite {
  display: block; margin-top: .5rem;
  font-family: var(--f-mono); font-size: var(--t-2xs); font-style: normal;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4);
}
@media (max-width: 560px) {
  .bmod__ph { width: 64px; }
}

/* Contact modal — reuses the .bmod box, adds the form chrome. */
.cmod__hd { padding-right: 2.5rem; margin-bottom: 1.25rem; }
.cmod__hd h2 { font-size: var(--t-h4); letter-spacing: -.01em; }
.cmod__hd p { margin-top: .5rem; font-size: var(--t-sm); line-height: 1.6; color: var(--ink-3); }
.cmod .field textarea { min-height: 8.5rem; resize: vertical; }
.cmod__note {
  margin-top: 1rem; font-size: var(--t-sm); line-height: 1.55;
  padding: .8rem 1rem; border-radius: 6px; border-left: 3px solid var(--line-2);
  background: var(--paper-2); color: var(--ink-3);
}
.cmod__note:empty { display: none; }
.cmod__note--bad { border-left-color: var(--signal); color: var(--ink-2); }
.cmod__note--ok  { border-left-color: var(--chapter); color: var(--ink-2); }
/* The bot trap, on every form that posts. Off-canvas rather than display:none —
   a headless crawler that fills every field it can see in the DOM still trips
   it, and no assistive technology reaches it because it is aria-hidden and out
   of the tab order. send.php rejects any submission that arrives with it set. */
.hp {
  position: absolute; left: -5000px; width: 1px; height: 1px;
  overflow: hidden; pointer-events: none;
}

/* --------------------------------------------------------------------------
   17. CTA BAND + SIGNUP  →  forms.signup-fields / forms.donate-options
   -------------------------------------------------------------------------- */
.ctaband {
  background: var(--surface); color: #fff; position: relative; overflow: hidden;
}
.ctaband__in { position: relative; z-index: 2; padding-block: clamp(3rem, 6vw, 5rem); }
.ctaband h2 { max-width: 22ch; }

.signup {
  background: var(--white); border: 1px solid var(--line);
  border-radius: 8px; padding: clamp(1.5rem, 3vw, 2rem);
  box-shadow: var(--shadow);
}
.signup--inv { background: rgba(255,255,255,.06); border-color: var(--line-inv); color: #fff; box-shadow: none; }
.signup h3 { font-size: var(--t-h4); margin-bottom: .5rem; }
.signup p { font-size: var(--t-sm); color: var(--ink-3); line-height: 1.6; }
.signup--inv p { color: rgba(255,255,255,.72); }

.field { display: block; margin-top: 1rem; }
.field span {
  display: block; font-family: var(--f-mono); font-size: var(--t-2xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4);
  margin-bottom: .4rem;
}
.signup--inv .field span { color: rgba(255,255,255,.6); }
.field input, .field select, .field textarea {
  width: 100%; min-height: 48px; padding: .7rem .9rem;
  border: 1px solid var(--line-2); border-radius: var(--radius);
  background: var(--paper); font-size: var(--t-base);
  transition: border-color .2s, box-shadow .2s;
}
.signup--inv .field input, .signup--inv .field select, .signup--inv .field textarea {
  background: rgba(255,255,255,.08); border-color: var(--line-inv); color: #fff;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 0; border-color: var(--chapter);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--chapter) 18%, transparent);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-4); }
/* The default grey placeholder all but disappears on an inverted panel. */
.signup--inv .field input::placeholder { color: rgba(255, 255, 255, .58); }

.checks { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .65rem; }
/* Squared to match the form fields and amount buttons — the pill shape is
   reserved for the Our Work filter chips, which are a different action. */
.check {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .3rem .6rem; border: 1px solid var(--line-2); border-radius: var(--radius);
  font-size: var(--t-sm); cursor: pointer; transition: .2s; min-height: 32px;
  user-select: none; line-height: 1.2;
}
.check:has(input:checked) { background: var(--chapter); border-color: var(--chapter); color: #fff; }
.check input { width: 14px; height: 14px; accent-color: #fff; }

/* State silhouette — chapter mark.
   Inherits currentColor, so it is white on dark panels and picks up the
   chapter color on light ones. One path per state; drop the next state's
   path in beside vt and the component is done. */
.state-mark {
  display: block; margin: 0 auto .9rem;
  height: 4rem; width: auto;
  fill: currentColor;
}
.state-mark--sm { height: 2.25rem; }
.state-mark--lg { height: 5rem; }
.signup__head--center { text-align: center; }
.signup__head--center + form { text-align: left; }

.fineprint { font-size: var(--t-xs); color: var(--ink-4); line-height: 1.55; margin-top: .9rem; }
.signup--inv .fineprint { color: rgba(255,255,255,.5); }

/* Amount picker  →  forms.donate-options */
.amounts { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin-top: .65rem; }
.amount {
  min-height: 56px; border: 1.5px solid var(--line-2); border-radius: var(--radius);
  font-family: var(--f-display); font-size: 1.25rem; transition: .2s var(--ease);
  display: grid; place-items: center;
}
.amount:hover { border-color: var(--signal); }
.amount.is-on { background: var(--signal); border-color: var(--signal); color: #fff; }
.toggle {
  display: inline-flex; padding: 3px; background: var(--paper-2);
  border-radius: 100px; gap: 2px; margin-top: .65rem;
}
.toggle button {
  padding: .5rem 1.1rem; border-radius: 100px; font-size: var(--t-sm);
  font-weight: 600; color: var(--ink-3); transition: .25s var(--ease); min-height: 40px;
}
.toggle button.is-on { background: var(--white); color: var(--ink); box-shadow: var(--shadow); }

/* Pull quote  →  shared.pull-quote */
.pullquote {
  border-left: 3px solid var(--chapter);
  padding: .25rem 0 .25rem clamp(1.25rem, 3vw, 2rem);
  margin-block: clamp(2rem, 4vw, 3rem);
}
.pullquote p {
  font-family: var(--f-display); font-size: clamp(1.25rem, 1.8vw + .9rem, 1.75rem);
  line-height: 1.35; letter-spacing: -.015em; color: var(--ink);
}
.pullquote cite {
  display: block; font-style: normal; margin-top: .9rem;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4);
}

/* --------------------------------------------------------------------------
   18. ARTICLE  →  content-item detail
   -------------------------------------------------------------------------- */
.artwrap { display: grid; gap: clamp(2rem, 5vw, 4rem); }
@media (min-width: 1060px) {
  .artwrap { grid-template-columns: minmax(0, 1fr) 264px; align-items: start; }
}

.prose { max-width: 70ch; font-size: 1.1875rem; line-height: 1.75; color: var(--ink-2); }
.prose > * + * { margin-top: 1.5rem; }
/* Direct child only. `.prose p:first-of-type` also matched the first paragraph
   of any nested panel, which struck a drop cap into the middle of the page. */
.prose > p:first-of-type::first-letter {
  float: left; font-family: var(--f-display); font-size: 3.8em;
  line-height: .82; padding: .06em .12em 0 0; color: var(--chapter);
}
/* A drop cap is ~3 lines tall. If the opening paragraph is shorter than that,
   the float bleeds into the paragraph below and indents its first lines, so
   the generator marks short openers to opt out. */
.prose p.nocap::first-letter {
  float: none; font-family: inherit; font-size: inherit;
  line-height: inherit; padding: 0; color: inherit;
}
.prose h2 {
  font-size: var(--t-h3); margin-top: 3rem; color: var(--ink);
  scroll-margin-top: calc(var(--hdr-h-stuck) + 46px);
}
.prose h3 { font-size: var(--t-h4); margin-top: 2.25rem; color: var(--ink); scroll-margin-top: calc(var(--hdr-h-stuck) + 46px); }
.prose strong { font-weight: 600; color: var(--ink); }
.prose a { color: var(--chapter); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.prose .quote-by {
  margin-top: 1.1rem; padding-left: 1.5rem;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4);
}
/* Key-points panel — the plain-language summary that opens a policy page.
   Inside .prose, so it inherits the measure but opts out of the drop cap. */
.pkey {
  border: 1px solid var(--line); border-left: 3px solid var(--chapter);
  border-radius: 6px; background: var(--paper-2);
  padding: clamp(1.25rem, 3vw, 1.75rem);
  font-size: var(--t-base); line-height: 1.65;
}
.pkey__h {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-4); margin-bottom: .9rem;
}
.pkey ul { list-style: none; padding: 0; display: grid; gap: .7rem; }
.pkey li { padding-left: 1.4rem; position: relative; }
.pkey li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--chapter);
}
.pkey__f { margin-top: 1.1rem; font-size: var(--t-sm); color: var(--ink-3); }
/* The drop cap keys off the first paragraph in .prose; this panel's paragraphs
   are not that paragraph, but ::first-letter would still catch one if the
   panel led the page, so it is neutralised here rather than per-instance. */
.pkey p::first-letter {
  float: none; font-family: inherit; font-size: inherit;
  line-height: inherit; padding: 0; color: inherit;
}

.prose blockquote {
  border-left: 3px solid var(--chapter); padding-left: 1.5rem;
  font-family: var(--f-display); font-size: 1.375rem; line-height: 1.45; color: var(--ink);
}
.prose ul, .prose ol { padding-left: 1.35rem; }
.prose li + li { margin-top: .6rem; }
.prose hr { border: 0; border-top: 1px solid var(--line); margin-block: 2.5rem; }
.prose figcaption {
  font-family: var(--f-mono); font-size: var(--t-xs); color: var(--ink-4);
  margin-top: .6rem; letter-spacing: .04em;
}
.prose figure img { display: block; width: 100%; height: auto; border-radius: var(--radius); }

/* Provenance line for syndicated work (op-eds, letters) that carries no banner
   image. A div, not a p, so it never steals the .prose drop cap. */
.artnote {
  font-family: var(--f-mono); font-size: var(--t-xs); line-height: 1.6;
  letter-spacing: .03em; color: var(--ink-3);
  border-left: 2px solid var(--line-2); padding: .1rem 0 .1rem 1rem;
}
.artnote a { color: var(--chapter); }

/* Reading progress */
.progress {
  position: fixed; top: 0; left: 0; height: 3px; width: 0%;
  background: var(--chapter); z-index: 200; transition: width .1s linear;
}

/* Sticky rail */
.rail { position: sticky; top: calc(var(--hdr-h-stuck) + 34px); display: grid; gap: 2rem; }
.rail__h {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-4);
  padding-bottom: .75rem; border-bottom: 1px solid var(--line); margin-bottom: .9rem;
}
.toc { list-style: none; padding: 0; display: grid; gap: .1rem; }
.toc a {
  display: block; padding: .45rem 0 .45rem .8rem; font-size: var(--t-sm);
  line-height: 1.4; color: var(--ink-4); border-left: 2px solid var(--line);
  transition: .2s;
}
.toc a:hover { color: var(--ink); }
.toc a.is-on { color: var(--chapter); border-color: var(--chapter); font-weight: 500; }

.share { display: flex; gap: .5rem; }
.share a {
  width: 40px; height: 40px; display: grid; place-items: center;
  border: 1px solid var(--line-2); border-radius: var(--radius);
  color: var(--ink-3); transition: .2s;
}
.share a:hover { background: var(--surface); border-color: var(--surface); color: #fff; }

.byline {
  display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
  padding-block: 1.5rem; border-block: 1px solid var(--line);
}
/* Each author is one unit so a multi-author byline never splits mid-person. */
.byline__person { display: flex; align-items: center; gap: .75rem; }
.byline__av {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  background: linear-gradient(150deg, var(--blue-dk), var(--surface-dp));
  display: grid; place-items: center; color: #fff;
  font-family: var(--f-display); font-size: 1.0625rem;
}
/* Stack name over role rather than relying on whitespace between the spans —
   the markup is generated, so it cannot depend on a source-formatting space. */
.byline__person > span:last-child { display: grid; gap: .1rem; }
.byline__nm { font-weight: 600; font-size: var(--t-base); }
.byline__ro { font-family: var(--f-mono); font-size: var(--t-xs); color: var(--ink-4); letter-spacing: .05em; }

/* Download / resource card */
.resource {
  display: flex; align-items: center; gap: 1rem;
  padding: 1.1rem 1.25rem; border: 1px solid var(--line);
  border-radius: 6px; background: var(--white); transition: .25s var(--ease);
}
.resource:hover { border-color: var(--chapter); transform: translateY(-2px); box-shadow: var(--shadow); }
.resource__ic {
  width: 42px; height: 42px; flex: none; border-radius: var(--radius);
  background: var(--chapter-lt); color: var(--chapter-dk);
  display: grid; place-items: center;
}
/* Title and meta each own their line — as inline spans they ran together. */
.resource__t { display: block; font-weight: 600; font-size: var(--t-sm); line-height: 1.4; }
.resource__s {
  display: block; font-family: var(--f-mono); font-size: var(--t-2xs);
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-4); margin-top: .25rem;
}

/* --------------------------------------------------------------------------
   19. TIMELINE / TRACKER
   -------------------------------------------------------------------------- */
.track { border-top: 1px solid var(--line); }
.track__row {
  display: grid; gap: .5rem 1.25rem; padding: 1.15rem 0;
  border-bottom: 1px solid var(--line); align-items: center;
}
@media (min-width: 780px) { .track__row { grid-template-columns: 90px 1fr 150px 110px; } }
.track__bill { font-family: var(--f-mono); font-size: var(--t-sm); font-weight: 500; color: var(--chapter); }
.track__t { font-size: var(--t-sm); line-height: 1.45; font-weight: 500; }
.track__st {
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-4);
}
.pos {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--f-mono); font-size: var(--t-2xs); letter-spacing: .1em; text-transform: uppercase;
  padding: .25rem .5rem; border-radius: 3px;
}
.pos::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pos--oppose  { background: var(--signal-lt); color: var(--signal-dk); }
.pos--support { background: #E7F1EC; color: #215037; }
.pos--watch   { background: var(--paper-2); color: var(--ink-3); }

/* --------------------------------------------------------------------------
   20. FOOTER  →  global.footerNav
   -------------------------------------------------------------------------- */
/* The footer runs one step larger than the rest of the small type — legibility
   matters here because it carries the contact details and legal identity.
   --ftr-up is the single dial for that; every footer size derives from it. */
.ftr {
  --ftr-up: 1.15;
  background: var(--surface-dp); color: rgba(255,255,255,.7);
  font-size: calc(var(--t-sm) * var(--ftr-up));
}
.ftr__main { padding-block: clamp(3rem, 6vw, 4.5rem); }
.ftr__grid { display: grid; gap: clamp(2rem, 4vw, 3rem); }
@media (min-width: 720px)  { .ftr__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .ftr__grid { grid-template-columns: 1.5fr repeat(3, 1fr); } }

.ftr h4 {
  font-family: var(--f-mono); font-size: calc(var(--t-2xs) * var(--ftr-up));
  letter-spacing: .14em;
  text-transform: uppercase; color: rgba(255,255,255,.45); margin-bottom: 1rem;
}
.ftr ul { list-style: none; padding: 0; display: grid; gap: .6rem; }
.ftr a:hover { color: #fff; }
.ftr__lock { display: flex; align-items: center; gap: .75rem; margin-bottom: 1.25rem; }
.ftr__lock img { width: 76px; height: 76px; border-radius: 50%; }
.ftr__501 {
  display: inline-block; margin-top: 1.25rem; padding: .5rem .75rem;
  border: 1px solid var(--line-inv); border-radius: var(--radius);
  font-family: var(--f-mono); font-size: calc(var(--t-2xs) * var(--ftr-up));
  letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255,255,255,.6);
}
.ftr__social { display: flex; gap: .5rem; margin-top: 1.5rem; }
.ftr__social a {
  width: 40px; height: 40px; display: grid; place-items: center;
  border: 1px solid var(--line-inv); border-radius: var(--radius); transition: .2s;
}
.ftr__social a:hover { background: #fff; color: var(--ink); border-color: #fff; }
.ftr__bot {
  border-top: 1px solid var(--line-inv); padding-block: 1.5rem;
  display: flex; flex-wrap: wrap; gap: 1rem; align-items: center;
  font-size: calc(var(--t-xs) * var(--ftr-up)); color: rgba(255,255,255,.45);
}
.ftr__bot nav { display: flex; gap: 1.25rem; flex-wrap: wrap; margin-left: auto; }

/* --------------------------------------------------------------------------
   21. MOTION
   -------------------------------------------------------------------------- */
.rv { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.rv.is-in { opacity: 1; transform: none; }
.rv-d1 { transition-delay: .07s; }
.rv-d2 { transition-delay: .14s; }
.rv-d3 { transition-delay: .21s; }
.rv-d4 { transition-delay: .28s; }
.rv-d5 { transition-delay: .35s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  .rv { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   22. PRINT
   -------------------------------------------------------------------------- */
@media print {
  .hdr, .netbar, .announce, .mbar, .rail, .ctaband, .ftr, .filters { display: none !important; }
  body { background: #fff; font-size: 11pt; }
  .prose { max-width: none; }
  a::after { content: " (" attr(href) ")"; font-size: 9pt; color: #666; }
}


