/* State-compliance preview styles — internal preview only (see build/build-state-pages-preview.mjs).
   Extends the site's existing Ledger visual system (DESIGN.md) rather than inventing a new one:
   same hard-shadow/flat card families, same badge shape, same Archivo/IBM Plex Mono pairing and
   green/amber/terracotta status vocabulary. State pages no longer load course.css at all (see
   build/lib/page-chrome.mjs's includeCourseStyles option) — this file is the page's only
   stylesheet besides Google Fonts, so the base reset and nav/breadcrumb/footer chrome rules
   (.nav, .crumbs, .footer) are defined here too, copied verbatim from course.css's own rules so
   that chrome renders identically without depending on that file. The one deliberate divergence is
   .crumbs, which drops course.css's opacity layer for the contrast reason recorded on that rule.

   Container widths follow DESIGN.md's own container/container-wide direction: single-column
   pages cap at ~1000px; the two-column state-page shell (main + sticky sidebar) widens to
   ~1240px at >=1040px, where the sidebar has room to sit beside a ~760-820px main column. */

/* ---- Base reset + chrome (previously inherited from course.css; copied verbatim from that
   file's own reset/nav/breadcrumb/footer rules — course.css itself is no longer loaded). ---- */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Archivo', sans-serif; background: #fff; color: #1A1F18; line-height: 1.65; }

.nav { background: #fff; border-bottom: 1px solid #E2E6DF; position: sticky; top: 0; z-index: 10; }
.nav-inner { max-width: 1240px; margin: 0 auto; padding: 16px 44px; display: flex; align-items: center; justify-content: space-between; }
.logo { font-weight: 800; font-size: 20px; letter-spacing: -.02em; color: #0B0F0A; text-decoration: none; }
.logo mark { background: #FAC700; color: #0B0F0A; padding: 0 3px; }
.nav-right { display: flex; align-items: center; gap: 20px; }
.nav-back { font-family: 'IBM Plex Mono',monospace; font-size: 12px; color: #5A6457; text-decoration: none; }
.nav-back:hover { color: #0B0F0A; }

/* The muted breadcrumb look comes from colour alone. course.css does it with `opacity: .5` on the
   whole trail, and at 12px that is a WCAG AA failure no colour value can fix: composited over the
   #FEFDF5 page it puts the links at 2.16:1, the current crumb at 3.61:1 and the separator at 1.92:1
   against a 4.5:1 minimum, and even pure #0B0F0A ink only reaches 3.61:1 through a .5 alpha. So the
   layer is gone here and the separator is darkened from course.css's #6B7B63, which measured 4.44:1
   on its own and would have failed by 0.06 even with the opacity removed. Measured now: links
   6.06:1, separator 7.95:1, current crumb 18.94:1. Do not reintroduce the opacity to make the trail
   quieter — pick a lighter colour and compute the ratio (STATE_DEPLOYMENT_MASTER.md 2.1, 25.1). */
.crumbs { max-width: 1000px; margin: 0 auto; padding: 20px 44px 0; font-family: 'IBM Plex Mono',monospace; font-size: 12px; color: #5A6457; font-style: italic; }
.crumbs.crumbs-wide { max-width: 1240px; }
.crumbs a { color: #5A6457; text-decoration: none; }
.crumbs a:hover { color: #155138; }
.crumb-sep { margin: 0 8px; color: #4A5247; }
.crumb-lead { margin: 0 8px 0 0; }
.crumb-current { color: #0B0F0A; }

.footer { background: #0B0F0A; color: #9DA89A; padding: 28px 44px; font-family: 'IBM Plex Mono',monospace; font-size: 10px; letter-spacing: .04em; line-height: 1.6; text-align: center; }
.footer a { color: #9DB89A; }

@media (max-width: 640px) {
  .nav-inner { padding: 14px 20px; }
  .crumbs { padding: 16px 20px 0; }
}

/* ---- Internal preview banner ---- */

.preview-banner {
  background: #FBF1EE;
  color: #9A4A2F;
  border: 1px solid #9A4A2F;
  font-family: 'IBM Plex Mono',monospace;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  padding: 10px 16px;
}

/* ---- Shared status badges (research verification: source-verified / review-required) ----
   This is ONE of two distinct status vocabularies on this page — the other is the requirement-
   status chip further down, which deliberately does NOT reuse this green/amber palette. Text
   label is always present alongside the color dot; never color alone. */

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'IBM Plex Mono',monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 4px 8px;
  border-radius: 2px;
  white-space: nowrap;
}
.status-badge::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 999px;
  display: inline-block;
  flex: none;
}
.status-badge-verified {
  background: #E8EFE4;
  color: #155138;
}
.status-badge-verified::before { background: #155138; }
.status-badge-review {
  background: #FCFBE8;
  color: #7A7440;
}
.status-badge-review::before { background: #8A6D1E; }
.status-badge-neutral {
  background: #F4F6F3;
  color: #4A5247;
}
.status-badge-neutral::before { background: #5A6457; }

/* ---- Requirement-status chip (what the law/agency requires) ----
   Deliberately neutral black/gray, never the green/amber verification palette above — this is a
   different question ("what must you do") from research-verification ("how sure are we"). Shape
   (solid/outline/ghost) plus the humanized text label carries the distinction, not color. */

.requirement-chip {
  display: inline-block;
  font-family: 'IBM Plex Mono',monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 9px;
  border-radius: 2px;
  margin-bottom: 10px;
}
.requirement-chip-solid {
  background: #0B0F0A;
  color: #FFFFFF;
}
.requirement-chip-outline {
  background: #FFFFFF;
  color: #0B0F0A;
  border: 1.5px solid #0B0F0A;
  padding: 2.5px 7.5px;
}
.requirement-chip-ghost {
  background: #F4F6F3;
  color: #5A6457;
  border: 1px dashed #C8CEC6;
  padding: 3px 8px;
}

/* ---- Effective-date chip (when the rule takes legal effect) ----
   A third vocabulary, deliberately sharing neither the verification badge's green/amber nor the
   requirement chip's black/gray: those answer "how sure are we" and "what must you do", this one
   answers "is this in force yet". Sits immediately after the requirement chip on a
   future-effective fact so the card cannot read as currently operative.

   Meaning never rests on colour: the chip's own text spells out "Takes effect <date>", and the
   dashed border repeats the not-yet-in-force signal for anyone who cannot distinguish the tint.
   Contrast computed, not eyeballed: #17505F on #EDF4F7 is 8.04:1, well clear of the 4.5:1 AA
   minimum for this 11px text, with headroom per STATE_DEPLOYMENT_MASTER.md 2.1 section 25.1. */
.effective-date-chip {
  display: inline-block;
  font-family: 'IBM Plex Mono',monospace;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2.5px 7.5px;
  border-radius: 2px;
  margin: 0 0 10px 8px;
  background: #EDF4F7;
  color: #17505F;
  border: 1.5px dashed #17505F;
  white-space: normal;
  overflow-wrap: break-word;
  max-width: 100%;
}

/* ---- /states/ directory page ---- */

.states-dir { max-width: 1000px; margin: 0 auto; padding: 24px 44px 80px; }
.states-dir-eyebrow {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .16em;
  color: #155138; margin-bottom: 14px;
}
.states-dir h1 {
  font-weight: 800; font-size: clamp(28px, 4vw, 44px); letter-spacing: -.02em;
  line-height: 1.15; margin: 0 0 18px; color: #0B0F0A;
}
.states-dir-intro { font-size: 16px; color: #4A5247; line-height: 1.6; max-width: 680px; margin-bottom: 12px; }
.states-dir-progress {
  font-family: 'IBM Plex Mono',monospace; font-size: 14px; font-weight: 600; color: #0B0F0A; margin-bottom: 36px;
}

.state-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 48px;
}
.state-card {
  display: block;
  background: #F4F6F3;
  color: #0B0F0A;
  border: 1px solid #0B0F0A;
  box-shadow: 6px 6px 0 #0B0F0A;
  padding: 20px;
  text-decoration: none;
  transition: transform .12s, box-shadow .12s;
}
.state-card:hover, .state-card:focus-visible {
  transform: translate(-2px, -2px);
  box-shadow: 8px 8px 0 #0B0F0A;
}
.state-card:focus-visible { outline: 2px solid #155138; outline-offset: 2px; }
.state-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.state-card-name { font-family: Archivo,sans-serif; font-weight: 700; font-size: 19px; color: #0B0F0A; flex: 1; min-width: 0; }
.state-card-outline { width: 84px; height: 84px; flex: 0 0 auto; color: #8fa99b; pointer-events: none; }
.state-card-outline path {
  fill: currentColor; fill-opacity: .025; stroke: currentColor; stroke-opacity: .9;
  stroke-width: 2; vector-effect: non-scaling-stroke;
}
.state-card:hover .state-card-outline path, .state-card:focus-visible .state-card-outline path {
  fill-opacity: .05; stroke-opacity: 1;
}
.state-card-status { margin-bottom: 14px; }
.state-card-stats {
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; color: #4A5247;
  display: flex; flex-direction: column; gap: 4px;
}
.state-card-stats dt { display: inline; }
.state-card-stats dd { display: inline; margin: 0; font-weight: 600; color: #0B0F0A; }
.state-card-stat-row { display: flex; justify-content: space-between; gap: 8px; border-bottom: 1px dotted #C8CEC6; padding-bottom: 4px; }
.state-card-cta {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; font-weight: 600; letter-spacing: .04em;
  color: #155138; margin-top: 14px; padding-top: 12px; border-top: 1px solid #E2E6DF;
}

/* Collapsed by default — 47 non-linked states no longer dominate the page; the summary is the
   only always-visible affordance, restrained but clearly interactive (Ledger mono-label + caret). */
.remaining-states-details {
  border-top: 1px solid #E2E6DF;
  padding-top: 24px;
}
.remaining-states-details summary {
  font-family: Archivo,sans-serif; font-weight: 700; font-size: 19px; color: #0B0F0A;
  cursor: pointer; list-style: revert;
}
.remaining-states-details summary:hover { color: #155138; }
.remaining-states-details[open] summary { margin-bottom: 16px; }
.state-list-plain {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 28px;
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; color: #5A6457;
}
.state-list-plain li {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border-left: 2px solid #C8CEC6;
  padding: 3px 0 3px 12px;
  white-space: nowrap;
}
.badge-not-researched {
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: #5A6457;
}

@media (min-width: 900px) {
  .state-list-plain { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ---- Individual state page ---- */

.state-page { max-width: 1000px; margin: 0 auto; padding: 24px 44px 80px; }
.state-page-eyebrow {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .16em;
  line-height: 1.3; color: #155138; margin-bottom: 14px;
}
.state-page h1 {
  font-weight: 800; font-size: clamp(28px, 4vw, 44px); letter-spacing: -.02em;
  line-height: 1.15; margin: 0 0 20px; color: #0B0F0A;
  scroll-margin-top: 84px;
}

/* Compliance-update article titles are typically much longer sentences than a state name
   ("Massachusetts Nonprofit Compliance Guide: Key Requirements and Filing Deadlines" vs.
   "Massachusetts") — the state-page h1 rule above (800 weight, 44px cap) reads as an oversized,
   overweight block once it wraps across 2-3 lines at that size. This is scoped to
   .update-article (the wrapper div update-article.mjs's renderUpdateArticle puts on the page),
   NOT a change to .state-page h1 itself — every /states/<slug>/ page is completely unaffected.
   clamp() keeps one responsive rule instead of several fragile fixed breakpoints: ~30px at
   375-430px, ~37px at 768px, ~42-47px at 1024-1280px, ~50px at 1440px+, capped at 52px. */
.update-article h1 {
  font-weight: 700;
  font-size: clamp(30px, 1.9vw + 23px, 52px);
  letter-spacing: -.015em;
  line-height: 1.1;
  max-width: 880px;
  margin: 0 0 22px;
}

.state-status-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-bottom: 16px; }
.state-status-row-meta { font-family: 'IBM Plex Mono',monospace; font-size: 13px; color: #5A6457; }

/* font-weight: 500 is explicit here as documentation, not a visual change: Archivo is loaded on
   this site only at wght 500/600/700/800 (see page-chrome.mjs's <link>), so an unset/400 weight
   was already being silently substituted to the nearest loaded weight (500) — see the compliance-
   update card typography fix for the same reasoning. Making it explicit means this paragraph's
   weight is a deliberate choice, not an inheritance accident, everywhere this class is used
   (state-page fact answers and hero sentences, and every update-article body paragraph below). */
.state-direct-answer {
  font-size: 17px; font-weight: 500; color: #0B0F0A; line-height: 1.65; max-width: 680px; margin-bottom: 14px;
}
.state-hero-stats {
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; color: #4A5247; margin-bottom: 20px;
}

/* Full, unmodified research summary — one click away, kept out of the hero's default (closed)
   height so the hero stays compact. Reuses .state-direct-answer's own typography for the
   expanded text so it reads identically to the generated preview sentence above it. */
.research-overview-details {
  margin-bottom: 28px; border: 1px solid #E2E6DF; padding: 4px 16px;
}
.research-overview-details summary {
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; font-weight: 600; letter-spacing: .04em;
  color: #155138; cursor: pointer; padding: 10px 0;
}
.research-overview-details[open] summary { border-bottom: 1px solid #E2E6DF; margin-bottom: 12px; }
.research-overview-full { padding-bottom: 14px; margin-bottom: 0; }

/* Mobile/tablet section nav (native <details>, no JS). Hidden at >=1040px, where the sticky
   sidebar's "On this page" panel takes over. */
.mobile-toc { margin-bottom: 28px; border: 1px solid #E2E6DF; padding: 4px 16px; }
.mobile-toc summary {
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; font-weight: 600; letter-spacing: .04em;
  color: #155138; cursor: pointer; padding: 10px 0;
}
.mobile-toc[open] summary { border-bottom: 1px solid #E2E6DF; margin-bottom: 8px; }
.mobile-toc .toc-list { padding-bottom: 12px; }

/* ---- Two-column shell: main content + sticky sidebar (>=1040px) ---- */

.state-shell { display: block; }
.state-sidebar { display: none; }

@media (min-width: 1040px) {
  .state-page { max-width: 1240px; }
  .state-shell {
    display: grid;
    grid-template-columns: minmax(0, 820px) 288px;
    column-gap: 48px;
    align-items: start;
  }
  .state-main { min-width: 0; }
  .state-sidebar {
    display: flex;
    flex-direction: column;
    gap: 20px;
    position: sticky;
    top: 84px;
  }
  .mobile-toc { display: none; }
}

.sidebar-panel {
  border: 1px solid #E2E6DF;
  padding: 16px;
}
.sidebar-panel-title {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: #5A6457; margin-bottom: 12px;
}
.snapshot-list { display: flex; flex-direction: column; gap: 10px; font-family: 'IBM Plex Mono',monospace; font-size: 13px; line-height: 1.4; }
/* flex-wrap: wrap is a safety net, not a visual change for the common case: a short label +
   short value (e.g. "Facts" / "72") still sits on one line exactly as before. It only matters
   once a row's content genuinely can't fit — see .snapshot-row-wrap below for the one row
   (Verification) that reliably doesn't. */
.snapshot-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; }
.snapshot-row dt { color: #5A6457; margin: 0; flex: 1 1 auto; min-width: 0; }
/* flex: none + nowrap so a value like "July 19, 2026" always wins the row's space and never
   wraps — if the row is ever tight, the label (dt) wraps first, not the value. */
.snapshot-row dd { color: #0B0F0A; font-weight: 600; margin: 0; text-align: right; flex: none; white-space: nowrap; }

/* Verification's dd holds a .status-badge (with its own sitewide white-space: nowrap), not
   plain text — the "value never wraps" rule above is exactly what let "MIXED VERIFICATION
   STATUS" push past the sidebar's ~256px inner width and overflow the panel. Applied only to
   this one row (see render-update-article.mjs's renderSidebar): the label goes on its own line,
   the badge becomes a full-width second line, left-aligned, and can wrap internally as a last
   resort on an extremely narrow panel. Every other snapshot row (dates, counts, state list)
   keeps the label-left/value-right single line above unchanged. */
.snapshot-row-wrap dd {
  flex: 1 1 100%;
  min-width: 0;
  white-space: normal;
  text-align: left;
}
.snapshot-row-wrap dd .status-badge { max-width: 100%; white-space: normal; overflow-wrap: break-word; }

.toc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.toc-list a {
  font-weight: 500; font-size: 14px; line-height: 1.4; color: #0B0F0A; text-decoration: none; border-bottom: 1px solid transparent;
}
.toc-list a:hover { color: #155138; border-bottom-color: #155138; }

.back-to-top {
  display: inline-block; font-family: 'IBM Plex Mono',monospace; font-size: 12px; font-weight: 600;
  color: #155138; text-decoration: none;
}
.back-to-top-inline { margin: 8px 0 24px; }
.back-to-top-inline a { font-family: 'IBM Plex Mono',monospace; font-size: 12px; font-weight: 600; color: #155138; text-decoration: none; }
.back-to-top:hover, .back-to-top-inline a:hover { text-decoration: underline; }

.state-section { margin-bottom: 56px; scroll-margin-top: 84px; }
/* 700 (not the previous 800) — still clearly the boldest text in each section, without the
   heaviest weight tier. Shared by every state-page section heading ("At a Glance", "Compliance
   Timeline", ...) and every update-article section heading ("Key Takeaways", each body section,
   "Official Sources", ...) — one rule, so both stay visually consistent with each other. */
.state-section h2 {
  font-family: Archivo,sans-serif; font-weight: 700; font-size: 28px; letter-spacing: -.01em;
  line-height: 1.2; color: #0B0F0A; margin: 0 0 18px; padding-top: 12px; border-top: 1px solid #E2E6DF;
}

/* At-a-glance: Requirement / Requirement status / Fee / Deadline / Research status */
.at-a-glance-wrap { position: relative; overflow-x: auto; margin-bottom: 12px; }
.at-a-glance {
  width: 100%; border-collapse: collapse; font-size: 14px; min-width: 640px;
}
.at-a-glance th, .at-a-glance td {
  text-align: left; padding: 10px 14px; border-bottom: 1px solid #E2E6DF; vertical-align: top;
}
.at-a-glance th {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: #5A6457;
}
.at-a-glance td.at-a-glance-requirement { font-weight: 700; color: #0B0F0A; }
.at-a-glance td.at-a-glance-requirement a { color: inherit; text-decoration: none; border-bottom: 1px solid #C8CEC6; }
.at-a-glance td.at-a-glance-requirement a:hover { border-bottom-color: #0B0F0A; }
.at-a-glance td { color: #4A5247; }

/* Below 768px: reflow the table into stacked accessible cards via CSS + data-label, not
   horizontal scroll. role= attributes on the markup keep the ARIA table semantics intact even
   though the visual layout becomes block-based. */
@media (max-width: 767px) {
  .at-a-glance-wrap { overflow-x: visible; }
  .at-a-glance, .at-a-glance thead, .at-a-glance tbody, .at-a-glance th, .at-a-glance td, .at-a-glance tr {
    display: block;
    width: 100%;
  }
  /* The desktop rule above sets min-width: 640px for the real table layout — that must not
     survive into the mobile card reflow, or every card is forced to 640px regardless of the
     390px viewport it's actually rendered in. This was the cause of the reported overflow. */
  .at-a-glance { min-width: 0; max-width: 100%; }
  .at-a-glance thead { position: absolute; inset: 0; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .at-a-glance tr { border: 1px solid #E2E6DF; padding: 12px 14px; margin-bottom: 14px; }
  .at-a-glance td { border-bottom: none; padding: 4px 0; }
  .at-a-glance td::before {
    content: attr(data-label); display: block; font-family: 'IBM Plex Mono',monospace; font-size: 11px;
    font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: #5A6457; margin-bottom: 2px;
  }
}

/* Compliance timeline: one continuous spine, one node per lifecycle bucket */
.timeline { position: relative; display: flex; flex-direction: column; gap: 24px; }
.timeline::before {
  content: '';
  position: absolute;
  left: 9px; top: 10px; bottom: 10px;
  width: 2px;
  background: #C8CEC6;
}
.timeline-bucket {
  position: relative;
  display: grid;
  grid-template-columns: 20px 1fr;
  column-gap: 14px;
}
.timeline-node {
  grid-column: 1; grid-row: 1;
  width: 12px; height: 12px; margin-top: 4px;
  border-radius: 999px;
  background: #155138;
  border: 2px solid #FFFFFF;
  position: relative;
  z-index: 1;
  justify-self: center;
}
.timeline-bucket-label {
  grid-column: 2; grid-row: 1;
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: #155138; padding-top: 2px;
}
.timeline-items {
  grid-column: 2; grid-row: 2; margin-top: 8px;
  list-style: none; padding: 0; display: flex; flex-direction: column; gap: 10px;
}
.timeline-item { font-size: 14px; line-height: 1.45; color: #0B0F0A; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.timeline-item a { color: #155138; text-decoration: underline; }
.timeline-item-status { font-family: 'IBM Plex Mono',monospace; font-size: 12px; line-height: 1.45; color: #5A6457; }
.timeline-review-marker {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; line-height: 1.45; font-weight: 600; letter-spacing: .04em;
  color: #7A7440;
}
.timeline-review-marker::before { content: '⚑ '; }

/* Fact cards */
.fact-list { display: flex; flex-direction: column; gap: 24px; }
.fact-card {
  background: #FFFFFF;
  border: 1px solid #E2E6DF;
  border-radius: 2px;
  padding: 22px;
  scroll-margin-top: 84px;
}
.fact-card-review {
  border-color: #8A6D1E;
  background: #FEFDF5;
}
/* Rail for a future-effective fact. Structural rather than a status colour of its own: it ties
   the .effective-date-chip to the card it belongs to while scrolling a long section, and it is
   never the only signal — the chip spells out the date in words. Declared after
   .fact-card-review deliberately, so a fact that is BOTH review_required and future-effective
   keeps the amber card treatment and still shows the teal not-yet-in-force rail, instead of
   .fact-card-review's border-color quietly repainting the left edge. */
.fact-card-future { border-left: 3px solid #17505F; }
.fact-card-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
  margin-bottom: 10px; flex-wrap: wrap;
}
.fact-card-label { font-family: Archivo,sans-serif; font-weight: 700; font-size: 19px; color: #0B0F0A; }
/* Same reason as .fact-key-fact dd below: several approved answers, exceptions, and
   consequences quote a form name or a URL with no break opportunity. */
.fact-card-answer { font-size: 15px; color: #0B0F0A; line-height: 1.65; margin-bottom: 10px; overflow-wrap: anywhere; }
.fact-card-provenance {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; color: #5A6457; margin: 4px 0 10px;
}
.fact-card-notes { margin: 0 0 10px; padding-left: 18px; font-size: 14px; color: #4A5247; }
.fact-card-notes li { margin-bottom: 4px; overflow-wrap: anywhere; }
.fact-card-notes-label {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: #5A6457; margin-bottom: 4px;
}
.fact-card-public-note {
  font-size: 13px; font-style: italic; color: #5A6457; border-left: 2px solid #E2E6DF;
  padding: 2px 0 2px 12px; margin-bottom: 10px;
}

/* Verification note — review_required facts only, shown just before the official-source
   component. Reuses the same amber "still verifying" vocabulary as the badge/section rail
   (never red/error), distinct from the neutral-gray .fact-card-public-note above. */
.fact-card-verification-note {
  font-size: 13px; font-style: italic; color: #7A7440; border-left: 2px solid #8A6D1E;
  padding: 2px 0 2px 12px; margin: 4px 0 10px;
}

/* Compact key-facts area: deadline / fee / filing agency / filing frequency */
.fact-key-facts {
  display: flex; flex-wrap: wrap; gap: 6px 28px; margin: 0 0 12px;
  padding: 10px 0; border-top: 1px solid #E2E6DF; border-bottom: 1px solid #E2E6DF;
}
/* min-width keeps two short fields side by side; max-width: 100% stops a field whose approved
   text contains a long unbreakable token (several states name a portal by its full URL inside
   "Official form or portal") from widening the flex row past the card. Without the pair, that one
   field pushed the whole document into horizontal scrolling at 390px — see the overflow-wrap rule
   below, which is what actually breaks the URL. */
.fact-key-fact { min-width: 140px; max-width: 100%; }
.fact-key-fact dt {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: #5A6457; margin: 0 0 2px;
}
/* Long URLs and long agency/form names wrap rather than overflow (STATE_DEPLOYMENT_MASTER.md 2.1,
   section 29). `anywhere` rather than `break-word` because these values include raw https:// URLs
   with no break opportunity at all; ordinary prose in the same field is unaffected, since the rule
   only takes effect when a line cannot otherwise fit. Nothing here clips or truncates: the full
   approved text still renders, on as many lines as it needs. */
.fact-key-fact dd { font-size: 14px; color: #0B0F0A; margin: 0; overflow-wrap: anywhere; }
/* A portal address the approved research states inside "How to comply" or "Official form or portal"
   (see render-state-page.mjs's linkifyApproved). Same green-underline treatment as every other
   official-source link on the card, so a filing destination looks and behaves the same whether the
   research put it in forms[] or in prose. Contrast computed: #155138 is 9.27:1 on the ordinary card
   and 9.08:1 on the amber verification-in-progress card, both well clear of the 4.5:1 AA minimum. */
.fact-key-fact dd a { color: #155138; text-decoration: underline; overflow-wrap: anywhere; }
.fact-key-fact-list { list-style: none; margin: 0; padding: 0; font-size: 14px; color: #0B0F0A; }
.fact-key-fact-list li { margin-bottom: 2px; overflow-wrap: anywhere; }

/* Citations: compact always-visible line + expandable full detail */
.fact-card-citation-compact {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; margin: 10px 0 0;
  padding-top: 10px; border-top: 1px dashed #C8CEC6;
}
.fact-card-citation-compact a { color: #155138; text-decoration: underline; overflow-wrap: anywhere; }

.citation-details { margin-top: 8px; font-family: 'IBM Plex Mono',monospace; font-size: 12px; color: #5A6457; }
.citation-details summary {
  cursor: pointer; color: #155138; font-weight: 600; padding: 4px 0; list-style: revert;
}
.citation-details[open] summary { margin-bottom: 8px; }
.citation-detail-entry { padding: 8px 0; border-top: 1px dotted #C8CEC6; }
.citation-detail-entry:first-of-type { border-top: none; }
.citation-detail-row { display: flex; gap: 8px; margin-bottom: 3px; line-height: 1.6; }
.citation-detail-row:last-child { margin-bottom: 0; }
.citation-detail-label { flex: none; width: 100px; color: #5A6457; }
/* The value half of the row (URL or long source title) is a flex item too — without min-width: 0
   a flex item's default min-width: auto uses its content's un-shrunk size, which for a long
   government URL can exceed the viewport on mobile regardless of the wrap rule below. */
.citation-detail-row > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.citation-detail-row a { color: #155138; text-decoration: underline; overflow-wrap: anywhere; }

/* Official sources appendix — column allocation keeps Accessed on one line and gives URL its own
   clear, separated column rather than everything competing for auto-layout's leftover space. */
.source-inventory-wrap { overflow-x: auto; }
.source-inventory { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 640px; }
.source-inventory th, .source-inventory td {
  text-align: left; padding: 8px 12px; border-bottom: 1px solid #E2E6DF; vertical-align: top;
}
.source-inventory th {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: #5A6457;
}
.source-inventory a { color: #155138; text-decoration: underline; overflow-wrap: anywhere; }
.source-inventory-agency { min-width: 160px; }
.source-inventory-source { min-width: 220px; }
.source-inventory-accessed { min-width: 110px; white-space: nowrap; }
.source-inventory-url { padding-left: 28px; }

/* Additional Requirements Under Verification: dashed structural rail as a second, non-color
   status signal, alongside every card's own text badge — deliberately not red/error styling. */
.review-section {
  border-left: 3px dashed #8A6D1E;
  padding-left: 20px;
}
.review-section-intro { max-width: 720px; }

/* Grouped subsection headings (e.g. "Corporate Reports") inside the review section. The first
   heading sits right under the intro paragraph — its own margin-bottom already separates it, so no
   extra top gap is added here. Every later heading follows a previous group's .fact-list, so it
   gets a much larger top gap plus a hairline rule to read as "start of the next group," not stray
   text wedged between cards. */
.review-section > h3 { margin: 0 0 16px; }
.review-section > .fact-list + h3 {
  margin-top: 32px;
  padding-top: 12px;
  border-top: 1px solid #E2E6DF;
}

/* ---- Version 2 visible group sections (build/lib/render-state-page.mjs) ----------------------
   A state whose record carries a public_layout renders its approved groups here instead of the
   Version 1 topic sections. Every group is an ordinary always-visible <section> with a plain
   <h2>: there is deliberately NO category-level disclosure styling here — no summary rule, no
   hidden native marker, no ▸/▾ arrow, no open/closed state, no pointer cursor and no hover
   affordance on a heading (STATE_DEPLOYMENT_MASTER.md 2.1, section 13.1). A group heading must
   not look clickable, because nothing about it is. Prominence comes from order, typography,
   counts, spacing, and the subordinate rail below. */
.state-section .state-group-heading {
  font-family: Archivo,sans-serif; font-weight: 700; font-size: 28px; letter-spacing: -.01em;
  line-height: 1.2; color: #0B0F0A; margin: 0 0 18px; padding-top: 12px;
  border-top: 1px solid #E2E6DF;
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
}
/* "60 requirements · 3 verification in progress" — plain non-interactive text, so a group with
   in-progress entries is identifiable at a glance and never by colour alone. */
.state-group-meta {
  font-family: 'IBM Plex Mono',monospace; font-weight: 400; font-size: 12px; letter-spacing: .04em;
  color: #5A6457; white-space: normal; overflow-wrap: anywhere;
}
.state-group-intro { max-width: 720px; }
/* Conditional and specialized groups carry a solid structural rail marking them as subordinate
   to the ordinary lifecycle sections — distinct from the dashed verification rail above, and
   never colour-only, since each group's own heading, count, and introduction say what it is. The
   rail wraps the section BODY, not the heading, so the heading stays a plain heading. */
.state-group-conditional > .state-group-body,
.state-group-specialized > .state-group-body {
  border-left: 3px solid #E2E6DF;
  padding-left: 20px;
}
@media (max-width: 640px) {
  .state-section .state-group-heading { font-size: 23px; gap: 8px; }
  .state-group-conditional > .state-group-body,
  .state-group-specialized > .state-group-body { padding-left: 14px; }
}

/* ---- The formation path (render-state-page.mjs's renderHowToStart) --------------------------
   The first section on a public state page, answering "how to start a nonprofit in {State}". It
   deliberately carries its OWN classes rather than reusing the group and entry-point ones, for two
   reasons. Semantically it is not a group of facts but an ordered path through them. Practically,
   every state's own regression test counts group headings and Start Here entries, and a path that
   borrowed those classes would inflate both counts on 46 pages and break 29 test files for a
   reason that has nothing to do with what they check.

   Styling mirrors a group heading exactly, because visually it IS the first section and should not
   announce itself as a special widget. */
.state-section .state-formation-heading {
  font-family: Archivo,sans-serif; font-weight: 700; font-size: 28px; letter-spacing: -.01em;
  line-height: 1.2; color: #0B0F0A; margin: 0 0 18px; padding-top: 12px;
  border-top: 1px solid #E2E6DF;
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
}
.state-formation-meta {
  font-family: 'IBM Plex Mono',monospace; font-weight: 400; font-size: 12px; letter-spacing: .04em;
  color: #5A6457; white-space: normal; overflow-wrap: anywhere;
}
.formation-step-list {
  list-style: decimal; padding-left: 24px; margin: 0;
  display: flex; flex-direction: column; gap: 14px;
  max-width: 760px;
}
.formation-step-item { color: #0B0F0A; }
.formation-step-link {
  display: inline; font-family: Archivo,sans-serif; font-weight: 600; font-size: 16px;
  line-height: 1.4; color: #155138; text-decoration: underline;
  overflow-wrap: anywhere;
}
.formation-step-meta {
  display: block; margin-top: 3px;
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; line-height: 1.45; letter-spacing: .04em;
  color: #5A6457; overflow-wrap: anywhere;
}
@media (max-width: 640px) {
  .state-section .state-formation-heading { font-size: 23px; gap: 8px; }
  .formation-step-list { padding-left: 20px; gap: 16px; }
}

/* ---- Start Here entry-point layer (build/lib/render-state-page.mjs's renderEntryPoint) -------
   An ordered list of links into fact cards further down the page, used when the approved layout
   places its primary facts inside the topical groups. Nothing here is a disclosure control and
   nothing here is clipped: no max-height, no line-clamp, no overflow:hidden, and every item's
   applicability sentence wraps in full. It is deliberately a plain list rather than a card grid,
   so the entry layer stays compact and the reference table below it is not pushed off the first
   screen. */
.entry-point-list {
  list-style: decimal; padding-left: 24px; margin: 0;
  display: flex; flex-direction: column; gap: 14px;
  max-width: 760px;
}
.entry-point-item { color: #0B0F0A; }
.entry-point-link {
  display: inline; font-family: Archivo,sans-serif; font-weight: 600; font-size: 16px;
  line-height: 1.4; color: #155138; text-decoration: underline;
  overflow-wrap: anywhere;
}
/* Requirement status, and the verification label when the entry is still under verification —
   plain mono text on the same row, so status is never carried by colour alone. */
.entry-point-meta {
  display: block; margin-top: 3px;
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; line-height: 1.45; letter-spacing: .04em;
  color: #5A6457; overflow-wrap: anywhere;
}
.entry-point-applies {
  display: block; margin-top: 3px; font-size: 14px; line-height: 1.5; color: #4A5247;
}
@media (max-width: 640px) {
  .entry-point-list { padding-left: 20px; gap: 16px; }
}

/* ---- Approved compact-reference rows (renderApprovedReferenceRows) --------------------------
   Reuses .at-a-glance wholesale, including its 767px stacked-card reflow, so this table needs no
   layout of its own — only the per-row link list and the in-progress marker. */
.reference-row-links {
  display: block; margin-top: 4px;
  font-family: Archivo,sans-serif; font-weight: 400; font-size: 13px; line-height: 1.5;
  overflow-wrap: anywhere;
}
.at-a-glance td.at-a-glance-requirement .reference-row-links a {
  color: #155138; text-decoration: underline; border-bottom: none;
}
.reference-review-marker {
  display: block; margin-top: 3px;
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; line-height: 1.45; font-weight: 600;
  letter-spacing: .04em; color: #7A7440; overflow-wrap: anywhere;
}
.reference-review-marker::before { content: '⚑ '; }

/* Methodology / disclaimer */
.state-disclaimer {
  font-size: 13px; color: #5A6457; border-left: 2px solid #E2E6DF; padding: 4px 0 4px 16px;
  font-style: italic; max-width: 720px;
}

@media (max-width: 900px) {
  .state-card-outline { width: 72px; height: 72px; }
}
@media (max-width: 640px) {
  .states-dir, .state-page { padding-left: 20px; padding-right: 20px; }
  .state-card-grid { grid-template-columns: 1fr; }
  .state-list-plain { grid-template-columns: 1fr; }
  .fact-key-facts { gap: 10px 20px; }
  .state-card-outline { width: 60px; height: 60px; }
}

/* ---- Keyboard focus visibility: every interactive element on the page, not just a few ---- */
a:focus-visible,
summary:focus-visible {
  outline: 2px solid #155138;
  outline-offset: 2px;
}

/* ==========================================================================
   Compliance Updates (/updates/) — reuses this file's existing tokens, card
   shape, and status-badge vocabulary rather than introducing a second visual
   language. See build/lib/render-updates-index.mjs, render-update-article.mjs,
   render-homepage-updates.mjs, and render-state-recent-updates.mjs.
   ========================================================================== */

/* A third verification-badge treatment alongside verified (green) and review
   (amber) — MIXED VERIFICATION STATUS covers an article that combines
   source-verified claims with at least one still-open issue. Text label is
   always present alongside the color dot, matching the other two badges. */
.status-badge-mixed {
  background: #EAF1F4;
  color: #285A6B;
}
.status-badge-mixed::before { background: #2E7E96; }

/* Compact inline variant used next to a related-fact link, where a full-size
   badge would overwhelm the line. */
.status-badge-inline { font-size: 10px; padding: 2px 6px; }

.update-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
  margin-bottom: 20px;
}
.update-card-grid-related { margin-bottom: 0; }

.update-card {
  display: flex;
  flex-direction: column;
  /* Grid items default to min-width: auto, which sizes to the content's un-shrunk width —
     exactly like a flex item without min-width: 0 (see .update-card-head below). Without this,
     a long non-wrapping child (historically .status-badge's own white-space: nowrap) could force
     this card wider than its grid track, overlapping the next column. */
  min-width: 0;
  background: #fff;
  color: #0B0F0A;
  border: 1px solid #0B0F0A;
  box-shadow: 4px 4px 0 #0B0F0A;
  padding: 18px;
  text-decoration: none;
  /* The clickable card is an <a>; explicit `normal` here (rather than leaving font-weight to
     inherit implicitly) means no descendant's weight is ever a byproduct of the anchor's own
     value — every child below sets its own explicit weight instead of relying on inheritance. */
  font-weight: normal;
  transition: transform .12s, box-shadow .12s;
}
.update-card:hover, .update-card:focus-visible {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 #0B0F0A;
}
.update-card:focus-visible { outline: 2px solid #155138; outline-offset: 2px; }

/* Card header: article-type label + verification badge. flex-wrap: wrap lets the badge drop to
   its own line on a narrow card instead of overflowing past the card's right edge — the type
   label and the badge each get min-width: 0 so they can shrink/wrap rather than refusing to,
   which is what let "MIXED VERIFICATION STATUS" spill into the next card at desktop widths. */
.update-card-head { display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: 6px 10px; margin-bottom: 12px; }
.update-card-type {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; font-weight: 600; line-height: 1.3; letter-spacing: .06em;
  text-transform: uppercase; color: #5A6457;
  min-width: 0; max-width: 100%; overflow-wrap: break-word;
}
/* Scoped override, not a change to the shared .status-badge rule: every other .status-badge on
   the site (fact cards, at-a-glance table cells, snapshot rows) relies on its own
   white-space: nowrap and has room for it, and none of that should change. Only inside an
   update-card header does the badge need to wrap instead of overflow. */
.update-card-head .status-badge { white-space: normal; max-width: 100%; overflow-wrap: break-word; }

/* Title: the one clearly bold element on the card. 600 (semibold) reads as the card's strongest
   text without the heavier 700/800 weights this design system reserves for hero/section
   headings — see DESIGN.md's weight scale. */
.update-card-title { font-family: Archivo,sans-serif; font-weight: 600; font-size: 18px; line-height: 1.3; color: #0B0F0A; margin: 0 0 12px; }

/* Summary: plain reading copy, deliberately the lightest weight this card uses. Archivo is
   loaded on this site only at wght 500/600/700/800 (see the <link> in page-chrome.mjs) — true
   regular (400) isn't among the downloaded static weights, so a browser asked for 400 here
   would silently substitute the nearest loaded weight (500) anyway. Setting 500 explicitly (the
   lightest weight actually available) makes that the deliberate, documented choice instead of an
   inherited accident, and is what actually produces visible contrast against the 600 title
   above — leaving font-weight unset was why the summary previously read almost as heavy as the
   title. flex: 1 (not margin-top: auto on the metadata) is what pushes .update-card-meta to the
   bottom of an equal-height card — the summary grows to fill the leftover space itself. */
.update-card-summary { font-size: 15px; font-weight: 500; color: #4A5247; line-height: 1.6; margin: 0 0 16px; flex: 1; }

/* Metadata: the quietest text on the card — smaller, lighter, and visually separated from the
   summary by both the margin above (on .update-card-summary) and this rule's own padding-top +
   divider. IBM Plex Mono is loaded at wght 400/500/600 (unlike Archivo), so 400 here is a true
   regular weight, not a substitution. */
.update-card-meta { font-family: 'IBM Plex Mono',monospace; font-size: 13px; font-weight: 400; line-height: 1.4; color: #5A6457; padding-top: 10px; border-top: 1px solid #E2E6DF; }

/* Homepage variant: sits inside .bsg-card's own box (already styled by index.html's inline
   <style>), so only the internal spacing needs to match — no border/shadow of its own here. */
.update-home-card-head { margin-bottom: 12px; }

/* Tags: identifying labels, not calls to action — smaller and lighter than the earlier 12px/600
   so they read as quiet metadata, not buttons competing with the title/summary above them. */
.update-chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.update-chip {
  display: inline-block;
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 500; line-height: 1.3; letter-spacing: .02em;
  color: #155138; background: #F4F6F3; border: 1px solid #C8CEC6;
  padding: 4px 9px; border-radius: 2px; text-decoration: none;
  max-width: 100%; overflow-wrap: break-word;
}
a.update-chip:hover { border-color: #155138; }
.update-chip-static { color: #5A6457; cursor: default; }

.update-meta-row { font-family: 'IBM Plex Mono',monospace; font-size: 13px; line-height: 1.5; color: #5A6457; margin-bottom: 14px; }

/* Article deck: the one paragraph a reader decides whether to keep reading from — larger than an
   ordinary body paragraph, but still explicitly lighter than the h1 above it (500, the lightest
   weight this design system's Archivo font actually has loaded — see .state-direct-answer's own
   comment). 19px covers the mobile target on its own; the 1040px bump (the same breakpoint the
   two-column shell already switches on) gives it a bit more presence once there's room for it. */
.update-deck { font-size: 19px; font-weight: 500; line-height: 1.6; margin-bottom: 20px; }
@media (min-width: 1040px) {
  .update-deck { font-size: 20px; }
}

.update-takeaway-list { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 12px; }
.update-takeaway-list li { font-size: 15px; font-weight: 500; color: #1A1F18; line-height: 1.6; }

.update-related-fact-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.update-related-fact {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px;
  border-bottom: 1px dotted #C8CEC6; padding-bottom: 8px;
}
.update-related-fact a { color: #155138; text-decoration: underline; font-size: 14px; }

.update-cta-links { display: flex; flex-direction: column; gap: 10px; }
.update-cta-link {
  font-family: 'IBM Plex Mono',monospace; font-size: 14px; font-weight: 600; color: #155138;
  text-decoration: none; border: 1px solid #155138; padding: 10px 14px; border-radius: 2px;
  width: fit-content;
}
.update-cta-link:hover { background: #155138; color: #fff; }

/* ---- /updates/ filter bar (build/lib/render-updates-index.mjs's renderFilterBar) --------------
   One line: three selects, the live "Showing N of M" count, and the clear-filters button, all in a
   single flex row above the article grid.

   It began as three labelled rows of chips — four, three and THIRTY of them — which ran to five
   lines and pushed the first article card most of a screen down the page. The chips read nicely and
   scanned badly, and the state row was 80% of the height for one dimension. Three selects say the
   same thing in one line and stay one line however many states get published.

   Flat, not elevated: this is a control surface sitting above the cards, and giving it the card
   family's hard shadow would make it compete with the very grid it filters.

   The bar is delivered with a `hidden` attribute that only the page's inline script removes, so
   the controls never exist where they cannot work. Nothing here is display-toggled by CSS. */
.update-filter {
  background: #F4F6F3;
  border: 1px solid #C8CEC6;
  padding: 12px 14px;
  margin-bottom: 24px;
}
.update-filter[hidden] { display: none; }

.update-filter-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }

/* Native <select>, stripped of the browser's own chrome and given this system's caret. Native is the
   point: keyboard support, type-to-jump and a phone's own picker all come for free, and none of it
   survives a hand-rolled combobox. Only the appearance is ours.
   The caret is an inline SVG data URI so it costs no request; %23 is a literal # inside the URI. */
.update-filter-select {
  appearance: none; -webkit-appearance: none;
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; font-weight: 500; line-height: 1.3;
  color: #0B0F0A; background-color: #fff; border: 1px solid #C8CEC6; border-radius: 2px;
  padding: 7px 30px 7px 10px; cursor: pointer; max-width: 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%235A6457' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 10px 6px;
}
.update-filter-select:hover { border-color: #155138; }
.update-filter-select:focus-visible { outline: 2px solid #155138; outline-offset: 2px; }

/* Pushed to the far end of the row, so the two controls that report state (the count and the clear
   button) sit together and away from the three that change it. */
.update-filter-summary {
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; font-weight: 600; color: #0B0F0A;
  margin: 0 0 0 auto;
}
.update-filter-reset {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; font-weight: 600; line-height: 1.3;
  color: #155138; background: none; border: 1px solid #155138; border-radius: 2px;
  padding: 5px 10px; cursor: pointer;
}
.update-filter-reset:hover { background: #155138; color: #fff; }
.update-filter-reset:focus-visible { outline: 2px solid #155138; outline-offset: 2px; }
.update-filter-reset[hidden] { display: none; }

/* Filtering hides a card with the `hidden` attribute. The card's own display:flex would otherwise
   beat the UA stylesheet's [hidden] { display: none } — a specificity detail, not a preference. */
.update-card[hidden] { display: none; }

.update-filter-empty {
  font-family: 'IBM Plex Mono',monospace; font-size: 14px; line-height: 1.6; color: #4A5247;
  background: #F4F6F3; border: 1px dashed #C8CEC6; padding: 16px 18px; margin: 0;
}
.update-filter-empty[hidden] { display: none; }

/* ---- /updates/ browse indexes (renderIndexSection) --------------------------------------------
   Plain link lists, one row per state / type / topic. These are the page's own sitemap and its
   no-JavaScript path: every article is reachable here without a single script running. They
   replaced three sections that re-rendered the full card grid once per group, which is what made
   this document 815 KB for 61 articles. */
.update-index-intro { font-size: 15px; color: #4A5247; line-height: 1.6; max-width: 680px; margin: 0 0 18px; }
.update-index { margin: 0; }
.update-index-row {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 6px 20px;
  padding: 10px 0;
  border-bottom: 1px dotted #C8CEC6;
}
.update-index-row:last-child { border-bottom: 0; }
.update-index dt { font-family: Archivo,sans-serif; font-weight: 600; font-size: 15px; line-height: 1.4; color: #0B0F0A; }
.update-index dt a { color: #155138; text-decoration: underline; }
.update-index-count { font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; color: #5A6457; }
.update-index dd { margin: 0; font-size: 14px; line-height: 1.7; color: #4A5247; }
.update-index dd a { color: #155138; text-decoration: underline; }
/* One article per line. Unstyled markers: the row's own label and count already say what the list
   is, and a bullet column would only push every title further from it. */
.update-index-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
/* The topic index lists state codes rather than repeating article titles (see indexRow's own
   note) — mono, because a run of two-letter codes reads as data, not prose. */
.update-index-states { font-family: 'IBM Plex Mono',monospace; font-size: 13px; color: #5A6457; }

.update-index-details > summary {
  font-family: 'IBM Plex Mono',monospace; font-size: 13px; font-weight: 600; color: #155138;
  cursor: pointer; padding: 8px 0;
}
.update-index-details > summary:focus-visible { outline: 2px solid #155138; outline-offset: 2px; }

@media (max-width: 640px) {
  .update-card-grid { grid-template-columns: 1fr; }
  /* The three selects share the row while they fit and wrap when they do not; the count drops to
     its own full-width line rather than being squeezed against the last select by margin-left:auto. */
  .update-filter-select { flex: 1 1 auto; }
  .update-filter-summary { margin-left: 0; flex: 1 1 100%; }
  .update-index-row { grid-template-columns: 1fr; }
}

/* Cross-state links on shared questions, rendered by render-state-page.mjs's renderNeighbors.
   Styled as one more labelled row of the card rather than as a callout: the label reuses the exact
   mono/uppercase treatment of .fact-key-fact dt and .fact-card-notes-label, so "Elsewhere" reads as
   a field name alongside Deadline and Fee. It repeats on every canonical fact, seventeen times on a
   page, and anything that announced itself more loudly than that would become the loudest thing on
   the page by sheer repetition.
   Link colour is #155138, the same green used for every other link on the card (9.27:1 on the
   ordinary card, 9.08:1 on the amber verification-in-progress card, both clear of the 4.5:1 AA
   minimum). The verdict beside it is the same #5A6457 as the provenance line, which measures 5.31:1
   and stays secondary without dropping below AA. */
.fact-neighbors { margin: 0 0 10px; }
.fact-neighbors-label {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: #5A6457; margin-bottom: 4px;
}
.fact-neighbor-list { list-style: none; margin: 0; padding: 0; }
/* From 600px up the label sits on the same baseline as the first link instead of above it, which
   removes one line from every canonical fact — seventeen lines a page. Below 600px it stays
   stacked: inline there costs more than it saves, because the label takes a whole row of its own
   and both links then wrap, measured at 103px against 72px stacked. */
@media (min-width: 600px) {
  .fact-neighbors { display: flex; flex-wrap: wrap; gap: 2px 10px; }
  .fact-neighbors-label { margin-bottom: 0; line-height: 1.7; flex: 0 0 auto; }
  .fact-neighbor-list { flex: 1 1 240px; }
}
/* Link and verdict share a baseline on a wide card and stack on a narrow one. Wrapping rather than
   a two-column grid because the anchor text runs to "Georgia charitable solicitation registration"
   and a fixed column would either clip it or leave the short ones stranded. */
.fact-neighbor {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  font-size: 14px; margin-bottom: 3px;
}
.fact-neighbor a { color: #155138; text-decoration: underline; overflow-wrap: anywhere; }
.fact-neighbor-verdict { color: #5A6457; font-size: 13px; }

   Reuses .fact-card, .fact-key-facts and .status-badge from the state guides on purpose: a benefit
   program and a compliance fact are the same shape of object, a claim with a source and a
   verification date, and they should not look like two different kinds of thing. */
.benefit-card-status { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; }
.benefit-checked {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; line-height: 1.4; color: #5A6457;
}
.benefit-block { margin-top: 14px; }
.benefit-block-label {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: #5A6457; margin-bottom: 5px;
}
.benefit-block p { font-size: 15px; line-height: 1.65; margin: 0; }
.benefit-list { margin: 0; padding-left: 20px; }
.benefit-list li { font-size: 15px; line-height: 1.6; margin-bottom: 5px; }
.benefit-value-kind, .benefit-former {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; color: #8A6D1E;
  text-transform: uppercase; letter-spacing: .06em;
}

.benefit-sources { margin-top: 18px; border-top: 1px solid #E2E6DF; padding-top: 12px; }
.benefit-sources-label {
  font-family: 'IBM Plex Mono',monospace; font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: #5A6457; margin-bottom: 8px;
}
.benefit-source-list { list-style: none; margin: 0; padding: 0; }
.benefit-source-list li { margin-bottom: 10px; font-size: 14px; line-height: 1.5; }
/* overflow-wrap because several of these are long .gov and vendor support URLs and the card is
   288px narrower than the page on desktop. */
.benefit-source-list a { color: #155138; text-decoration: underline; overflow-wrap: anywhere; }
.benefit-source-when, .benefit-source-supports, .benefit-source-note {
  display: block; font-family: 'IBM Plex Mono',monospace; font-size: 11px; color: #5A6457;
  line-height: 1.45; margin-top: 2px;
}
.benefit-no-source {
  margin-top: 18px; font-size: 13px; color: #8A6D1E; border-top: 1px solid #E2E6DF; padding-top: 12px;
}

.benefit-precondition-list { margin: 18px 0 0; padding-left: 22px; }
.benefit-precondition-list li { font-size: 16px; line-height: 1.65; margin-bottom: 10px; }
.benefit-exclusions { font-size: 15px; line-height: 1.65; margin-top: 20px; }
.benefit-section-count {
  font-family: 'IBM Plex Mono',monospace; font-size: 12px; color: #5A6457;
  text-transform: uppercase; letter-spacing: .08em; margin: 0 0 20px;
}
