/*!
 * state_profile_counties.css — ERN state-profile house style (county level).
 *
 * For county-only states (no tract feed): the "Counties on the rise" trend
 * plate stands in for the tract/race plates. Tract states use the sibling
 * state_profile_tracts.css. Canonical copies live in
 * library/templates/state_profile/.
 *
 * Brand spec: cidrlab/library/brand/ern/BRAND.md
 * Colors:    accent #F9322B · navy #19222C · medium-blue #223754 · light-blue #e8eef4
 * Font:      Inter — single canonical ERN brand family.
 *            Display headlines: Inter 200 (Extra Light, hairline)
 *            Body / nav / pills: Inter 400/500/600/700
 *
 * Type scale (CSS px), no half-pixels — six steps:
 *   11 small (labels · captions · axis) · 13 secondary (body-2 · table · values) ·
 *   16 body · 18 large body/claim · 22 lead · 30 big number ·
 *   clamp() display headings (h1, section-title, stat number) — fluid, separate.
 *   In-SVG chart text uses the same 11/13 px, held constant across widths by
 *   JS counter-scaling (--sx); see index.template.html.
 */
:root {
  --paper:      #ffffff;
  --tint:       rgba(232, 238, 244, 0.45);
  --navy:       #19222C;
  --navy-soft:  #223754;
  --steel:      #8BA3BE;   /* swatch/graphic only — fails as text on white (2.6:1) */
  --accent:     #F9322B;   /* brand red — GRAPHICS only (markers, dots, rules). Fails as text (3.8:1). */
  --accent-deep:#F9322B;   /* brand red — used for text/links/buttons too, per Tim 2026-08-15 */
  --accent-deeper:#CC2118; /* slightly darker red for hover/active, so links still respond */
  --rule:       rgba(25, 34, 44, 0.18);
  /* Gridline colour for the annual-state charts. Previously referenced by
     .ca-grid with no definition and no fallback, which makes the declaration
     invalid at computed-value time and drops it, so those gridlines were not
     drawing from this rule at all. Set to the value the adjacent .ca-axis rule
     already uses. Needs a look on California's page. */
  --ca-grid:    #d7dce1;
  --rule-fine:  rgba(25, 34, 44, 0.10);
  --muted:      #586573;   /* secondary / caption text — WCAG-safe (6.0:1 on white) */
  --sans:       "Inter", -apple-system, system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --gutter:     24px;
  --transition: 220ms ease;
  --header-h:   84px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; font-family: var(--sans); font-size: 16px;
  line-height: 1.6; font-weight: 400;
  color: var(--navy); background: var(--paper);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01", "cv11";
}
a {
  color: var(--navy); text-decoration: none;
  border-bottom: 1px solid var(--navy);
  padding-bottom: 1px;
  transition: color var(--transition), border-color var(--transition);
}
a:hover, a:focus { color: var(--accent-deep); border-color: var(--accent-deep); outline: none; }
/* Body-prose links. These previously dropped the base rule's underline
   entirely, which left an inline citation looking exactly like the navy text
   around it. The text stays navy so it keeps its reading contrast; the brand
   red goes on the underline, which is what marks it as a link. Hover moves
   the text to red as well. Tim 2026-08-20. */
a.unstyled {
  border: none; padding: 0;
  text-decoration: underline;
  text-decoration-color: var(--accent-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.16em;
}
a.unstyled:hover, a.unstyled:focus {
  color: var(--accent-deep); border: none;
  text-decoration-color: var(--accent-deeper);
}

.page { max-width: 1320px; margin: 0 auto; padding: 0 40px; }
@media (max-width: 720px) { .page { padding: 0 20px; } }

/* ─── Sticky header ─── */
header.site {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255,255,255,0.94);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition), box-shadow var(--transition);
}
header.site.scrolled {
  border-bottom-color: var(--rule-fine);
  box-shadow: 0 4px 14px rgba(25, 34, 44, 0.04);
}
header.site .inner {
  max-width: 1320px; margin: 0 auto;
  padding: 18px 40px;
  display: grid; grid-template-columns: auto 1fr;
  align-items: center; gap: var(--gutter);
  min-height: var(--header-h);
}
@media (max-width: 720px) { header.site .inner { padding: 14px 20px; } }
header.site .logo { border: none; display: inline-flex; align-items: center; }
header.site .logo img { display: block; height: 44px; width: auto; }
@media (max-width: 720px) { header.site .logo img { height: 34px; } }
header.site nav {
  justify-self: end; font-size: 13px;
  display: flex; gap: 28px; font-weight: 500;
}
header.site nav a { border: none; padding: 0; }
header.site nav a:hover { border-bottom: 1px solid var(--accent); }

/* Hamburger toggle — hidden on desktop, revealed ≤900px (mobile block below). */
.nav-toggle {
  display: none; justify-self: end; box-sizing: border-box;
  width: 42px; height: 42px; padding: 9px;
  background: none; border: none; cursor: pointer;
  flex-direction: column; justify-content: center; gap: 5px;
}
.nav-toggle span {
  display: block; width: 100%; height: 2px; border-radius: 2px;
  background: var(--navy);
  transition: transform 220ms ease, opacity 180ms ease;
}
header.site.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
header.site.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
header.site.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Nav dropdowns (Maps & Profiles, Resources) — hover/focus reveals the panel. */
header.site nav .dropdown { position: relative; }
header.site nav .dropdown > .dropdown-toggle {
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px;
}
header.site nav .dropdown > .dropdown-toggle .caret {
  font-size: 11px; line-height: 1;
  transition: transform 180ms ease;
}
header.site nav .dropdown:hover > .dropdown-toggle .caret,
header.site nav .dropdown:focus-within > .dropdown-toggle .caret {
  transform: rotate(180deg);
}
header.site nav .dropdown-panel {
  position: absolute;
  top: 100%; left: -12px;
  min-width: 200px;
  background: var(--paper);
  border: 1px solid var(--rule-fine);
  box-shadow: 0 10px 28px rgba(25, 34, 44, 0.08);
  padding: 8px 0;
  z-index: 60;
  /* Hidden by default; revealed via hover/focus-within. Using
     opacity+visibility (rather than display:none) lets the panel be
     keyboard-focusable for accessibility. */
  opacity: 0; visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 160ms ease, transform 160ms ease, visibility 160ms;
}
header.site nav .dropdown:hover > .dropdown-panel,
header.site nav .dropdown:focus-within > .dropdown-panel {
  opacity: 1; visibility: visible; transform: translateY(0);
}
header.site nav .dropdown-panel a {
  display: block;
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 400;
  color: var(--navy);
  white-space: nowrap;
  border: none;
}
header.site nav .dropdown-panel a:hover {
  background: var(--tint);
  color: var(--accent-deep);
  border: none;
}
header.site nav .dropdown-panel a[aria-current="page"] {
  color: var(--accent-deep);
  font-weight: 600;
}

/* ─── Mobile nav: hamburger reveals a full-width dropdown panel ─── */
@media (max-width: 900px) {
  header.site { position: sticky; }
  .nav-toggle { display: inline-flex; }
  header.site nav {
    position: absolute; top: 100%; left: 0; right: 0;
    justify-self: stretch;   /* override desktop `justify-self: end` so the panel fills width */
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--paper); border-bottom: 1px solid var(--rule-fine);
    box-shadow: 0 12px 28px rgba(25, 34, 44, 0.10);
    padding: 6px 0 10px;
    max-height: 0; overflow: hidden;
    opacity: 0; visibility: hidden;
    transition: max-height 280ms ease, opacity 200ms ease, visibility 200ms;
  }
  header.site.nav-open nav {
    max-height: 80vh; overflow-y: auto;
    opacity: 1; visibility: visible;
  }
  header.site nav > a,
  header.site nav .dropdown > .dropdown-toggle {
    padding: 13px 24px; font-size: 16px; font-weight: 500;
  }
  header.site nav a:hover { border-bottom: none; color: var(--accent-deep); }
  /* Dropdowns sit inline and stay expanded inside the mobile panel. */
  header.site nav .dropdown { position: static; }
  header.site nav .dropdown > .dropdown-toggle .caret { display: none; }
  header.site nav .dropdown-panel {
    position: static; opacity: 1; visibility: visible; transform: none;
    box-shadow: none; border: none; padding: 0; min-width: 0;
    background: var(--tint);
  }
  header.site nav .dropdown-panel a { padding: 10px 24px 10px 38px; font-size: 13px; white-space: normal; }
}

/* ─── Chart text holds a constant pixel size at every width via JS
   counter-scaling (see "Constant-size chart text" in index.template.html):
   each chart's <svg> gets --sx = renderedWidth / viewBoxWidth, and chart text
   is sized font-size: calc(<px> / var(--sx)). No viewBox-unit font "bump"
   at a breakpoint is needed anymore. ─── */

/* Plate II only: with constant-size text, the per-bar value labels + the
   projection label collide once the bar pitch compresses on a phone (11
   six-digit numbers can't fit a ~335px-wide plot). Hide them under 640px —
   the bars, the year axis, the hover gridlines, and the tap tooltip still
   carry every value. (Plate I and III have few labels and don't collide.) */
@media (max-width: 640px) {
  /* every yearly chart: the statewide one and the county picker's */
  svg[id^="chart-yearly-svg"] .yval,
  svg[id^="chart-yearly-svg"] .yproj-label { display: none; }
}

/* ─── Hero ─── */
.hero { padding: 32px 0 96px; position: relative; }
.hero::before {
  content: ""; position: absolute; top: 0; right: 0;
  width: 75%; height: 1px; background: var(--navy);
}
.hero .row {
  display: grid; grid-template-columns: 1fr 1.4fr;
  gap: 88px; align-items: center; padding-top: 80px;
}
@media (max-width: 900px) {
  .hero .row { grid-template-columns: 1fr; gap: 48px; padding-top: 56px; }
}
/* State outline — rendered at runtime from US Census TIGER/Line data
   via D3 + us-atlas. The viewBox is set on the SVG by JS based on
   the projected bounding box, so the figure adapts to any state. */
.hero .state-outline {
  width: 100%; max-width: 460px;
  justify-self: center; margin: 0;
  display: block;
  /* Reserve a vertical slot while D3 + us-atlas load so the page
     doesn't reflow. fitSize will produce a state-specific shape; the
     min-height keeps the slot even before the JS runs. */
  min-height: 360px;
}
.hero .state-outline svg {
  width: 100%; height: auto; display: block; overflow: visible;
}
.hero .state-outline .state-shape {
  fill: none;
  stroke: var(--navy);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  transition: stroke 600ms ease;
}
.hero .state-outline:hover .state-shape {
  stroke: var(--accent);
}
.hero .state-outline .state-mark {
  fill: var(--accent);
}
.hero .text { display: flex; flex-direction: column; gap: 22px; }
.hero .kicker {
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--accent-deep); margin: 0;
}
.hero h1 {
  font-weight: 200;
  font-size: clamp(2.8rem, 5.6vw, 4.6rem);
  line-height: 1.04; letter-spacing: -0.025em;
  margin: 0; color: var(--navy); max-width: 14ch;
}
.hero h1 em { font-style: normal; font-weight: 600; }
.hero .lede {
  font-size: 18px; line-height: 1.65;
  max-width: 56ch; color: var(--navy); margin: 0;
}
.hero .byline {
  margin-top: 4px; padding-top: 14px;
  border-top: 1px solid var(--rule-fine);
  font-size: 13px; color: var(--muted);
  display: flex; gap: 24px; flex-wrap: wrap;
}
.hero .byline strong { color: var(--navy); font-weight: 600; }

/* ─── Buttons ─── */
.btn {
  font-family: var(--sans); font-weight: 600; font-size: 13px;
  letter-spacing: 0.06em; text-transform: uppercase;
  padding: 13px 24px; border-radius: 4px;
  text-decoration: none;
  transition: all var(--transition);
  display: inline-flex; align-items: center; gap: 12px;
  border: 1.5px solid transparent;
}
.btn::after { content: "→"; font-size: 16px; transition: transform var(--transition); letter-spacing: 0; }
.btn:hover::after { transform: translateX(4px); }
.btn-red { background: var(--accent-deep); color: #fff; border-color: var(--accent-deep); }
.btn-red:hover { background: var(--accent-deeper); border-color: var(--accent-deeper); color: #fff; }
.btn-ghost { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-ghost:hover { color: var(--accent-deep); border-color: var(--accent-deep); }

/* ─── Stats row ─── */
.stats {
  padding: 48px 0;
  border-top: 1px solid var(--rule-fine);
  border-bottom: 1px solid var(--rule-fine);
}
.stats .row {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: var(--gutter);
}
@media (max-width: 720px) { .stats .row { grid-template-columns: 1fr 1fr; gap: 32px; } }
.stat { display: flex; flex-direction: column; gap: 12px; }
.stat .num {
  font-weight: 200;
  font-size: clamp(2rem, 3.6vw, 2.8rem);
  letter-spacing: -0.025em; line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--navy);
}
.stat .num em { font-style: normal; font-weight: 600; color: var(--accent-deep); }
.stat .num .small { font-size: 0.5em; font-weight: 500; opacity: 0.85; }
.stat .num .delta { color: var(--accent-deep); margin-right: 4px; font-weight: 400; }
.stat .label { font-size: 11px; line-height: 1.5; color: var(--muted); max-width: 22ch; }

/* ─── 20-second summary ("if you read nothing else") ─── */
.tldr { margin: 4px 0 0; }
.tldr-inner {
  background: var(--tint);
  border-left: 3px solid var(--accent);
  padding: 26px 30px;
}
.tldr h2 {
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent-deep); margin: 0 0 16px;
}
.tldr ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 13px; }
.tldr li {
  font-size: 17px; line-height: 1.55; color: var(--navy);
  padding-left: 24px; position: relative; max-width: 96ch;
}
.tldr li::before {
  content: "→"; position: absolute; left: 0; top: 0;
  color: var(--accent-deep); font-weight: 700;
}
.tldr li strong { font-weight: 600; }
@media (max-width: 720px) {
  .tldr li { font-size: 15px; }
  .tldr-inner { padding: 22px 20px; }
}

/* ─── Section ─── */
section.section { padding: 96px 0; }
/* Trends section opens right under the "In short" summary box, with Figure 2
   since Figure 1 moved above the box (2026-10-21), so the gap is trimmed. */
#trends { padding-top: 44px; }
#chart-monthly { margin-top: 0; }
/* Figure 1 leads the page, above the "In short" box (Tim, 2026-10-21): its
   own section, with the gap to the box below trimmed to match. */
#monthly { padding: 56px 0 48px; }
section.section + section.section { border-top: 1px solid var(--rule-fine); }
section.section.tinted { background: var(--tint); }
section.section.tinted.inset {
  margin: 0 -40px; padding: 96px 80px;
}
@media (max-width: 1100px) {
  section.section.tinted.inset { padding: 96px 64px; }
}
@media (max-width: 720px) {
  section.section.tinted.inset { margin: 0 -20px; padding: 72px 32px; }
}

.two-col {
  display: grid; grid-template-columns: 1fr 1.3fr;
  gap: 72px; align-items: start;
}
@media (max-width: 900px) { .two-col { grid-template-columns: 1fr; gap: 32px; } }
/* Magazine-deck title wrap, generalized from .action-lead (California's
   action section, above the credit cards block): the heading floats left
   and the body prose sits beside it, then wraps on underneath, filling the
   tall empty well a grid split leaves under a short title. Opt in per
   section as {.two-col .title-wrap}: the grid gives way to a float and the
   body typography stays. Dropped on narrow screens, where the heading
   stacks above the text as before. */
.two-col.title-wrap { display: block; }
.two-col.title-wrap::after { content: ""; display: block; clear: both; }
.two-col.title-wrap > div:first-child {
  float: left; width: 42%; margin: 0 44px 18px 0;
}
.two-col.title-wrap .body p { max-width: none; }
@media (max-width: 900px) {
  .two-col.title-wrap > div:first-child { float: none; width: auto; margin: 0 0 20px; }
}
/* Left column stretches and pushes its figure (e.g. Figure 2's text) to the bottom, filling the empty space. */
.lead-fill { align-self: stretch; display: flex; flex-direction: column; }
.lead-fill > .figure { margin-top: auto; }
/* Affordability split: heading + Figure 5 chart on the left, body text on the right. */
.afford-split {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  grid-template-areas: "head body" "chart body";
  gap: 28px 56px; align-items: start;
}
.afford-split .afford-head { grid-area: head; }
.afford-split > .body { grid-area: body; }
.afford-split .afford-chart { grid-area: chart; margin-top: 0; }
.afford-split .body p { font-size: 16px; line-height: 1.7; max-width: 56ch; margin: 0 0 16px; color: var(--navy); }
.afford-split .body p strong { font-weight: 600; }
@media (max-width: 900px) {
  .afford-split { grid-template-columns: 1fr; grid-template-areas: "head" "chart" "body"; gap: 24px; }
}

h2.section-title {
  font-weight: 200;
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 1.05; letter-spacing: -0.022em;
  margin: 0 0 24px;
  color: var(--navy); max-width: 20ch;
}
h2.section-title em { font-style: normal; font-weight: 600; }
.lead-paragraph {
  font-weight: 400;
  font-size: 22px; line-height: 1.45;
  letter-spacing: -0.01em;
  max-width: 32ch; color: var(--navy);
  margin: 0 0 24px;
}
.two-col .body p {
  font-size: 16px; line-height: 1.7;
  max-width: 56ch; margin: 0 0 16px; color: var(--navy);
}
.two-col .body p strong { font-weight: 600; }

/* ─── Bare-on-page chart figure ─── */
.figure { margin-top: 56px; }
.figure svg { width: 100%; height: auto; display: block; }
/* Bare `.caption` (not `.figure .caption`) so all six plates match: Plates
   IV/V (map + table, outside .figure) and Plate III (in .plate-rising-chart)
   use the same caption style as I/II/VI. The old per-plate inline-grid
   captions on III/IV/V are removed from the markup in favor of this rule. */
.caption {
  max-width: 100%;
  margin-top: 18px;
  display: grid;
  grid-template-columns: 70px 1fr 220px;
  gap: var(--gutter);
  font-size: 11px; color: var(--muted);
  line-height: 1.5;
  align-items: baseline;
}
@media (max-width: 720px) {
  .caption { grid-template-columns: 70px 1fr; }
  .caption .src { grid-column: 2; margin-top: 4px; }
}
.caption .num {
  font-weight: 600; color: var(--navy);
  letter-spacing: 0.04em; text-transform: uppercase;
  font-size: 11px;
}
.caption .desc { font-style: italic; color: var(--navy); font-size: 13px; }
.caption .src {
  color: var(--muted); text-align: right;
  letter-spacing: 0.02em; text-transform: lowercase;
  font-size: 11px;
}
@media (max-width: 720px) { .caption .src { text-align: left; } }

.charts-pair {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 64px; margin-top: 56px;
}
@media (max-width: 900px) { .charts-pair { grid-template-columns: 1fr; gap: 56px; } }
/* Side by side, the two figures share rows (eyebrow, claim, description,
   chart, caption) so their charts and captions line up even when one
   description runs longer (Tim, 2026-10-30, Minnesota Figures 5 and 6). */
@media (min-width: 901px) {
  .charts-pair { grid-template-rows: repeat(5, auto); row-gap: 0; }
  .charts-pair > .figure {
    display: grid; grid-row: span 5;
    grid-template-rows: subgrid;
  }
  .charts-pair > .figure > * { align-self: start; }
}

.figure h3 {
  font-size: 16px; font-weight: 600;
  letter-spacing: -0.005em;
  margin: 0 0 6px; color: var(--navy);
}
.figure .desc-lead {
  font-size: 13px; line-height: 1.55;
  color: var(--muted); margin: 0 0 18px; max-width: 64ch;
}

/* ─── Plate header (Du Bois lineage; see methodology for citation).
   Each chart is numbered (Plate I…) and titled with a claim sentence,
   followed by a one-or-two sentence interpretive description.
   Uses Inter only (no display companion font) — all-caps + tracked
   letter-spacing carries the display register on cross-platform Inter. */
/* Plate III lives in .plate-rising-* containers (not .figure), so its header
   and caption are included here explicitly to keep all six plates uniform. */
.figure .plate-num,
.plate-rising-chart .plate-num {
  display: block;
  font-family: var(--sans);
  font-weight: 800;
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin: 0 0 8px;
}
.figure h3.plate-claim,
.plate-rising-text h3.plate-claim {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.32;
  letter-spacing: 0.035em;
  text-transform: uppercase;
  color: var(--navy);
  margin: 0 0 12px;
  max-width: 52ch;
}
.figure h3.plate-claim em,
.plate-rising-text h3.plate-claim em {
  font-style: normal;
  color: var(--accent-deep);
}
.figure p.plate-desc {
  font-family: var(--sans);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.6;
  color: var(--navy);
  margin: 0 0 22px;
  max-width: 66ch;
}
.figure p.plate-desc strong { font-weight: 600; }
.figure p.plate-desc em { font-style: italic; }

/* ─── "What can be done" action list (Plate VII scaffold).
   Numbered grid of evidence-based interventions; placeholder
   content is Tim-fillable.  Same restrained Inter palette as
   the rest of the page. */
.action-list {
  list-style: none;
  padding: 0;
  margin: 36px 0 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 36px 56px;
}
@media (max-width: 800px) {
  .action-list { grid-template-columns: 1fr; gap: 28px; }
}
.action-list li {
  display: grid;
  grid-template-columns: 50px 1fr;
  gap: 16px;
  align-items: stretch;
}
/* Body is a flex column so the ROI callout can pin to the bottom — that keeps
   the two side-by-side recs' callouts aligned even when their text differs. */
.action-list .action-body { display: flex; flex-direction: column; }
.action-list .action-body > p:first-of-type { margin-bottom: 12px; }
.action-list .action-num {
  font-family: var(--sans);
  font-weight: 800;
  font-size: 30px;
  letter-spacing: 0.02em;
  color: var(--accent-deep);
  line-height: 1;
  margin-top: 2px;
}
.action-list h4 {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: var(--navy);
  margin: 0 0 6px;
}
.action-list p {
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.55;
  color: var(--navy);
  margin: 0;
}
.action-list p em {
  font-style: italic;
}
/* ROI callout — an accent-tinted box under a lever, to encourage adoption. */
.action-list p.action-roi {
  margin: auto 0 0;
  padding: 11px 15px;
  background: var(--tint);
  border-left: 3px solid var(--accent);
  border-radius: 0 6px 6px 0;
  font-size: 13px;
  color: var(--navy);
}
.action-list p.action-roi strong { color: var(--accent-deep); font-weight: 600; }

/* Plate VI "what works" — inline SVG (built in render.R from the lever data,
   replacing the old PNG): vector-crisp, responsive, real/accessible text.
   Text holds a constant pixel size via --sx (see the "Constant-size chart text"
   watcher in index.template.html), drawn only from the page's six-size scale.
   The min-width stops --sx from dropping so low on a phone that the constant-px
   labels would outgrow the chips; below it the dense graphic pans horizontally
   inside the wrap rather than collapsing to an illegible thumbnail. */
.plate6-svg-wrap { margin: 24px 0 8px; overflow-x: auto; }
.plate6-svg { width: 100%; min-width: 820px; height: auto; display: block; }
.plate6-svg text { font-family: var(--sans); }

/* Coda below the action list — short closing prose:
   eviction-in-the-displacement-system framing + the 3 P's.  */
.action-coda {
  margin-top: 44px;
  padding-top: 28px;
  border-top: 1px solid var(--rule-fine);
  max-width: 78ch;
}
.action-coda h4 {
  font-family: var(--sans);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: var(--navy);
  margin: 22px 0 8px;
}
.action-coda h4:first-child { margin-top: 0; }
.action-coda p {
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.65;
  color: var(--navy);
  margin: 0 0 14px;
}
/* In the coda, em is doing emphasis-as-keyword duty for the 3 P's
   (production / preservation / protections) — give them weight + the
   ERN accent color, no italic. */
.action-coda p em {
  font-style: normal;
  font-weight: 700;
  color: var(--accent-deep);
}

/* ─── Chart legend strip ─── */
.figure .chart-legend {
  display: flex; flex-wrap: wrap;
  gap: 8px 22px;
  font-size: 11px; line-height: 1.4;
  color: var(--muted); font-style: italic;
  margin: -6px 0 14px;
}
/* Variant: legend sitting below the SVG instead of above */
.figure .chart-legend.chart-legend-below { margin: 28px 0 12px; }
/* Variant: subtitle sitting below the SVG (after legend, before caption) */
.figure .desc-lead.desc-lead-below { margin: 0; max-width: none; }
.figure .chart-legend .legend-item {
  display: inline-flex; align-items: center; gap: 8px;
}
.figure .chart-legend .legend-mark {
  display: inline-block; flex-shrink: 0;
  width: 22px; height: 10px;
}
.figure .chart-legend .legend-mark-baseline {
  height: 0; border-top: 1px dashed #6c7a89;
}
.figure .chart-legend .legend-mark-proj {
  height: 10px; background: rgba(249, 50, 43, 0.08);
  border-top: 1.5px dashed #F9322B;
}
.figure .chart-legend .legend-item[hidden] { display: none; }
.figure .chart-legend .legend-mark-band {
  background: rgba(25, 34, 44, 0.06);
  border-left: 1px solid rgba(25, 34, 44, 0.18);
  border-right: 1px solid rgba(25, 34, 44, 0.18);
}

/* ─── Interactive chart shared chrome ─── */
.chart-interactive {
  position: relative;
  /* No crosshair. The chart already draws its own vertical guide and dots on
     hover, so a crosshair cursor is a second, less precise pointer competing
     with the one that carries the reading. Minnesota's profile never set one;
     this matches it. The bar-chart rule below still opts its rects into
     `pointer`, where the cursor does signal that a bar is clickable. */
  cursor: default;
  /* overflow MUST stay visible on both axes. Constant-size chart text (--sx,
     see index.template.html) keeps labels legible at any width, so we no
     longer force a min-width + horizontal scroll. Two reasons visible matters:
       1. Hover tooltips are absolutely-positioned children that sit ABOVE the
          plot — a scroll/auto container would clip them.
       2. On a phone the now-larger constant-size edge labels (first/last year,
          the Plate I annotation) extend slightly past the viewBox; visible
          lets them show instead of being cut at the left/right edge.
     NB: a single `overflow-x: auto` forces overflow-y to compute to `auto`
     too (CSS spec), which is the bug that was clipping tooltips. */
  overflow: visible;
}
.chart-interactive svg {
  display: block;
  /* Fit the column instead of forcing a wider canvas; text stays readable via
     counter-scaling, and the chart no longer gets cut off on the left/right. */
  width: 100%;
  min-width: 0;
  overflow: visible;   /* don't clip enlarged edge labels at the viewBox bounds */
}
/* Race-pair charts (tract states) keep a modest floor so the two side-by-side
   plots don't collapse; county-only WA has a single full-width chart. */
.charts-pair > .chart-interactive svg { min-width: 0; }
.chart-interactive .hover-grid {
  opacity: 0;
  transition: opacity 220ms ease;
  pointer-events: none;
}
.chart-interactive:hover .hover-grid { opacity: 1; }
.chart-interactive .hover-grid .grid-line {
  stroke: #19222C; stroke-width: 0.5;
  stroke-dasharray: 2 3; opacity: 0.22;
}
.chart-interactive .hover-grid .grid-label {
  font-family: 'Inter', sans-serif; font-size: calc(11px / var(--sx, 1));
  fill: #586573; letter-spacing: 0.02em;
}
.chart-interactive .hover-indicator {
  opacity: 0;
  transition: opacity 120ms ease;
  pointer-events: none;
}
.chart-interactive .hover-indicator.active { opacity: 1; }
.chart-interactive .hover-vguide {
  stroke: #F9322B; stroke-width: 1;
  stroke-dasharray: 2 3; opacity: 0.7;
}
.chart-interactive .hover-dot {
  fill: #F9322B; stroke: #fff; stroke-width: 2;
}
.chart-interactive .hover-tooltip {
  position: absolute;
  background: #19222C; color: #fff;
  padding: 8px 12px; border-radius: 4px;
  font-family: 'Inter', sans-serif;
  font-size: 11px; line-height: 1.4;
  pointer-events: none; white-space: nowrap;
  z-index: 5;
  transform: translate(-50%, calc(-100% - 14px));
  box-shadow: 0 4px 14px rgba(25,34,44,0.18);
  opacity: 0; transition: opacity 120ms ease;
}
.chart-interactive .hover-tooltip.active { opacity: 1; }
.chart-interactive .hover-tooltip::after {
  content: "";
  position: absolute;
  bottom: -5px; left: 50%;
  transform: translateX(-50%) rotate(45deg);
  width: 8px; height: 8px;
  background: #19222C;
}
.chart-interactive .tip-date {
  font-weight: 500; font-size: 11px;
  color: rgba(255,255,255,0.78);
  letter-spacing: 0.04em; text-transform: uppercase;
  margin-bottom: 2px;
}
.chart-interactive .tip-value {
  font-weight: 600; font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.chart-interactive .tip-value .tip-sub {
  font-weight: 400; font-size: 11px;
  color: rgba(255,255,255,0.72); letter-spacing: 0.04em;
  text-transform: uppercase; margin-left: 4px;
}
.chart-interactive .tip-value .tip-proj-line {
  font-weight: 600; font-size: 13px; color: #ff8a85;
  margin-top: 4px;
}
.chart-interactive .tip-value .tip-proj-pi {
  font-weight: 400; font-size: 11px;
  color: rgba(255,255,255,0.7); letter-spacing: 0.02em;
}
.chart-interactive .tip-rows {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.chart-interactive .tip-row {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  gap: 8px; align-items: center;
}
.chart-interactive .tip-row .swatch {
  width: 8px; height: 8px; border-radius: 50%;
  background: #fff; border: 1px solid rgba(255,255,255,0.5);
}
.chart-interactive .tip-row .swatch.focal { background: #F9322B; border-color: #F9322B; }
.chart-interactive .tip-row .swatch.muted { background: #8BA3BE; border-color: #8BA3BE; }
.chart-interactive .tip-row .swatch.dashed {
  background: transparent; border: 1px dashed #fff;
}
.chart-interactive .tip-row .tip-num { font-weight: 600; }

/* Bar-chart variants */
.chart-interactive[data-chart-type="bar"] { cursor: default; }
.chart-interactive[data-chart-type="bar"] rect[data-key] {
  cursor: pointer;
  transition: opacity 220ms ease;
}
.chart-interactive[data-chart-type="bar"]:hover rect[data-key] { opacity: 0.45; }
.chart-interactive[data-chart-type="bar"] rect[data-key].bar-active { opacity: 1; }

/* ─── Map UI (MapLibre + PMTiles) ─── */
.map-section {
  width: 100%;
  /* Washington's bbox is ~3:2 landscape (≈5.4° wide × 3.55° tall after the
     cos-latitude correction at 47°N). The box is a hair taller than that
     (1.4:1) so the JS fit can pad the TOP — pushing the state down clear of
     the search-box overlay — without shrinking the state. Tune per state. */
  aspect-ratio: 1.4 / 1;
  /* No top margin so the map's top edge aligns with the headline text
     in the adjacent column. */
  margin-top: 0;
  background: var(--tint);
  border: 1px solid var(--rule-fine);
  overflow: hidden;
  position: relative;
}
@media (max-width: 1100px) {
  /* Stacked layout below 1100px — map is full-width. Keep the same 3:2 as
     desktop so the wide state fills the column without the tall portrait
     whitespace the old 4/5 box created. */
  .map-section { aspect-ratio: 3 / 2; margin-top: 24px; }
}
#state-map {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  background: var(--tint);
}
.map-toolbar {
  position: absolute;
  top: 12px; left: 12px;
  z-index: 5;
  display: flex; align-items: center; gap: 0;
  background: #fff;
  border: 1px solid var(--rule-fine);
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
  overflow: hidden;
  max-width: calc(100% - 110px);
}
.map-toolbar input {
  border: none; outline: none;
  padding: 8px 10px;
  font-family: var(--sans); font-size: 13px;
  color: var(--navy);
  width: 240px; min-width: 0;
  background: transparent;
}
.map-toolbar button {
  border: none; background: var(--accent-deep); color: #fff;
  padding: 8px 14px;
  font-family: var(--sans); font-size: 11px;
  font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer; flex-shrink: 0;
}
.map-toolbar button:hover { background: var(--accent-deeper); }
@media (max-width: 720px) {
  .map-toolbar input { width: 150px; font-size: 11px; }
  .map-toolbar { max-width: calc(100% - 90px); }
}
.map-help-btn {
  position: absolute;
  top: 12px; right: 56px;
  z-index: 6;
  width: 32px; height: 32px;
  border-radius: 4px;
  border: 1px solid var(--rule-fine);
  background: #fff;
  font-family: var(--sans); font-weight: 600; font-size: 13px;
  color: var(--navy); cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
}
.map-help-btn:hover { color: var(--accent-deep); }
.map-help-panel {
  position: absolute;
  top: 52px; right: 12px;
  z-index: 6;
  width: 280px; max-width: calc(100% - 24px);
  background: #fff;
  border: 1px solid var(--rule-fine);
  border-radius: 4px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  padding: 16px 18px;
  font-size: 11px; line-height: 1.5;
  color: var(--navy);
}
.map-help-panel h4 {
  margin: 0 0 10px;
  font-family: var(--sans); font-size: 11px;
  font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--accent-deep);
}
.map-help-panel ul { margin: 0; padding-left: 18px; }
.map-help-panel li { margin-bottom: 5px; }
.map-help-panel[hidden] { display: none; }
.map-onboarding {
  position: absolute;
  bottom: 64px; left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  max-width: 86%;
  background: var(--navy); color: #fff;
  padding: 10px 14px; border-radius: 4px;
  font-family: var(--sans); font-size: 11px; line-height: 1.4;
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
  animation: mapBounceIn 0.4s ease-out;
}
.map-onboarding::after {
  content: "";
  position: absolute;
  bottom: -8px; left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--navy);
}
.map-onboarding .close { margin-left: 10px; cursor: pointer; opacity: 0.7; font-weight: 700; }
.map-onboarding .close:hover { opacity: 1; }
@keyframes mapBounceIn {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.map-legend {
  margin-top: 14px;
  display: flex; flex-wrap: wrap; gap: 6px;
  font-family: var(--sans); font-size: 11px;
  color: var(--navy);
}
.map-legend .key {
  display: inline-flex; align-items: center; gap: 5px;
  margin-right: 10px;
  padding: 2px 4px; border-radius: 2px;
  cursor: pointer; user-select: none;
  transition: opacity 0.15s, background 0.15s;
}
.map-legend .key.key-title { font-weight: 600; cursor: default; }
.map-legend .key:not(.key-title):hover { background: var(--tint); }
.map-legend .key.key-inactive { opacity: 0.35; }
.map-legend .key.key-inactive .swatch-box { filter: saturate(0); }
.map-legend .swatch-box {
  display: inline-block; width: 14px; height: 14px;
  border: 1px solid rgba(0,0,0,0.18);
}
.map-legend .key-reset {
  font-family: var(--sans); font-size: 11px;
  color: var(--muted); cursor: pointer;
  margin-left: 6px; text-decoration: underline;
}
.map-legend .key-reset:hover { color: var(--accent-deep); }
.map-help-inline {
  margin-top: 10px;
  font-family: var(--sans); font-size: 11px;
  letter-spacing: 0.04em; color: var(--muted);
  padding: 6px 0;
  border-top: 1px dashed var(--rule-fine);
}
.map-help-disclosure {
  margin-top: 12px;
  font-size: 13px; color: var(--navy);
}
.map-help-disclosure summary {
  cursor: pointer; font-weight: 600; font-size: 13px;
  padding: 4px 0;
}
.map-help-disclosure summary:hover { color: var(--accent-deep); }
.map-help-disclosure ul {
  margin: 8px 0 4px 16px; padding: 0;
  font-size: 13px; line-height: 1.6;
}
.map-help-disclosure li { margin-bottom: 3px; }

/* ─── Counties section: two-column intro, then map + live readout ─── */
.counties-intro {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: start;
  margin-bottom: 34px;
}
.counties-intro-plate { margin: 0; }
/* Counties intro: heading + Figure 4 lead on the LEFT (Figure 4 pushed toward the
   bottom of the column, near the map, with a little space below); the rate/King
   essay sits in the RIGHT column. */
.counties-intro-essay { align-self: stretch; display: flex; flex-direction: column; }
.counties-intro-essay .counties-intro-plate { margin-top: auto; padding-bottom: 0; }
/* Plate IV's description doubles as the map's intro prose (it sits beside the
   left essay), so it reads at body size — not the 13px caption size the other
   plates use for the line under their figure. */
.counties-intro .figure p.plate-desc {
  font-size: 13px;
  line-height: 1.6;
}

/* Map (right) + live county readout (left), side by side; the time-slider spans
   full width below. DOM order is map-col → readout-card; grid-column flips them
   to readout-left so the ID-based explorer JS needn't have the card relocated. */
.counties-map-grid {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 28px;
  align-items: start;
}
.counties-map-grid .explorer-card    { grid-column: 1; grid-row: 1; margin-bottom: 0; }
.counties-map-grid .counties-map-col { grid-column: 2; grid-row: 1; }
/* In the narrow readout column the four tiles go 2×2 at any viewport width. */
.counties-map-grid .explorer-tiles { grid-template-columns: 1fr 1fr; }

@media (max-width: 1100px) {
  .counties-intro { grid-template-columns: 1fr; gap: 26px; }
  .counties-map-grid { grid-template-columns: 1fr; gap: 22px; }
  .counties-map-grid .explorer-card    { grid-column: auto; grid-row: auto; margin-bottom: 16px; }
  .counties-map-grid .counties-map-col { grid-column: auto; grid-row: auto; }
}

/* (Retired May 2026: top-10 chart removed; visual ranking lives in the
   table itself via inline rate bars — see `table.county-table td.rate`
   below.) The standalone table block sits in its own .section flow
   with no special grid wrapper needed. */

/* ─── County table ─── */
.table-wrap {
  margin-top: 24px;
  border-top: 1px solid var(--navy);
}
.table-search {
  padding: 14px 0;
  display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid var(--rule-fine);
}
.table-search input {
  flex: 1; max-width: 360px;
  padding: 10px 14px;
  border: 1px solid var(--rule-fine);
  border-radius: 4px;
  font-family: var(--sans); font-size: 13px;
  color: var(--navy); background: #fff;
  outline: none;
  transition: border-color var(--transition);
}
.table-search input:focus { border-color: var(--accent-deep); }
.table-search .count {
  font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* Scroll container — sticky header + max-height so all 87 counties
   are accessible without taking over the page. */
.table-scroll {
  max-height: 480px;
  overflow-y: auto;
  /* With the new per-row sparkline the table runs ~440 px wide; let
     mobile readers swipe horizontally instead of clipping. */
  overflow-x: auto;
  border-bottom: 1px solid var(--navy);
  /* Custom scrollbar for webkit browsers */
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
  -webkit-overflow-scrolling: touch;
}
.table-scroll::-webkit-scrollbar { width: 8px; }
.table-scroll::-webkit-scrollbar-track { background: transparent; }
.table-scroll::-webkit-scrollbar-thumb {
  background: var(--rule);
  border-radius: 4px;
}
.table-scroll::-webkit-scrollbar-thumb:hover { background: var(--navy-soft); }
table.county-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
table.county-table thead {
  /* sticky is applied to each <th> below — applying it to thead leaves
     the cell-gap area transparent with border-collapse, so scrolled
     rows show through. Each th sticks individually and paints its own
     background. */
  background: var(--paper);
}
table.county-table th {
  position: sticky;
  top: 0;
  z-index: 5;
  text-align: left;
  padding: 12px 16px 12px 0;
  font-weight: 600; font-size: 11px;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--rule-fine);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  background: var(--paper);
  /* Solid box-shadow under the header so the rule reads continuously
     across the cell gaps. */
  box-shadow: 0 1px 0 var(--rule-fine);
}
table.county-table th:hover { color: var(--accent-deep); }
table.county-table th.sort-asc::after { content: " ▲"; color: var(--accent-deep); font-size: 11px; }
table.county-table th.sort-desc::after { content: " ▼"; color: var(--accent-deep); font-size: 11px; }
table.county-table th.num-col { text-align: right; padding-right: 16px; }
table.county-table td {
  padding: 10px 16px 10px 0;
  border-bottom: 1px solid var(--rule-fine);
  color: var(--navy); font-variant-numeric: tabular-nums;
}
table.county-table td.county-name { font-weight: 500; }
table.county-table td.num { text-align: right; padding-right: 16px; }
table.county-table tr.hi td.county-name { color: var(--accent-deep); font-weight: 600; }
table.county-table .small-n {
  color: var(--muted, #586573); font-size: 0.72em; font-weight: 400;
  vertical-align: super; margin-left: 2px; cursor: help;
}
table.county-table tr.hi td.rate { color: var(--accent-deep); font-weight: 600; }
table.county-table tbody tr:hover td { background: var(--tint); }

/* Inline bar on the Rate column only. Bar length is set via the
   `--bar-pct` custom property (computed in JS from RATE_MAX). Implemented
   as a ::before pseudo-element so the bar lives behind the number; the
   `> span` rule lifts the digits above it. Hidden when the table carries
   the .bars-off class (toggled by the "Hide bars" button). */
table.county-table td.num {
  position: relative;
  min-width: 110px;
}
table.county-table td.num.rate::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: var(--bar-pct, 0%);
  height: 16px;
  transform: translateY(-50%);
  background: rgba(25, 34, 44, 0.12);
  border-radius: 2px;
  pointer-events: none;
  z-index: 0;
  transition: width 220ms ease;
}
table.county-table tr.hi td.rate::before {
  background: rgba(249, 50, 43, 0.20);
}
table.county-table td.num > span { position: relative; z-index: 1; }
/* Hide the rate bar when the user toggles bars off */
table.county-table.bars-off td.num.rate::before { display: none; }

/* Bars on/off toggle button — sits next to the search input + count. */
.table-search .bars-toggle {
  margin-left: auto;
  padding: 6px 12px;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: #fff;
  color: var(--navy);
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: border-color var(--transition), color var(--transition),
              background var(--transition);
}
.table-search .bars-toggle:hover {
  border-color: var(--accent-deep);
  color: var(--accent-deep);
}
.table-search .bars-toggle[aria-pressed="false"] {
  background: var(--tint);
  color: var(--muted);
}

/* ─── Methodology ─── */
.methodology {
  padding: 64px 0;
  border-top: 1px solid var(--rule-fine);
  display: grid; grid-template-columns: 200px 1fr;
  gap: 64px;
}
@media (max-width: 720px) { .methodology { grid-template-columns: 1fr; gap: 24px; } }
.methodology h3 {
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  margin: 0; color: var(--navy);
}
.methodology p {
  font-size: 13px; line-height: 1.65;
  color: var(--muted); margin: 0 0 12px;
  max-width: 64ch;
}
.methodology p strong { color: var(--navy); font-weight: 600; }

/* ─── Footer ─── */
footer.site {
  padding: 64px 0 32px;
  border-top: 1px solid var(--rule-fine);
}
footer.site .grid {
  display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: 36px;
}
@media (max-width: 720px) { footer.site .grid { grid-template-columns: 1fr 1fr; } }
footer.site .col h4 {
  font-size: 13px; font-weight: 600; margin: 0 0 14px;
  color: var(--navy);
}
footer.site .col ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 8px;
  font-size: 13px;
}
footer.site .col ul a { border: none; color: var(--navy-soft); }
footer.site .col ul a:hover { color: var(--accent-deep); }
footer.site .about p {
  font-size: 13px; line-height: 1.55;
  color: var(--muted); margin: 14px 0 0;
  max-width: 36ch;
}
footer.site .about img { max-height: 32px; width: auto; display: block; }
footer.site .imprint {
  grid-column: 1 / -1; margin-top: 36px;
  padding-top: 18px; border-top: 1px solid var(--rule-fine);
  font-size: 11px; color: var(--muted);
  display: flex; justify-content: space-between;
  flex-wrap: wrap; gap: 12px;
}

/* ─── Map time-window explorer ──────────────────────────────────────────────
   Sits directly under the choropleth. Stats card on top, histogram + dual-
   handle slider + date pickers below. Vertical layout — works on mobile.
   The PDA pattern (cidrlab.org/pda/...) was the structural model; the
   look-and-feel is tuned to MN brand tokens. */
.map-explorer {
  margin: 0;
  /* Tint backdrop so the white readout card + the map read as panels floating
     on it, rather than white-on-white. Matches the map's own tint placeholder. */
  background: var(--tint);
}

/* Stats card. White card with thin border, generous padding. */
.explorer-card {
  border: 1px solid var(--rule-fine);
  border-radius: 8px;
  padding: 22px 24px 18px;
  background: var(--paper);
  margin-bottom: 16px;
}
.explorer-card-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 18px; flex-wrap: wrap;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule-fine);
}
.explorer-place { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.explorer-kicker {
  font-family: var(--sans); font-size: 16px; font-weight: 600;
  color: var(--navy); letter-spacing: -0.005em;
}
.explorer-sub {
  font-size: 11px; color: var(--muted); letter-spacing: 0.04em;
  text-transform: uppercase; font-weight: 500;
}
.explorer-window {
  font-family: var(--sans); font-size: 11px; color: var(--muted);
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
}

/* Four stat tiles in a row. Collapse to 2x2 on small screens, then to a
   single column on tiny ones. */
.explorer-tiles {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1.4fr;
  gap: 18px;
  align-items: stretch;
}
.explorer-tile {
  display: flex; flex-direction: column; gap: 4px;
  padding: 4px 0;
}
.explorer-tile-num {
  font-family: var(--sans);
  font-size: 30px; font-weight: 600; color: var(--navy);
  line-height: 1.05; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.explorer-tile-label {
  font-size: 11px; color: var(--muted);
  letter-spacing: 0.04em; text-transform: uppercase;
  line-height: 1.35;
  font-weight: 500;
}
.explorer-tile-sublabel {
  font-style: italic; text-transform: none; letter-spacing: 0;
  font-size: 11px; color: var(--muted);
}
/* Sparkline tile renders a wider area for the chart */
.explorer-tile-spark svg { width: 100%; height: 56px; display: block; }

@media (max-width: 880px) {
  .explorer-tiles { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .explorer-tiles { grid-template-columns: 1fr; }
}

/* Race breakdown row — one row per race, label + horizontal bar + value */
.explorer-race {
  display: grid; grid-template-columns: 1fr;
  gap: 8px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--rule-fine);
}
.explorer-race-row {
  display: grid;
  grid-template-columns: 60px 1fr 70px;
  align-items: center; gap: 12px;
  font-variant-numeric: tabular-nums;
}
.explorer-race-label {
  font-size: 11px; font-weight: 600; color: var(--navy);
  letter-spacing: 0.02em;
}
.explorer-race-bar {
  position: relative; display: block;
  height: 10px; background: var(--rule-fine);
  border-radius: 2px; overflow: hidden;
}
.explorer-race-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--navy);
  width: 0%;
  transition: width 250ms ease;
}
/* Color-code the highlight to match the eviction-page palette */
.explorer-race-fill[data-race="black"]  { background: var(--navy); }
.explorer-race-fill[data-race="latine"] { background: var(--navy-soft); }
.explorer-race-fill[data-race="other"]  { background: var(--steel); }
.explorer-race-fill[data-race="white"]  { background: #aab4be; }
.explorer-race-value {
  font-size: 11px; font-weight: 600; color: var(--navy);
  text-align: right;
}
.explorer-race-note {
  font-size: 11px; color: var(--muted); font-style: italic;
  margin: 10px 0 0;
  line-height: 1.5;
}
/* When the panel shows a tract (no race breakdown), the note replaces bars */
.explorer-race.tract-mode .explorer-race-row { display: none; }
.explorer-race.tract-mode .explorer-race-note { display: block; }

/* ─── County characteristics in the readout (ACS, data/o2c_county_acs.json) ─── */
.explorer-chars {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--rule-fine);
}
.ec-group { margin-bottom: 16px; }
.ec-group-title {
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--accent-deep);
  margin: 0 0 7px;
}
.ec-row {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; padding: 4px 0; font-size: 13px; line-height: 1.4;
  border-bottom: 1px dotted var(--rule-fine);
}
.ec-row:last-child { border-bottom: none; }
.ec-label { color: var(--muted); }
.ec-val {
  color: var(--navy); font-weight: 600; text-align: right;
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.ec-is-driver .ec-label::after {
  content: " \25B2"; color: var(--accent-deep);
  font-size: 0.7em; vertical-align: 1.5px; font-weight: 700;
}
/* Renter race composition bars */
.ec-bars { display: flex; flex-direction: column; gap: 6px; }
.ec-bar-row {
  display: grid; grid-template-columns: 62px 1fr 38px;
  align-items: center; gap: 9px; font-size: 13px;
}
.ec-bar-label { color: var(--muted); }
.ec-bar-track {
  height: 7px; background: var(--tint); border-radius: 4px; overflow: hidden;
}
.ec-bar-fill { display: block; height: 100%; background: var(--navy); border-radius: 4px; }
.ec-bar-val {
  text-align: right; color: var(--navy); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ec-note {
  font-size: 11px; color: var(--muted); line-height: 1.45;
  margin: 12px 0 0; font-style: italic;
}
.ec-driver-tag { color: var(--accent-deep); font-style: normal; }

/* Histogram + slider + pickers, in a tinted panel under the stats card. */
.explorer-controls {
  margin-top: 20px;
  padding: 22px 28px 18px;
  background: var(--paper);
  border: 1px solid var(--rule-fine);
  border-radius: 8px;
}
.explorer-controls .trend-stack {
  display: flex; flex-direction: column;
  padding: 0 7px;
  gap: 6px;
}
.explorer-controls .trend-stack svg {
  width: 100%; height: 64px; display: block;
  background: transparent;
}
.explorer-controls .trend-stack #explorer-slider { width: 100%; }
.explorer-controls .trend-axis {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--muted);
  letter-spacing: 0.04em;
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.explorer-controls .date-pickers-row {
  display: flex; align-items: end; justify-content: space-between;
  gap: 24px; margin-top: 40px;
}
@media (max-width: 720px) {
  .explorer-controls .date-pickers-row { flex-direction: column; align-items: stretch; gap: 14px; }
}
.explorer-controls .date-pickers {
  display: flex; gap: 12px; align-items: end;
  flex-wrap: nowrap;
}
.explorer-controls .date-pickers label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted);
}
.explorer-controls .date-pickers input[type="date"] {
  padding: 8px 10px; font-family: var(--sans);
  font-size: 13px; color: var(--navy);
  border: 1px solid var(--rule); border-radius: 4px;
  background: #fff; outline: none; min-width: 124px;
  font-variant-numeric: tabular-nums;
}
.explorer-controls .date-pickers input[type="date"]:focus { border-color: var(--accent-deep); }
.explorer-controls .ghost-btn {
  font-family: var(--sans); font-size: 11px;
  font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 9px 14px; border-radius: 4px;
  border: 1px solid var(--navy); background: transparent; color: var(--navy);
  cursor: pointer; transition: all var(--transition);
}
.explorer-controls .ghost-btn:hover { color: var(--accent-deep); border-color: var(--accent-deep); }
.explorer-controls .hint {
  font-size: 11px; color: var(--muted);
  font-style: italic; margin: 0;
  max-width: 56ch;
}

/* noUiSlider — match brand */
#explorer-slider.noUi-target { background: rgba(25,34,44,0.12); border: none; box-shadow: none; height: 4px; }
#explorer-slider .noUi-connect { background: var(--navy); cursor: grab; }
#explorer-slider .noUi-connect:active { cursor: grabbing; }
#explorer-slider .noUi-handle {
  width: 14px !important; height: 14px !important;
  right: -7px !important; top: -5px !important;
  border-radius: 50%; background: var(--accent);
  border: 2px solid #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.18);
  cursor: grab;
}
#explorer-slider .noUi-handle::before,
#explorer-slider .noUi-handle::after { display: none; }
#explorer-slider .noUi-handle:active { cursor: grabbing; }
#explorer-slider .noUi-tooltip {
  background: var(--navy); color: #fff; border: none;
  padding: 4px 8px; font-family: var(--sans); font-size: 11px;
  font-weight: 600; letter-spacing: 0.02em; border-radius: 3px;
  font-variant-numeric: tabular-nums;
  display: none;
}
#explorer-slider .noUi-handle:hover .noUi-tooltip,
#explorer-slider .noUi-handle.noUi-active .noUi-tooltip,
#explorer-slider .noUi-handle:focus .noUi-tooltip { display: block; }

/* ─── Mini sparkline hover (4th tile in the explorer card) ─── */
.spark-wrap { position: relative; }
.spark-wrap svg { width: 100%; height: 64px; display: block; cursor: default; }
/* Faint dashed top line (inside the SVG) — visible only on hover. */
.spark-wrap .spark-axis {
  opacity: 0; transition: opacity 120ms ease; pointer-events: none;
}
.spark-wrap:hover .spark-axis { opacity: 1; }
/* Vertical guide line stays in the SVG (lines stretch fine). */
.spark-wrap .spark-guide {
  opacity: 0; transition: opacity 120ms ease; pointer-events: none;
}
.spark-wrap:hover .spark-guide { opacity: 1; }
/* HTML hover dot — kept outside the SVG so it stays a true circle. */
.spark-dot {
  position: absolute; pointer-events: none;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
  border: 1.5px solid #fff;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.05);
  transform: translate(-50%, -50%);
  z-index: 3;
}
.spark-dot[hidden] { display: none; }
/* Caption row under the chart: "max X" by default, "max X · MMM YYYY · N filings" on hover. */
.spark-caption {
  font-family: var(--sans); font-size: 11px;
  color: var(--muted); font-variant-numeric: tabular-nums;
  margin-top: 6px;
  letter-spacing: 0.02em;
  line-height: 1.4;
}
.spark-caption .spark-caption-max  { font-weight: 600; color: var(--muted); }
.spark-caption .spark-caption-sep[hidden],
.spark-caption .spark-caption-tip[hidden] { display: none; }
.spark-caption .spark-caption-tip { color: var(--navy); font-weight: 600; }
.spark-caption .spark-tip-date  { letter-spacing: 0.06em; text-transform: uppercase; }
.spark-caption .spark-tip-value { font-weight: 700; }

/* ─── Tbl 01 — sparkline + tightened columns ───
   The Filings cell hosts a small per-county sparkline next to its
   number. Renter HH gets less right padding so the row breathes. */
table.county-table td.col-renters { min-width: 70px; padding-right: 10px; }
table.county-table th.col-renters { padding-right: 10px; }
table.county-table td.col-filings,
table.county-table th.col-filings { min-width: 260px; padding-right: 14px; }
table.county-table .filings-cell-inner {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 14px;
}
table.county-table .filings-spark {
  flex: 1 1 auto; max-width: 200px; height: 24px; display: inline-block;
  opacity: 0.95;
}
table.county-table .filings-spark svg {
  width: 100%; height: 100%; display: block;
}
table.county-table .filings-num {
  min-width: 50px; text-align: right;
  font-variant-numeric: tabular-nums;
}
table.county-table tr.hi .filings-spark { opacity: 1; }

/* Small reset / refresh hint right under the map legend. */
.map-refresh-hint {
  font-size: 11px; color: var(--muted);
  font-style: italic;
  margin: 8px 0 0;
  text-align: center;
  line-height: 1.5;
}
.map-refresh-hint a { color: var(--accent-deep); border-color: var(--accent-deep); }

/* Mobile portrait — table is ~520 px wide with the sparkline; the rate
   column ends up off-screen on a 360–414 px phone. Hide the sparkline
   below 600 px so County + Renter HH + Filings + Rate all fit without
   horizontal scroll. The full table is still available on rotate /
   tablet / desktop. */
@media (max-width: 600px) {
  table.county-table .filings-spark { display: none; }
  table.county-table td.col-filings,
  table.county-table th.col-filings { min-width: 80px; padding-right: 10px; }
  table.county-table .filings-cell-inner { gap: 0; }
}

/* Map button strip — sits below the map onboarding hint, hosts the
   county-outline toggle (and any future per-map toggles). */
.map-toggle-row {
  display: flex; justify-content: flex-end; gap: 8px;
  margin: 6px 0 0;
}
.map-toggle-row .map-toggle-btn {
  font-family: var(--sans); font-size: 11px;
  font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 12px; border-radius: 4px;
  border: 1px solid var(--rule); background: #fff; color: var(--navy);
  cursor: pointer; transition: all var(--transition);
}
.map-toggle-row .map-toggle-btn:hover { color: var(--accent-deep); border-color: var(--accent-deep); }
.map-toggle-row .map-toggle-btn[aria-pressed="true"] {
  background: var(--navy); color: #fff; border-color: var(--navy);
}

/* Loading overlay shown while the choropleth fill-opacity is 0
   (initial load, basemap visible). Hidden via [hidden] the moment
   the first ckmeans paint lands. Pointer-events disabled so it
   doesn't block map interaction (search box, zoom, etc.). */
.map-loading {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 16px 9px 12px;
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid var(--rule-fine);
  border-radius: 999px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  font-family: var(--sans); font-size: 11px;
  font-weight: 600; letter-spacing: 0.03em;
  color: var(--navy);
  pointer-events: none;
  z-index: 30;
}
.map-loading[hidden] { display: none; }
.map-loading-spinner {
  width: 14px; height: 14px;
  border: 2px solid var(--rule);
  border-top-color: var(--accent-deep);
  border-radius: 50%;
  animation: map-spin 0.8s linear infinite;
}
@keyframes map-spin {
  to { transform: rotate(360deg); }
}

/* ──────────────────────────────────────────────────────────────────────
   County name markers (HTML <div> overlay, attached via maplibregl.Marker
   from o2b_county_monthly.json centroid lon/lat). Used in county-only
   states where the basemap glyph stack can't be relied on for symbol
   labels. Hidden via .hide-county-names on the #state-map container.
   ────────────────────────────────────────────────────────────────────── */
.county-name-marker {
  font-family: 'Inter', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #19222C;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  text-shadow:
    0 0 4px rgba(255, 255, 255, 0.95),
    0 0 4px rgba(255, 255, 255, 0.95),
    0 0 4px rgba(255, 255, 255, 0.95);
}
#state-map.hide-county-names .county-name-marker {
  display: none;
}

/* ──────────────────────────────────────────────────────────────────────
   Plate III — Counties on the rise (interactive trend chart)
   ────────────────────────────────────────────────────────────────────── */
.plate-rising-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 36px;
  align-items: start;
}
@media (max-width: 900px) {
  .plate-rising-layout { grid-template-columns: 1fr; gap: 24px; }
}
/* Plate III's chart-beside-title layout (Tim, 2026-08-20, replacing a
   float that text cleared below instead of wrapping): named grid areas —
   chart top-left, the section title + claim to its RIGHT, and the body
   prose full width beneath both. The .plate-rising-text wrapper becomes
   display:contents so its .plate-rising-head and .plate-rising-bodyblock
   children take the grid areas directly. Opt in as
   {.plate-rising-layout .chart-wrap}; on narrow screens the areas stack
   title-first. */
.plate-rising-layout.chart-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  grid-template-areas: "chart head" "body body";
  column-gap: 44px; row-gap: 10px;
  align-items: start;
}
.plate-rising-layout.chart-wrap > .plate-rising-chart { grid-area: chart; }
.plate-rising-layout.chart-wrap > .plate-rising-text { display: contents; }
.plate-rising-layout.chart-wrap .plate-rising-head { grid-area: head; padding-top: 8px; }
.plate-rising-layout.chart-wrap .plate-rising-bodyblock { grid-area: body; }
@media (max-width: 900px) {
  .plate-rising-layout.chart-wrap {
    grid-template-columns: 1fr;
    grid-template-areas: "head" "chart" "body";
  }
}
.plate-rising-chart { position: relative; min-width: 0; }
.plate-rising-text { padding-top: 8px; }
.plate-rising-text .section-title { margin-top: 0; }
.plate-rising-text .plate-claim { margin: 18px 0 12px; }
.plate-rising-body p {
  font-size: 16px; line-height: 1.7; color: var(--navy); margin: 0 0 16px;
}

.ct-controls {
  display: flex; flex-wrap: wrap; gap: 14px;
  align-items: center; margin: 14px 0 12px;
  font-family: 'Inter', sans-serif; font-size: 13px;
}
.ct-toggle {
  display: inline-flex; border: 1px solid #d0d4d8; border-radius: 4px;
  overflow: hidden; background: #fff;
}
.ct-toggle-btn, .proj-toggle-btn, .ct-proj-btn {
  appearance: none; border: 0; background: #fff; color: var(--navy);
  font: 600 12px/1 'Inter', sans-serif; letter-spacing: 0.02em;
  text-transform: uppercase; padding: 8px 14px; cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.ct-toggle-btn + .ct-toggle-btn,
.proj-toggle-btn + .proj-toggle-btn,
.ct-proj-btn + .ct-proj-btn { border-left: 1px solid #d0d4d8; }
.ct-toggle-btn:hover, .proj-toggle-btn:hover, .ct-proj-btn:hover { background: #f3f4f6; }
.ct-toggle-btn.ct-active, .proj-toggle-btn.ct-active,
.ct-proj-btn.ct-active { background: var(--navy); color: #fff; }
/* .ct-toggle sets display, which would override the hidden attribute. */
.ct-toggle[hidden] { display: none; }
/* Figure 1's projection buttons share the county-trend toggle's look but not
   its class, since that handler binds every .ct-toggle-btn on the page. */
.proj-controls { margin: 18px 0 0; }
.proj-controls .ct-select-label { color: var(--navy); }
.ct-select-wrap {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--navy);
}
.ct-select-label {
  font: 600 12px/1 'Inter', sans-serif; letter-spacing: 0.02em;
  text-transform: uppercase;
}
.ct-select {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid #d0d4d8; border-radius: 4px; background: #fff;
  padding: 7px 28px 7px 10px; font: 500 13px 'Inter', sans-serif;
  color: var(--navy); cursor: pointer; min-width: 180px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%2319222C' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 12px 8px;
}
.ct-select:focus, .ct-toggle-btn:focus-visible, .proj-toggle-btn:focus-visible,
.ct-proj-btn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

#chart-county-trend { width: 100%; height: auto; overflow: visible; }
/* Default view tells the "21 of 39" story as a two-tone binary: the record
   counties (2024/25 annual peaks) are brand red; the other 18 are dark navy.
   Navy (not steel-blue) gives the field much stronger contrast against white
   and a cleaner red-vs-navy read — the page's core ink/accent pairing. Opacity
   is lifted (0.7) and the stroke thickened so the navy group reads as solid
   lines, not a faint wash. */
#chart-county-trend .ctl {
  fill: none; stroke: var(--navy, #19222C); stroke-width: 1; opacity: 0.7;
  stroke-linejoin: round; stroke-linecap: round; pointer-events: stroke;
  transition: opacity 120ms ease, stroke 120ms ease, stroke-width 120ms ease;
}
#chart-county-trend .ctl-record  { stroke: var(--accent); opacity: 0.7; stroke-width: 1.4; }
/* The projected final year (yearly view): same color as the line, dashed. */
#chart-county-trend .ctl-proj { stroke-dasharray: 4 3; }
#chart-county-trend .ctl:hover   { stroke: var(--accent); opacity: 1; stroke-width: 2.4; }
/* When a county is picked from the dropdown, the chart JS adds .ct-has-selection
   to the SVG: the chosen line goes red and bold, and every other line (record
   or not) recedes to a faint navy so the selection pops. */
#chart-county-trend.ct-has-selection .ctl,
#chart-county-trend.ct-has-selection .ctl-record {
  stroke: var(--navy, #19222C); opacity: 0.18; stroke-width: 0.8;
}
#chart-county-trend.ct-has-selection .ctl.ct-selected {
  stroke: var(--accent); opacity: 1; stroke-width: 2.6;
}
#chart-county-trend .ctgrid { stroke: #e6e6e6; stroke-width: 0.5; }
#chart-county-trend .ctax {
  font-family: 'Inter', sans-serif; font-size: calc(11px / var(--sx, 1)); fill: #586573;
  font-variant-numeric: tabular-nums;
}
#chart-county-trend .ctlbl {
  font-family: 'Inter', sans-serif; font-size: calc(11px / var(--sx, 1)); fill: #586573;
  font-weight: 500; pointer-events: none;
}
#chart-county-trend .ctlbl.ct-selected { fill: var(--accent-deep); font-weight: 600; } /* selected label is TEXT — use WCAG-safe deep red */
#chart-county-trend .ct-cursor { stroke: var(--navy); stroke-width: 0.75; stroke-dasharray: 2 3; opacity: 0; }
#chart-county-trend .ct-cursor.active { opacity: 0.45; }
#chart-county-trend .ct-dot { fill: var(--accent); opacity: 0; }
#chart-county-trend .ct-dot.active { opacity: 1; }

/* Single transparent rect captures all mousemoves over the chart area.
   Without it the user has to land exactly on a 1px stroke — with it we
   compute the nearest line at the cursor's x and highlight that one. */
#chart-county-trend .ct-hit { fill: transparent; pointer-events: all; cursor: default; }
#chart-county-trend .ctl.ct-hover {
  stroke: var(--accent); opacity: 1; stroke-width: 2.2;
}
/* Y-axis: anchor (1,000) always visible; other gridlines fade in on hover. */
#chart-county-trend .ctax-anchor { fill: var(--navy); font-weight: 600; }
#chart-county-trend .ct-anchor .ctgrid { stroke: #c4c8cd; stroke-width: 0.8; stroke-dasharray: 3 3; }
#chart-county-trend .hover-grid { opacity: 0; transition: opacity 180ms ease; }
.plate-rising-chart:hover #chart-county-trend .hover-grid { opacity: 1; }

.ct-tooltip {
  position: absolute; pointer-events: none; opacity: 0;
  transform: translate(-50%, -100%);
  background: rgba(25, 34, 44, 0.95); color: #fff;
  font: 500 12px/1.4 'Inter', sans-serif;
  padding: 6px 10px; border-radius: 4px; white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2); transition: opacity 80ms ease;
  z-index: 2;
}
.ct-tooltip.active { opacity: 1; }
.ct-tooltip .ct-tip-name { font-weight: 600; }
.ct-tooltip .ct-tip-value {
  font-variant-numeric: tabular-nums; opacity: 0.92; margin-left: 4px;
}

/* --------------------------------------------------------------
   Accessibility — WCAG 2.1 AA
   Added 2026-06-16: skip link, sr-only utility, visible focus.
   (In-content links already carry a border-bottom underline, so the
    1.4.1 use-of-color requirement is met by the base `a` rule above.)
   -------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: 8px;
  top: -48px;
  background: #ffffff;
  color: var(--navy, #19222C);
  padding: 10px 16px;
  border-radius: 4px;
  z-index: 10000;
  font-weight: 600;
  font-family: var(--sans, sans-serif);
  text-decoration: none;
  border-bottom: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
  transition: top 0.15s ease-in-out;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 8px;
  outline: 3px solid var(--accent, #F9322B);
  outline-offset: 2px;
  color: var(--navy, #19222C);
}

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

/* Restore a visible focus ring on keyboard navigation. The base
   `a:hover, a:focus { outline: none }` rule above suppresses it, so
   re-assert it for :focus-visible (keyboard) only — mouse users are
   unaffected, keyboard users get a clear indicator (WCAG 2.4.7). */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--accent, #F9322B);
  outline-offset: 2px;
  border-radius: 2px;
}

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

/* ─── Source directory (.src-list) ──────────────────────────────────────────
   The "where the data lives" list each state profile carries: the source
   behind the page first, then every other active collection effort in the
   state, deepest coverage to narrowest. Shared so the states read alike. */
.src-list { list-style: none; margin: 0; padding: 0; }
.src-list li {
  padding: 14px 2px;
  border-bottom: 1px solid var(--rule-fine);
  font-size: 15px; line-height: 1.5;
}
.src-list li:last-child { border-bottom: 0; }
.src-list li a {
  color: var(--navy); font-weight: 600;
  border-bottom: 2px solid var(--accent);
}
.src-list li a:hover, .src-list li a:focus {
  color: var(--accent-deep); border-bottom-color: var(--accent-deep);
}
.src-list li span {
  display: block; color: var(--muted);
  font-size: 13.5px; line-height: 1.55; margin-top: 3px;
}
.src-list li span strong { color: var(--navy); font-weight: 600; }

/* ==========================================================================
   County-table second-line headers and the change column
   Both are opt-in from nt_profile_county_table (sub_labels, change_th), so a
   state that passes neither renders exactly as before.
   ========================================================================== */
table.county-table th .th-sub {
  display: block; font-size: 10px; font-weight: 500; letter-spacing: .02em;
  text-transform: none; color: var(--muted); margin-top: 2px;
}
/* Direction of change is carried by colour AND sign, never colour alone. */
table.county-table td.chg.up   { color: var(--accent-deeper); }
table.county-table td.chg.down { color: var(--navy-soft); }
table.county-table td.chg      { font-variant-numeric: tabular-nums; }
table.county-table .tbl-nr     { color: var(--muted); }

/* ==========================================================================
   Multi-paragraph method note
   The .p callout renders as a literal <p>, so it silently drops everything
   after its first paragraph. Use .method-note where a caveat needs more than
   one paragraph, a quotation, or a citation link.
   ========================================================================== */
aside.method-note {
  background: var(--tint, #eef3f8);
  border-left: 3px solid var(--accent);
  padding: 14px 18px; margin: 32px 0 0;
  font-size: 13px; line-height: 1.65; color: var(--navy);
}
aside.method-note p { margin: 0 0 10px; }
aside.method-note p:last-child { margin-bottom: 0; }
aside.method-note a { color: var(--accent-deep); text-decoration: underline; }
aside.method-note a:hover { color: var(--accent-deeper, #CC2118); }

/* ==========================================================================
   ANNUAL-GRAIN STATES AND THE FIGURE FAMILIES THAT COME WITH THEM

   Everything below was written for California, the first state whose court
   feed publishes one number a year rather than one a month. It is inert on
   a monthly state: none of these class names appear in a monthly page's
   markup. Two rules are the exception and do apply everywhere, both at the
   end of the annual-map block: the two-column methodology layout and the
   .methodology p cap that has to come off for it.
   ========================================================================== */

/* ==========================================================================
   Annual-state county map (nt_profile_map_svg)

   For states whose court feed publishes yearly rather than monthly. The
   monthly profiles use the MapLibre explorer and its .counties-map-grid;
   this is the static-SVG equivalent. Layout is info-left / map-right: a
   portrait state pairs with a tall column of controls and characteristics,
   and the map sticks while that column scrolls.
   ========================================================================== */
.annual-map .map-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 520px);
  gap: 44px; align-items: start;
}
.annual-map .map-col { max-width: 520px; position: sticky; top: calc(var(--header-h) + 8px); }
.annual-map-wrap { position: relative; }
.annual-map-svg { width: 100%; height: auto; display: block; }
@media (max-width: 980px) {
  .annual-map .map-layout { grid-template-columns: 1fr; gap: 22px; }
  .annual-map .map-col { max-width: 520px; margin: 0 auto; width: 100%; position: static; }
}

/* county shapes + labels */
.am-county { stroke: #fff; stroke-width: 0.4; cursor: pointer; transition: fill .15s; }
.am-county:hover { stroke: var(--navy); stroke-width: 1.2; }
.am-county-sel { stroke: var(--navy); stroke-width: 2; }
.am-city-dot { fill: var(--navy); stroke: #fff; stroke-width: 1; }
.am-city-label {
  font-family: var(--sans); font-size: 12px; font-weight: 600; fill: var(--navy);
  paint-order: stroke; stroke: #fff; stroke-width: 3px; stroke-linejoin: round;
}
/* County labels sit on top of saturated choropleth fills (pale yellow through
   deep purple), so they are drawn as opaque navy with a solid white halo
   rather than a tinted gray. The earlier 40%-opacity fill disappeared against
   the orange and red bins. paint-order puts the halo behind the glyphs. */
.am-county-label {
  font-family: var(--sans); font-size: 9.5px; font-weight: 600;
  fill: var(--navy);
  paint-order: stroke; stroke: #fff; stroke-width: 2.8px;
  stroke-linejoin: round; stroke-opacity: 0.92;
  pointer-events: none;
}
.am-search-dot { fill: var(--accent-deeper); stroke: #fff; stroke-width: 1.5; }
.am-search-label {
  font-family: var(--sans); font-size: 12px; font-weight: 700; fill: var(--accent-deeper);
  text-anchor: middle; paint-order: stroke; stroke: #fff; stroke-width: 3.5px;
  stroke-linejoin: round;
}

/* tooltip */
.annual-map .ca-tip {
  position: absolute; pointer-events: none; opacity: 0; transition: opacity .12s;
  background: var(--navy); color: #fff; font-family: var(--sans); font-size: 12.5px;
  line-height: 1.45; padding: 8px 11px; border-radius: 7px; max-width: 230px; z-index: 5;
}
.am-tip-sub { color: #cdd6df; }
.am-tip-warn { color: #ff8079; }

/* legend + toggles */
.annual-map .map-legend-row {
  display: flex; flex-wrap: wrap; gap: 16px; margin-top: 12px;
  font-family: var(--sans); font-size: 12px; color: var(--muted); align-items: center;
}
.annual-map .map-legend-row .key { display: inline-flex; align-items: center; gap: 7px; }
.annual-map .map-legend-row .sw { width: 18px; height: 12px; display: inline-block; border-radius: 2px; }
.annual-map .map-toggle-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 2px; }

/* search */
.map-search-row { margin: 16px 0 2px; }
.map-search-label {
  display: block; font-family: var(--sans); font-size: 12px; font-weight: 600;
  color: var(--muted); margin-bottom: 7px;
}
.map-search-controls { display: flex; flex-wrap: wrap; gap: 8px; }
.map-search-input {
  font-family: var(--sans); font-size: 13px; padding: 7px 11px;
  border: 1px solid #d7dce1; border-radius: 6px; color: var(--navy);
  background: var(--paper); flex: 1 1 210px; min-width: 0;
}
.map-search-input:focus { outline: 2px solid var(--navy); outline-offset: 1px; border-color: var(--navy); }
.map-search-status {
  font-family: var(--sans); font-size: 12.5px; color: var(--muted);
  margin: 9px 0 0; min-height: 1.2em;
}

/* readout card head — the monthly profiles use .explorer-card-head; this is
   the annual variant, with the period label instead of a month window */
.annual-map .explorer-card { margin-top: 26px; padding: 20px 22px 4px; }
.annual-map .ec-title {
  font-size: 20px; font-weight: 700; color: var(--navy); margin: 0; letter-spacing: -0.01em;
}
.annual-map .ec-eyebrow {
  font-family: var(--sans); font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted); margin: 5px 0 0;
}
.annual-map .ec-window { font-family: var(--sans); font-size: 12.5px; color: var(--muted); margin: 12px 0 0; }
.annual-map .ec-headline-row {
  display: flex; flex-wrap: wrap; gap: 18px 30px; margin: 14px 0 0;
  padding: 16px 0 0; border-top: 1px solid var(--rule-fine);
}
.annual-map .ec-headline { display: flex; flex-direction: column; gap: 3px; min-width: 120px; flex: 1 1 120px; }
.annual-map .ec-headline-num {
  font-family: var(--sans); font-size: 30px; font-weight: 700; color: var(--navy);
  font-variant-numeric: tabular-nums; line-height: 1;
}
.annual-map .ec-headline-lab {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted); line-height: 1.35;
}
.annual-map .explorer-chars { display: block; }
.annual-map .ec-group { padding: 18px 0 4px; }
.annual-map .ec-note { margin: 14px 0 0; padding: 14px 0 18px; border-top: 1px solid var(--rule-fine); }
.annual-map .ec-flag {
  font-family: var(--sans); font-size: 11.5px; line-height: 1.5;
  color: var(--accent-deeper); margin: 10px 0 0;
}

/* Muted small counties, zoom controls. The --zk variable is set by the zoom
   handler to 1/scale, so strokes and label text keep their on-screen size as
   the map scales up instead of thickening and ballooning. */
.am-county-muted { opacity: 0.42; }
.annual-map .map-legend-row .sw-muted { opacity: 0.42; }
.am-zoom-root { --zk: 1; }
.am-zoom-root .am-county { stroke-width: calc(0.4px * var(--zk)); }
.am-zoom-root .am-county:hover { stroke-width: calc(1.2px * var(--zk)); }
.am-zoom-root .am-county-sel { stroke-width: calc(2px * var(--zk)); }
.am-zoom-root .am-city-label { font-size: calc(12px * var(--zk)); stroke-width: calc(3px * var(--zk)); }
.am-zoom-root .am-county-label { font-size: calc(9.5px * var(--zk)); stroke-width: calc(2.8px * var(--zk)); }
.am-zoom-root .am-city-dot { r: calc(3px * var(--zk)); stroke-width: calc(1px * var(--zk)); }
.am-zoom-root .am-search-dot { r: calc(4.5px * var(--zk)); stroke-width: calc(1.5px * var(--zk)); }
.am-zoom-root .am-search-label { font-size: calc(12px * var(--zk)); stroke-width: calc(3.5px * var(--zk)); }

.annual-map-wrap { position: relative; }
.annual-map-svg { touch-action: none; cursor: grab; }
.annual-map-svg:active { cursor: grabbing; }
.am-zoom-controls {
  position: absolute; top: 8px; right: 8px; z-index: 3;
  display: flex; flex-direction: column; gap: 5px;
}
.am-zoom-btn {
  font-family: var(--sans); font-size: 14px; font-weight: 700; line-height: 1;
  width: 30px; min-height: 30px; padding: 0 6px; cursor: pointer;
  border: 1px solid #d7dce1; border-radius: 6px;
  background: rgba(255, 255, 255, 0.94); color: var(--navy);
}
.am-zoom-btn:hover { border-color: var(--navy); }
.am-zoom-btn.am-zoom-reset { width: auto; font-size: 11px; letter-spacing: .03em; }
.am-zoom-hint {
  font-family: var(--sans); font-size: 11px; color: var(--muted);
  margin: 8px 0 0; text-align: right;
}

/* Map subtitle — states the measure and period currently shaded. Sits with
   the map (inside the sticky column) rather than with the controls, so it
   stays visible while the reader scrolls the characteristics card. */
.am-subtitle {
  font-family: var(--sans); margin: 0 0 10px; line-height: 1.35;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px;
}
.am-subtitle-metric {
  font-size: 14.5px; font-weight: 700; color: var(--navy); letter-spacing: -0.005em;
}
.am-subtitle-period {
  font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--muted);
}

/* ==========================================================================
   Annual-state county table (nt_profile_county_table_annual)
   Reuses table.county-table from the monthly profiles for the shell; these
   rules cover the columns the annual table adds.
   ========================================================================== */
.annual-table-figure { margin-top: 44px; }
table.county-table th .th-sub {
  display: block; font-size: 10px; font-weight: 500; letter-spacing: .02em;
  text-transform: none; color: var(--muted); margin-top: 2px;
}
/* Direction of change is carried by colour AND sign, never colour alone. */
table.county-table td.chg.up   { color: var(--accent-deeper); }
table.county-table td.chg.down { color: var(--navy-soft); }
table.county-table td.num-col  { font-variant-numeric: tabular-nums; }
.tbl-dagger { color: var(--muted); font-weight: 600; }
.tbl-nr {
  color: var(--muted); font-style: italic; font-size: 12px;
  text-decoration: none; border-bottom: 1px dotted var(--rule); cursor: help;
}
.tbl-note {
  font-family: var(--sans); font-size: 12px; line-height: 1.6;
  color: var(--muted); margin: 12px 0 0;
}
.tbl-note strong { color: var(--navy); font-weight: 600; }

/* Filings column carries the same inline bar the rate column does, so a
   county's volume can be compared down the column at a glance. Both are
   hidden together by the table's bars toggle. */
table.county-table td.num.filings::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: var(--bar-pct, 0%);
  height: 16px;
  transform: translateY(-50%);
  background: rgba(25, 34, 44, 0.12);
  border-radius: 2px;
  pointer-events: none;
  z-index: 0;
  transition: width 220ms ease;
}
table.county-table.bars-off td.num.filings::before { display: none; }
.tbl-nr { color: var(--muted); font-style: italic; font-size: 12px; white-space: nowrap; }


/* ==========================================================================
   Ported plates — court pipeline, disposition stack, processing time, and the
   four-P framework. These rules lived in the hand-built page's inline <style>
   block (index.v3.html) and moved here with the markup during the Quarto
   migration. Unchanged except for the --ca-grid token, which the inline block
   defined alongside them.
   ========================================================================== */

:root { --ca-grid: rgba(25, 34, 44, 0.08); }
.ca-chart-wrap { position: relative; }
.ca-axis text, .ca-tick { font-family: 'Inter', sans-serif; font-size: 12px; fill: var(--muted); }
.ca-axis .domain, .ca-axis line { stroke: #d7dce1; }
.ca-grid line { stroke: var(--ca-grid); shape-rendering: crispEdges; }
.ca-grid .domain { stroke: none; }
/* Pipeline + stacked disposition bars */
    .pipe-seg { stroke: #fff; stroke-width: 1.5; }
.pipe-cap { font-family: 'Inter', sans-serif; font-size: 12.5px; font-weight: 700; fill: var(--navy); font-variant-numeric: tabular-nums; }
.pipe-sub { font-family: 'Inter', sans-serif; font-size: 11.5px; fill: var(--muted); }
.disp-legend { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 14px; font-family: 'Inter', sans-serif; font-size: 12px; color: var(--navy); }
.disp-legend .key { display: inline-flex; align-items: center; gap: 7px; }
.disp-legend .sw { width: 14px; height: 14px; border-radius: 3px; display: inline-block; }
/* Shared tooltip */
    .ca-tip { position: absolute; pointer-events: none; background: var(--navy); color: #fff; font-family: 'Inter', sans-serif; font-size: 12px; line-height: 1.45; padding: 7px 10px; border-radius: 6px; opacity: 0; transition: opacity .12s; transform: translate(-50%, -125%); white-space: nowrap; z-index: 40; }
.ca-tip strong { font-weight: 700; }
.ca-tip .tip-accent { color: #ff8079; }
/* Four-P's framework (CA-lettered, with existence status) */
    .fourp { margin: 24px 0 8px; border: 1px solid var(--rule-fine); border-radius: 12px; overflow: hidden; }
.fourp-head { padding: 18px 22px; background: var(--tint); border-bottom: 1px solid var(--rule-fine); }
.fourp-head h4 { font-family: var(--sans); font-size: 17px; font-weight: 800; color: var(--navy); margin: 0 0 10px; letter-spacing: 0.01em; text-transform: uppercase; }
.fourp-legend { display: flex; flex-wrap: wrap; gap: 8px 18px; font-family: var(--sans); font-size: 12px; color: var(--muted); align-items: center; }
.fourp-legend .status { font-weight: 700; }
.fourp-legend .tierkey { margin-left: auto; }
.fourp-band { padding: 14px 22px; border-bottom: 1px solid var(--rule-fine); }
.fourp-band:last-of-type { border-bottom: 0; }
.fourp-band-label { display: flex; align-items: baseline; gap: 10px; font-family: var(--sans); font-weight: 800; font-size: 14px; letter-spacing: 0.04em; color: var(--navy); margin-bottom: 12px; }
.fourp-band-label .pnum { position: relative; top: 2px; display: inline-flex; width: 20px; height: 20px; border-radius: 50%; align-items: center; justify-content: center; color: #fff; font-size: 11px; font-weight: 700; }
.fourp-band-label em { font-weight: 400; font-style: italic; font-size: 12.5px; color: var(--muted); letter-spacing: 0; }
.fourp-band[data-p="1"] .pnum { background: var(--navy); }
.fourp-band[data-p="2"] .pnum { background: #3C4C5C; }
.fourp-band[data-p="3"] .pnum { background: #6E7C8A; }
.fourp-band[data-p="4"] .pnum { background: #97A4B0; }
.fourp-chips { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
/* Stacked chip rows: bands that pin their rows (3+3) use two .fourp-chips
   containers; match the grid gap between them. Tim 2026-08-21. */
.fourp-chips + .fourp-chips { margin-top: 12px; }

/* Band grounds, restored from the original four-P plate (Tim 2026-08-21).
   The values are the builder's own ramp — nt_profile_fourps_svg's
   fill = c("#19222C", "#3C4C5C", "#6E7C8A", "#B4BFC9") — which the page
   already carried on the .pnum circles but had dropped from the bands
   themselves. Dark to light reads as urgent-and-fast to structural-and-slow,
   matching the tier ordering. The slab wraps only the chip rows: in the
   plate the band label sat ABOVE the coloured rect, on the page ground, so
   .fourp-band-label stays outside .fourp-bandbox and keeps its navy. Chips
   are white on every band, so contrast holds across the whole ramp. */
.fourp-bandbox { padding: 12px; border-radius: 8px; }
.fourp-band[data-p="1"] .fourp-bandbox { background: #19222C; }
.fourp-band[data-p="2"] .fourp-bandbox { background: #3C4C5C; }
.fourp-band[data-p="3"] .fourp-bandbox { background: #6E7C8A; }
.fourp-band[data-p="4"] .fourp-bandbox { background: #B4BFC9; }
/* On a coloured ground the hairline border reads as grime; the slab supplies
   the separation instead. */
.fourp-bandbox .chip { border-color: transparent; }
.chip { border: 1px solid var(--rule-fine); border-radius: 9px; padding: 12px 14px; background: #fff; display: flex; flex-direction: column; gap: 6px; }
.chip-top { display: flex; align-items: center; gap: 8px; }
.chip .tier { font-family: var(--sans); font-size: 10.5px; font-weight: 700; padding: 1px 6px; border-radius: 4px; letter-spacing: 0.02em; }
.chip .tier.t1 { color: #fff; background: var(--accent); }
.chip .tier.t2 { color: var(--navy); background: #e3e8ee; }
.chip .tier.t3 { color: #fff; background: var(--steel); }
.chip .status { margin-left: auto; font-size: 12px; font-weight: 700; }
.chip-name { font-family: var(--sans); font-weight: 700; font-size: 14.5px; color: var(--navy); line-height: 1.2; }
.chip-stat { font-size: 12px; line-height: 1.45; color: var(--muted); }
.fourp-note { padding: 16px 22px; background: var(--tint); font-size: 13.5px; line-height: 1.62; color: var(--navy); border-top: 1px solid var(--rule-fine); }
.fourp-note strong { color: var(--accent-deep); }
.fourp-legend .tierkey { margin-left: 0; }

/* Four-P status markers: statewide / local-or-partial / none. Missed by the
   initial CSS port because the selector carries no .chip or .fourp prefix. */
.status.s-yes { color: #2a7d4f; }
.status.s-local { color: #B7791F; }
.status.s-none { color: var(--accent-deep); }
/* Washington-specific fourth state. CA's grid needed three (statewide, local,
   none), but Washington's story turns on two Tier-1 levers it actually ran
   and then let expire, which is neither "has it" nor "never had it". Slate
   grey with a strike-through mark reads as switched off rather than absent.
   Tim 2026-08-20. */
.status.s-lapsed { color: #6E7C8A; }
.chip.is-lapsed { background: repeating-linear-gradient(135deg, transparent, transparent 7px, rgba(110,124,138,.055) 7px, rgba(110,124,138,.055) 14px); }
.chip.is-paired { border-color: var(--accent-deep); box-shadow: 0 0 0 1px var(--accent-deep) inset; }
.chip .pair-tag { display: inline-block; margin-top: 8px; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--accent-deep); }
.annual-map .ec-head { padding-bottom: 4px; }
.annual-map .map-text { min-width: 0; }

/* Action section lead. The heading is short and the three paragraphs beneath
   it are long, so the usual two-column split left a tall empty well under the
   title. Floating the heading lets the prose sit beside it and then wrap on
   underneath, filling that space the way a magazine deck does. The float is
   dropped on narrow screens, where the heading simply stacks above the text. */
.action-lead::after { content: ""; display: block; clear: both; }
.action-lead .section-title {
  float: left; width: 42%; margin: 0 44px 18px 0;
}
.action-lead .body p { max-width: none; }
@media (max-width: 900px) {
  .action-lead .section-title { float: none; width: auto; margin: 0 0 20px; }
}


/* ==========================================================================
   Credit cards and footer marks — ported from the hand-built page's inline
   <style> block. Missed in the first CSS port because the extraction filtered
   on a hand-written list of selectors and "credit" was not on it; found by
   diffing the classes the rendered page uses against the classes this sheet
   defines. The featured card (SAJE) carries the tinted, red-bordered
   treatment; the rest sit in a four-across grid.
   ========================================================================== */
/* Policy ledger — the compact form of the policy section: one hairline row
   per instrument, an effective-date rail on the left, the mechanism and the
   effect-on-the-counts clause on the right, one sources line under the
   ledger. Replaced Washington's credit-card grid (2026-08-20): five long
   cards took a screen and a half, five ledger rows take half that. The
   .credit-* card styles above are untouched (California's credits use them).
   Rows stack on narrow screens. */
.policy-ledger { margin-top: 30px; border-top: 1px solid var(--rule); }
.pl-row {
  display: grid; grid-template-columns: 210px 1fr; gap: 30px;
  padding: 18px 0 14px; border-bottom: 1px solid var(--rule-fine);
}
.policy-ledger .pl-row:last-child { border-bottom: 1px solid var(--rule); }
.pl-when { display: flex; flex-direction: column; gap: 3px; }
.pl-date {
  font-family: 'Inter', sans-serif; font-weight: 700; font-size: 15px;
  color: var(--navy); letter-spacing: 0.01em;
}
.pl-inst, .pl-scope {
  font-family: 'Inter', sans-serif; font-size: 12px; line-height: 1.45;
  color: var(--muted);
}
/* Instrument-line links: quiet in the rail (muted, hairline underline),
   waking to the text red on hover like every other link on the page. */
.pl-inst a { color: inherit; border-bottom-color: var(--rule); }
.pl-inst a:hover, .pl-inst a:focus { color: var(--accent-deep); border-bottom-color: var(--accent-deep); }
.pl-what h4 {
  margin: 0 0 6px; font-family: 'Inter', sans-serif;
  font-size: 16px; font-weight: 600; line-height: 1.35; color: var(--navy);
}
.pl-what p { margin: 0 0 8px; font-size: 14px; line-height: 1.6; color: var(--navy); }
.pl-what p:last-child { margin-bottom: 0; }
.pl-effect { font-size: 13px; color: var(--muted); }
.pl-effect strong { color: var(--accent-deep); font-weight: 600; }
.pl-sources {
  margin: 14px 0 0; font-family: 'Inter', sans-serif;
  font-size: 11.5px; line-height: 1.6; color: var(--muted);
}
@media (max-width: 700px) {
  .pl-row { grid-template-columns: 1fr; gap: 8px; padding: 16px 0 12px; }
}

/* Recent-work credit cards */
    .credit-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: 18px; margin-top: 26px; }
.credit-card { border: 1px solid var(--rule-fine, #e3e8ee); border-radius: 10px; padding: 20px 22px; background: #fff; }
.credit-card.feature { border: 1.5px solid var(--accent); background: #fff6f5; grid-column: 1 / -1; }
.credit-card .credit-org { font-family: 'Inter', sans-serif; font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--accent-deep); margin: 0 0 6px; }
.credit-card h4 { font-family: 'Inter', sans-serif; font-size: 17px; line-height: 1.3; margin: 0 0 8px; color: var(--navy); }
.credit-card.feature h4 { font-size: 21px; }
.credit-card p { font-size: 14px; line-height: 1.62; margin: 0 0 10px; color: var(--navy); }
.credit-card .credit-meta { font-size: 12px; color: var(--muted); }
.credit-card blockquote { margin: 0 0 12px; padding: 0 0 0 14px; border-left: 3px solid var(--accent); font-size: 15px; line-height: 1.55; font-style: italic; color: var(--navy); }
.footer-logos { display: flex; align-items: center; gap: 18px; margin-bottom: 16px; flex-wrap: wrap; }
.footer-logos img { max-height: 38px; width: auto; }
.footer-logos .berkeley-mark { max-height: 26px; }
.footer-logo-divider { width: 1px; height: 28px; background: rgba(255,255,255,0.3); display: inline-block; }

/* Methodology body in two columns. The section is a 200px label beside a wide
   content column, but each paragraph was capped at 64ch, so the text ran in a
   narrow ribbon with half the width empty. Flowing it into two columns fills
   the measure and keeps the line length readable, so the cap comes off. The
   tinted gap note and the closing structure note are kept whole rather than
   split across the column break. */
.methodology > div:last-of-type {
  column-count: 2;
  column-gap: 44px;
}
.methodology p {
  max-width: none;
  break-inside: avoid-column;
}
@media (max-width: 900px) {
  .methodology > div:last-of-type { column-count: 1; }
}

/* Figure 6 (processing time) — three rules the Quarto port dropped from the
   hand-built page (index.v3.html). Without them the 90%-standard reference
   line draws solid (reading as a data series) and its label and the
   series-end labels inherit 16px. The CSS stroke/fill deliberately override
   the JS presentation attributes, as they did on the v3 page. */
.ca-ref { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 2 4; }
.ca-ref-label { font-size: 11px; fill: var(--muted); font-style: italic; }
.ct-end { font-size: 12px; font-weight: 700; }

/* ==========================================================================
   News: recent movements in eviction policy (nt_profile_news)

   A dated list, one row per instrument. The chip encodes whether the
   instrument is IN FORCE, never whether it is good news: a preemption statute
   and a right-to-counsel statute are both "enacted", and colouring them by
   valence would editorialise a factual section.
     in-force  solid navy
     lapsed    red outline, for a protection that has been repealed, struck
               down, or has expired
     not-law   grey outline, for anything pending, proposed, or failed
   ========================================================================== */
.news-list { list-style: none; margin: 0; padding: 0; }
.news-item {
  display: grid;
  grid-template-columns: 128px 1fr;
  gap: 0 22px;
  padding: 18px 2px;
  border-bottom: 1px solid var(--rule-fine);
}
.news-item:last-child { border-bottom: 0; }
.news-meta { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }
.news-date {
  font-family: 'Inter', sans-serif; font-size: 12.5px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.news-chip {
  font-family: 'Inter', sans-serif; font-size: 11px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 3px; white-space: nowrap;
}
.news-chip-in-force { background: var(--navy, #19222C); color: #fff; }
.news-chip-lapsed {
  background: transparent; color: var(--accent-deeper, #CC2118);
  box-shadow: inset 0 0 0 1px var(--accent-deeper, #CC2118);
}
.news-chip-not-law {
  background: transparent; color: var(--muted, #586573);
  box-shadow: inset 0 0 0 1px var(--rule-fine, #D7DCE1);
}
.news-title {
  font-family: 'Inter', sans-serif; font-size: 16px; line-height: 1.35;
  font-weight: 600; color: var(--navy); margin: 0 0 6px;
}
.news-summary { font-size: 15px; line-height: 1.55; color: var(--navy); margin: 0 0 6px; max-width: 68ch; }
.news-effect {
  font-size: 14px; line-height: 1.55; color: var(--navy); margin: 0 0 6px;
  max-width: 68ch; padding-left: 11px;
  border-left: 2px solid var(--accent);
}
.news-effect strong { color: var(--accent-deep); }
.news-src { font-size: 13px; line-height: 1.4; margin: 0; }
.news-src a { color: var(--muted); text-decoration: none; border-bottom: 1px solid var(--rule-fine); }
.news-src a:hover { color: var(--accent-deep); border-bottom-color: currentColor; }
.news-empty, .news-more {
  font-size: 14px; line-height: 1.6; color: var(--muted);
  margin: 14px 0 0; font-style: italic;
}

/* One column on a phone: a 128px meta rail leaves the title nowhere to go. */
@media (max-width: 640px) {
  .news-item { grid-template-columns: 1fr; gap: 8px; }
  .news-meta { flex-direction: row; align-items: center; gap: 10px; }
}

/* ═══ SCATTER PLATE ═══════════════════════════════════════════════════════
   Two county-level rates plotted against each other (report Figure 6:
   eviction filing rate against homelessness rate). Emitted by
   nt_profile_scatter_svg() in the neighborhood package.

   Static by design — no hover layer — so the grid classes are scoped here
   rather than borrowed from .chart-interactive .hover-grid. Text sizes divide
   by --sx like every other chart, which the template's watcher sets on any
   svg inside a .figure, so the labels hold their pixel size on a phone.

   Point fill is the steel swatch at 62% rather than the brand red: on an
   uncorrelated cloud of 35 counties, red on everything reads as emphasis
   where there is nothing to emphasise. Red is reserved for the named
   accent counties. */
.chart-scatter .grid-line {
  stroke: #19222C; stroke-width: 0.5;
  stroke-dasharray: 2 3; opacity: 0.22;
}
.chart-scatter .grid-label {
  font-family: 'Inter', sans-serif; font-size: calc(11px / var(--sx, 1));
  fill: var(--muted); letter-spacing: 0.02em;
}
.chart-scatter .sc-dot {
  fill: var(--steel); fill-opacity: 0.62;
  stroke: #fff; stroke-width: 1;
}
.chart-scatter .sc-dot-accent { fill: var(--accent-deep); fill-opacity: 0.85; }
.chart-scatter .sc-label {
  font-family: 'Inter', sans-serif; font-size: calc(11.5px / var(--sx, 1));
  font-weight: 500; fill: var(--navy);
}
.chart-scatter .sc-label-accent { fill: var(--accent-deep); font-weight: 600; }
.chart-scatter .sc-axis-title {
  font-family: 'Inter', sans-serif; font-size: calc(12px / var(--sx, 1));
  font-weight: 500; fill: var(--muted); letter-spacing: 0.02em;
}
