.dc-page {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 24px 80px;
  font-family: var(--font-ui);
  color: var(--app-text);
}

.dc-page h1,
.dc-page h2 {
  text-wrap: balance;
}

.dc-page h1 {
  font-size: 2rem;
  line-height: 1.2;
  margin: 24px 0 12px;
  letter-spacing: -0.02em;
}

.dc-page h2 {
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 48px 0 12px;
  letter-spacing: -0.01em;
}

.dc-page p,
.dc-page ul:not(.dc-downloads) {
  max-width: 72ch;
  text-wrap: pretty;
}

.dc-lede {
  font-size: 1.125rem;
  line-height: 1.55;
  max-width: 68ch;
  color: var(--app-text);
}

.dc-callout {
  background: var(--app-accent-soft);
  padding: 16px 18px;
  margin: 28px 0;
  max-width: 72ch;
}

.dc-callout p {
  margin: 0;
}

.dc-table-wrap {
  overflow-x: auto;
  margin: 16px 0 8px;
}

.dc-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.dc-table caption {
  caption-side: top;
  text-align: left;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--app-text);
  margin: 0 0 10px;
}

.dc-table th,
.dc-table td {
  text-align: left;
  padding: 10px 16px 10px 0;
  border-bottom: 1px solid var(--app-border);
  vertical-align: top;
}

.dc-table th {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--app-text-muted);
}

.dc-table tbody th {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--app-text);
}

.dc-table td:last-child,
.dc-table th:last-child {
  padding-right: 0;
}

.dc-table .dc-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.dc-table .dc-num:has(.dc-period) {
  white-space: normal;
}

.dc-family-table td:last-child,
.dc-family-table th[scope="col"]:last-child {
  min-width: 16ch;
}

.dc-period {
  display: block;
  margin-top: 4px;
  font-size: 0.85rem;
  font-weight: 400;
  letter-spacing: 0;
  white-space: normal;
  color: var(--app-text-muted);
}

.dc-page code {
  font-family: ui-monospace, "SF Mono", Consolas, Menlo, Monaco, "Liberation Mono", "Courier New", monospace;
  font-size: 0.85em;
}

.dc-table tbody tr:hover {
  background: var(--app-surface-1);
}

.dc-downloads {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin: 12px 0 32px;
  padding: 0;
  list-style: none;
}

.dc-page a {
  color: var(--app-accent);
}

.dc-page a:focus-visible {
  outline: 2px solid var(--app-focus-outline, var(--app-accent));
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .dc-page * {
    transition: none !important;
  }
}

/* ------------------------------------------------------------------ choropleth

   Every fill is a class, never a `style=` attribute: the site CSP is
   `style-src 'self' https://fonts.googleapis.com` with no 'unsafe-inline', so an
   inline style on an SVG path would simply not apply and the map would render
   as fifty black silhouettes.

   The ramp is one hue, light→dark, five quantile classes. Single-hue sequential
   is colour-blind safe by construction — protan, deutan, and tritan readers all
   retain the lightness ordering that carries the magnitude. Steps are taken from
   the documented blue ramp and validated per mode (monotone lightness, adjacent
   ΔL >= 0.06, and the surface-nearest step clearing 2:1 against the panel):
     light  #86b6ef #5598e7 #2a78d6 #1c5cab #0d366b  on #F8FAFC
     dark   #1c5cab #2a78d6 #5598e7 #86b6ef #b7d3f6  on #222933
   Dark is re-stepped, not flipped: the low class stays nearest the surface in
   both modes, so "darker means more" inverts to "brighter means more" and the
   reading of the map does not.

   Two values are deliberately OFF the ramp, because letting them take the
   lightest step would say "a little money" where the truth is "none" and
   "no rows at all":
     .dc-map-zero    obligated is exactly $0.00, with edges behind it
     .dc-map-absent  the layer has no edge in this state
*/
.dc-map {
  margin: 48px 0 0;
}

.dc-map-warning {
  border-left: 4px solid var(--app-accent);
  background: var(--app-accent-soft);
  padding: 14px 18px;
  margin: 16px 0 20px;
  max-width: 72ch;
}

.dc-map-warning p {
  margin: 0;
}

.dc-map-intro {
  color: var(--app-text-muted);
}

.dc-map-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.dc-map-panel {
  margin: 28px 0 0;
  padding: 18px;
  background: var(--app-surface-1);
  border: 1px solid var(--app-border);
}

.dc-map-caption {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin-bottom: 14px;
}

.dc-map-layer {
  font-size: 1.1rem;
  font-weight: 650;
  color: var(--app-text);
}

.dc-map-total {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--app-text);
}

.dc-map-population {
  flex-basis: 100%;
  font-size: 0.9rem;
  color: var(--app-text-muted);
}

/* The outside bucket is a COLUMN BESIDE THE MAP, not a footnote under it.
   L3 loses 6.44% of its total to places no state shape can hold; a reader who
   scrolls past the picture has to have already seen where that money went. */
.dc-map-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(250px, 310px);
  gap: 20px;
  align-items: start;
}

.dc-map-plot {
  min-width: 0;
  /* Safe here: the column is `minmax(0, 1fr)`, so this element's inline size
     already does not depend on its contents. See the @container rule below. */
  container-type: inline-size;
  container-name: dc-map-plot;
}

.dc-map-svg {
  display: block;
  width: 100%;
  height: auto;
}

.dc-map-states use {
  stroke: var(--app-surface-1);
  stroke-width: 0.7;
  stroke-linejoin: round;
}

.dc-map-c1 { fill: #86b6ef; }
.dc-map-c2 { fill: #5598e7; }
.dc-map-c3 { fill: #2a78d6; }
.dc-map-c4 { fill: #1c5cab; }
.dc-map-c5 { fill: #0d366b; }

.dc-map-zero {
  fill: var(--app-border-strong);
}

/* Not a fill at all: a hairline outline on the panel, so "no edges in this
   layer" cannot be mistaken for the bottom of the ramp. */
.dc-map-absent {
  fill: var(--app-surface-3);
}

.dc-map-states .dc-map-absent {
  stroke: var(--app-border-strong);
  stroke-width: 1.1;
  stroke-dasharray: 3 2.5;
}

.dc-map-legend-wrap {
  margin-top: 10px;
}

.dc-map-legend-title {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--app-text-muted);
  margin: 0 0 8px;
}

.dc-map-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.dc-map-key {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  color: var(--app-text);
}

.dc-map-swatch {
  width: 16px;
  height: 12px;
  flex: none;
  border: 1px solid var(--app-border);
}

.dc-map-swatch.dc-map-absent {
  background: var(--app-surface-3);
  border: 1px dashed var(--app-border-strong);
}

.dc-map-swatch.dc-map-zero {
  background: var(--app-border-strong);
}

.dc-map-swatch.dc-map-c1 { background: #86b6ef; }
.dc-map-swatch.dc-map-c2 { background: #5598e7; }
.dc-map-swatch.dc-map-c3 { background: #2a78d6; }
.dc-map-swatch.dc-map-c4 { background: #1c5cab; }
.dc-map-swatch.dc-map-c5 { background: #0d366b; }

.dc-map-key-count {
  color: var(--app-text-muted);
}

.dc-map-legend-note {
  font-size: 0.8rem;
  color: var(--app-text-muted);
  margin: 8px 0 0;
  max-width: 68ch;
}

.dc-outside {
  border: 1px solid var(--app-border-strong);
  background: var(--app-bg-subtle);
  padding: 14px;
  min-width: 0;
}

.dc-outside-heading {
  font-size: 0.95rem;
  font-weight: 650;
  margin: 0 0 6px;
  color: var(--app-text);
}

.dc-outside-total {
  margin: 0 0 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.dc-outside-amount {
  font-size: 1.15rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--app-text);
}

.dc-outside-share {
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  color: var(--app-text-muted);
}

.dc-outside-note {
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--app-text-muted);
  margin: 0 0 12px;
}

.dc-outside-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Shape · place · money on one row. The rail sits beside a 340px map and has to
   carry up to eight entries without either cramping or leaving a hole under the
   map, so nothing here is allowed a second line unless it earns one. */
.dc-outside-item {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  gap: 2px 10px;
  align-items: center;
  padding: 8px 0;
  border-top: 1px solid var(--app-border);
}

.dc-outside-list > .dc-outside-item:first-child {
  border-top: 0;
}

.dc-outside-shape {
  width: 26px;
  height: 26px;
  fill: var(--app-accent);
}

/* A jurisdiction with no U.S. boundary gets a marker that is visibly NOT a
   shape, so the rail never implies a place that does not exist. */
.dc-outside-noshape {
  width: 26px;
  height: 26px;
  border: 1px dashed var(--app-border-strong);
  background: repeating-linear-gradient(
    45deg,
    transparent,
    transparent 4px,
    var(--app-border) 4px,
    var(--app-border) 5px
  );
}

.dc-outside-name {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--app-text);
}

.dc-outside-code {
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: var(--app-text-muted);
  margin-left: 5px;
}

.dc-outside-money {
  font-size: 0.86rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
  color: var(--app-text);
}

/* Only a $0.00 entry gets a second line, because only a $0.00 entry looks
   like a bug without one. */
.dc-outside-note-row {
  grid-column: 2 / -1;
  font-size: 0.73rem;
  line-height: 1.35;
  color: var(--app-text-muted);
}

.dc-map-conservation {
  margin: 16px 0 0;
  padding: 12px 14px;
  background: var(--app-surface-2);
  border: 1px solid var(--app-border);
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: none;
}

.dc-map-sum {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--app-text);
  overflow-wrap: anywhere;
}

.dc-map-op {
  color: var(--app-text-muted);
  padding: 0 2px;
}

.dc-map-conservation-note {
  font-size: 0.82rem;
  color: var(--app-text-muted);
}

.dc-map-details {
  margin-top: 14px;
}

.dc-map-details summary {
  cursor: pointer;
  font-size: 0.88rem;
  color: var(--app-accent-text, var(--app-accent));
}

.dc-map-details summary:focus-visible {
  outline: 2px solid var(--app-focus-outline, var(--app-accent));
  outline-offset: 2px;
}

.dc-map-credit {
  font-size: 0.8rem;
  color: var(--app-text-muted);
  margin: 18px 0 0;
}

@media (max-width: 860px) {
  .dc-map-body {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (prefers-color-scheme: dark) {
  /* Re-stepped for the dark panel, not flipped. See the block comment above. */
  .dc-map-c1, .dc-map-swatch.dc-map-c1 { fill: #1c5cab; background: #1c5cab; }
  .dc-map-c2, .dc-map-swatch.dc-map-c2 { fill: #2a78d6; background: #2a78d6; }
  .dc-map-c3, .dc-map-swatch.dc-map-c3 { fill: #5598e7; background: #5598e7; }
  .dc-map-c4, .dc-map-swatch.dc-map-c4 { fill: #86b6ef; background: #86b6ef; }
  .dc-map-c5, .dc-map-swatch.dc-map-c5 { fill: #b7d3f6; background: #b7d3f6; }

  .dc-outside-shape {
    fill: #86b6ef;
  }
}

/* The one thing a five-class fill genuinely cannot say. Virginia is 65.7% of
   L1 and shares its class with a state 100× smaller; the sentence and the
   outline carry what colour cannot. */
.dc-map-dominance {
  margin: 0 0 14px;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--app-text-muted);
  max-width: 76ch;
}

.dc-map-dominance strong {
  color: var(--app-text);
  font-variant-numeric: tabular-nums;
}

.dc-map-top-halo {
  fill: none;
  stroke: var(--app-surface-1);
  stroke-width: 4.5;
  stroke-linejoin: round;
}

.dc-map-top-ring {
  fill: none;
  stroke: var(--app-text);
  stroke-width: 1.8;
  stroke-linejoin: round;
}

/* Legible over the darkest class in light mode and the brightest in dark:
   text ink with a surface-coloured halo, painted stroke-first. */
.dc-map-top-label {
  fill: var(--app-text);
  stroke: var(--app-surface-1);
  stroke-width: 3.5;
  paint-order: stroke;
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/*
 * The letter goes away before it stops being a letter.
 *
 * `font-size: 17px` is in the 960-unit viewBox, so it renders at 17 × (plot
 * width / 960). Below about 520px of plot that is under 9px — at 390px viewport
 * the plot is 304px and the letter is 5.4px with a 1.1px halo eating into it,
 * which is not a label, it is a smudge inside the ring. It makes the ring
 * harder to read rather than easier, and everything it says is already said
 * twice: the sentence above the map names the state in bold, and the legend
 * carries a "Largest state in this layer — outlined" row. The ring survives at
 * every width; the letter does not need to.
 *
 * A container query, not a viewport one, because the plot is narrow in two
 * separate bands and a viewport rule would have to guess at both: 304px on a
 * phone, and 445px in the two-column layout just above the 860px breakpoint,
 * where the map is NARROWER than it is at 859px. The only question worth
 * asking is how wide the plot actually is. A browser without `@container`
 * ignores this and keeps the letter, which is the pre-existing behaviour.
 */
@container dc-map-plot (max-width: 520px) {
  .dc-map-top-label {
    display: none;
  }
}

.dc-map-swatch--outline {
  background: transparent;
  border: 2px solid var(--app-text);
}
