/* ============================================================================
   EPIEME — STATES OVERVIEW (Alden)

   One page, no boxes: a left-aligned serif title with a sky highlighter
   stroke, a sentence with the headline numbers, a tile map shaded by bills
   only, and a flat table of every state split by fog hairlines. Nothing
   wraps the map or the table; space and small headings separate them.

   The map uses one hue: parchment for zero, then four steps of sky. Every
   tile prints its code (and its count where it fits), and the table below
   repeats every number, so colour never carries meaning alone.

   states-overview.js renders the tiles, legend, readout and table rows.
   ============================================================================ */

:root {
  --so-canvas: #ffffff;
  --so-parchment: #f3f1eb;
  --so-ink: #28262a;
  --so-graphite: #4a4a4c;
  --so-fog: #dddcdd;
  --so-sky: #97cde5;
  --so-sans: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --so-serif: "Source Serif 4", ui-serif, Georgia, Cambria, "Times New Roman", serif;
  --so-gutter: clamp(16px, 4vw, 40px);
  /* Field and control boundaries need 3:1 against the canvas. */
  --so-control-line: color-mix(in srgb, var(--so-ink) 55%, var(--so-canvas));
  --so-highlight: color-mix(in srgb, var(--so-sky) 60%, transparent);

  /* Bills per state, one hue (sky). Labels: ink on 0-3 (graphite on 0),
     canvas on 4; every pair clears 4.5:1 in both themes. */
  --so-map-0: var(--so-parchment);
  --so-map-1: #bfe3f4;
  --so-map-2: #97cde5;
  --so-map-3: #6fb2cf;
  --so-map-4: #1b637e;
  --so-map-on-0: var(--so-graphite);
  --so-map-on: var(--so-ink);
  --so-map-on-4: #ffffff;
}

[data-theme="dark"] {
  color-scheme: dark;
  --so-canvas: #1a191b;
  --so-parchment: #232124;
  --so-ink: #f3f1eb;
  --so-graphite: #b5b2ad;
  --so-fog: #353236;
  --so-highlight: color-mix(in srgb, var(--so-sky) 38%, transparent);

  /* Zero tiles get a touch of fog so the map's outline still reads. */
  --so-map-0: #2a282b;
  --so-map-1: #1d3a45;
  --so-map-2: #245466;
  --so-map-3: #2c6c84;
  --so-map-4: #97cde5;
  --so-map-on-4: #1a191b;
}

/* ------------------------------------------------------------------ base -- */
body.so-page {
  margin: 0;
  min-height: 100vh;
  background: var(--so-canvas);
  color: var(--so-ink);
  font-family: var(--so-sans);
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: -0.32px;
  -webkit-font-smoothing: antialiased;
}

.so-main,
.so-main *,
.so-main *::before,
.so-main *::after {
  box-sizing: border-box;
}

:where(.so-main) :where(h1, h2, p, ol, dl, dd, figure) {
  margin: 0;
  padding: 0;
}

.so-main :focus-visible {
  outline: 2px solid var(--so-ink);
  outline-offset: 2px;
}

.so-main svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.so-main a {
  color: var(--so-ink);
  text-decoration-line: underline;
  text-decoration-color: var(--so-control-line);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.so-main a:hover {
  text-decoration-color: var(--so-ink);
}

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

.so-main {
  width: min(100%, 880px + 2 * var(--so-gutter));
  margin: 0 auto;
  padding: 56px var(--so-gutter) 80px;
}

/* ---------------------------------------------------------------- header -- */
.so-title {
  color: var(--so-ink);
  font-family: var(--so-serif);
  font-size: clamp(40px, 5vw, 48px);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

/* Sky as a highlighter stroke under ink: sky as text is about 1.7:1. */
.so-title-accent {
  color: inherit;
  background: linear-gradient(transparent 60%, var(--so-highlight) 60%, var(--so-highlight) 90%, transparent 90%);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

.so-summary {
  max-width: 62ch;
  margin-top: 16px;
  color: var(--so-graphite);
  font-size: 18px;
  line-height: 1.5;
  letter-spacing: -0.36px;
  text-wrap: pretty;
}

.so-summary strong {
  color: var(--so-ink);
  font-weight: 600;
}

.so-activity {
  max-width: 70ch;
  margin-top: 10px;
  color: var(--so-graphite);
  font-size: 14px;
  line-height: 1.5;
  letter-spacing: -0.28px;
}

.so-summary[hidden],
.so-activity[hidden] {
  display: none;
}

/* -------------------------------------------------------------- sections -- */
.so-section {
  margin-top: 56px;
}

.so-section[hidden] {
  display: none;
}

.so-section-title {
  color: var(--so-ink);
  font-size: 18px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.36px;
}

.so-asof {
  margin-left: 8px;
  color: var(--so-graphite);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: -0.28px;
}

/* ---------------------------------------------------------------- legend -- */
.so-legend {
  display: flex;
  align-items: flex-start;
  margin: 12px 0 16px;
  list-style: none;
}

.so-legend li {
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--so-graphite);
  font-size: 12px;
  line-height: 1.2;
  letter-spacing: 0.24px;
  font-variant-numeric: tabular-nums;
}

.so-legend li.is-zero {
  margin-right: 12px;
}

.so-swatch {
  display: block;
  width: 56px;
  height: 8px;
  background: var(--so-map-0);
}

.so-legend li.is-zero .so-swatch,
.so-legend li:nth-child(2) .so-swatch {
  border-radius: 4px 0 0 4px;
}

.so-legend li.is-zero .so-swatch {
  border-radius: 4px;
}

.so-legend li:last-child .so-swatch {
  border-radius: 0 4px 4px 0;
}

.so-swatch[data-class="1"] { background: var(--so-map-1); }
.so-swatch[data-class="2"] { background: var(--so-map-2); }
.so-swatch[data-class="3"] { background: var(--so-map-3); }
.so-swatch[data-class="4"] { background: var(--so-map-4); }

/* ------------------------------------------------------------------- map -- */
.so-map {
  container: so-map / inline-size;
  max-width: 640px;
}

/* The tiles and the readout share one 12 x 8 grid; the readout sits in the
   empty band at the top, so it never covers a state. */
.so-map-grid,
.us-map {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(8, auto);
  gap: 4px;
}

/* The tiles inherit the outer grid's tracks, so when the readout's text
   wraps and its two rows grow, the tile rows grow with them instead of
   sliding under it. */
.us-map {
  grid-column: 1 / -1;
  grid-row: 1 / -1;
  grid-template-columns: subgrid;
  grid-template-rows: subgrid;
}

/* Before the data arrives: a quiet block the size of the map. */
.us-map:empty {
  display: block;
  aspect-ratio: 12 / 8;
  border-radius: 8px;
  background: var(--so-parchment);
  animation: so-pulse 1.6s ease-in-out infinite;
}

@keyframes so-pulse {
  50% { opacity: 0.55; }
}

.so-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  aspect-ratio: 1;
  min-width: 0;
  border-radius: 4px;
  background: var(--so-map-0);
  color: var(--so-map-on-0);
  line-height: 1;
  text-decoration: none;
}

.so-main a.so-tile {
  color: var(--so-map-on-0);
  text-decoration: none;
}

.so-tile[data-class="1"] { background: var(--so-map-1); }
.so-tile[data-class="2"] { background: var(--so-map-2); }
.so-tile[data-class="3"] { background: var(--so-map-3); }
.so-tile[data-class="4"] { background: var(--so-map-4); }

.so-main a.so-tile[data-class="1"],
.so-main a.so-tile[data-class="2"],
.so-main a.so-tile[data-class="3"] {
  color: var(--so-map-on);
}

.so-main a.so-tile[data-class="4"] {
  color: var(--so-map-on-4);
}

/* Hover is a hairline; keyboard focus is the full 2px ring, so the two
   never look alike when they're on different tiles. */
.so-tile:hover {
  z-index: 1;
  outline: 1px solid var(--so-ink);
  outline-offset: 1px;
}

.so-tile:focus-visible {
  z-index: 1;
  outline: 2px solid var(--so-ink);
  outline-offset: 1px;
}

.so-tile-abbr {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.so-tile-count {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.so-readout {
  grid-column: 2 / span 9;
  grid-row: 1 / span 2;
  align-self: center;
  min-width: 0;
  padding: 0 12px;
  pointer-events: none;
}

.so-readout-title {
  color: var(--so-ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.3px;
  text-wrap: balance;
}

.so-readout-meta {
  margin-top: 2px;
  color: var(--so-graphite);
  font-size: 13px;
  line-height: 1.4;
  letter-spacing: -0.13px;
}

.so-figcaption {
  max-width: 64ch;
  margin-top: 16px;
  color: var(--so-graphite);
  font-size: 13px;
  line-height: 1.5;
  letter-spacing: -0.13px;
}

@container so-map (max-width: 559px) {
  .so-tile-count {
    display: none;
  }

  .so-tile-abbr {
    font-size: 11px;
  }

  .so-readout {
    padding: 0 4px;
  }

  .so-readout-title {
    font-size: 13px;
  }

  .so-readout-meta {
    font-size: 12px;
  }

  .so-readout-meta.is-extra {
    display: none;
  }
}

@container so-map (max-width: 479px) {
  .so-map-grid,
  .us-map {
    gap: 2px;
  }

  .so-tile {
    border-radius: 3px;
  }
}

@container so-map (max-width: 339px) {
  .so-tile-abbr {
    font-size: 10px;
  }

  .so-readout-meta {
    display: none;
  }
}

/* --------------------------------------------------------------- toolbar -- */
.so-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin: 12px 0 8px;
}

.so-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 320px;
  min-width: 0;
}

.so-search svg {
  position: absolute;
  left: 14px;
  color: var(--so-graphite);
  pointer-events: none;
}

.so-input {
  width: 100%;
  min-height: 40px;
  border: 1px solid var(--so-control-line);
  border-radius: 100px;
  background: var(--so-canvas);
  color: var(--so-ink);
  padding: 0 16px 0 40px;
  font: inherit;
  font-size: 14px;
  letter-spacing: -0.28px;
}

.so-input::placeholder {
  color: var(--so-graphite);
}

.so-input:hover {
  border-color: var(--so-ink);
}

.so-input:focus {
  border-color: var(--so-ink);
  outline: 2px solid var(--so-ink);
  outline-offset: 1px;
}

.so-count {
  margin-left: auto;
  color: var(--so-graphite);
  font-size: 13px;
  letter-spacing: -0.13px;
}

/* ----------------------------------------------------------------- table -- */
#list {
  container: so-list / inline-size;
}

.so-table {
  width: calc(100% + 24px);
  margin-inline: -12px;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  font-size: 15px;
  letter-spacing: -0.3px;
}

.so-table[hidden] {
  display: none;
}

.so-table col.col-num { width: 80px; }
.so-table col.col-pet { width: 128px; }
.so-table col.col-date { width: 136px; }

.so-table thead th {
  height: 40px;
  border-bottom: 1px solid var(--so-fog);
  background: var(--so-canvas);
  padding: 0 12px;
  text-align: left;
  vertical-align: middle;
}

/* Only signed in: the app shell's top edge is known (12px glass inset, or
   the 56px bar under 960px). The public navbar's height varies. The scroll
   padding keeps a focused row clear of the sticky header. */
html.epieme-authenticated[data-app-shell] {
  scroll-padding-top: 64px;
}

html.epieme-authenticated[data-app-shell] .so-table thead th {
  position: sticky;
  top: 12px;
  z-index: 2;
}

.so-table thead th.num {
  text-align: right;
}

.so-table thead button {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 36px;
  border: 0;
  background: none;
  color: var(--so-graphite);
  padding: 0;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.24px;
  cursor: pointer;
}

/* Numbers right-align, so their sort mark sits before the label and the
   label lines up with the figures. */
.so-table thead th.num button {
  flex-direction: row-reverse;
  justify-content: flex-start;
  width: 100%;
}

.so-table thead button:hover,
.so-table th[aria-sort] button {
  color: var(--so-ink);
}

.so-sort-mark {
  width: 0;
  height: 0;
  border-right: 4px solid transparent;
  border-left: 4px solid transparent;
}

.so-table th[aria-sort="ascending"] .so-sort-mark {
  border-bottom: 5px solid currentColor;
}

.so-table th[aria-sort="descending"] .so-sort-mark {
  border-top: 5px solid currentColor;
}

.so-table tbody tr {
  position: relative;
}

.so-table tbody th,
.so-table tbody td {
  border-bottom: 1px solid var(--so-fog);
  padding: 13px 12px;
  color: var(--so-ink);
  font-weight: 400;
  text-align: left;
  vertical-align: top;
}

.so-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.so-table tbody td.col-date {
  color: var(--so-graphite);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The whole row opens the state; the link's box is stretched over it. */
.so-table tbody a {
  color: var(--so-ink);
  font-weight: 500;
  text-decoration: none;
}

.so-table tbody a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.so-table tbody a:focus-visible {
  outline: none;
}

.so-table tbody a:focus-visible::after {
  outline: 2px solid var(--so-ink);
  outline-offset: -2px;
  border-radius: 4px;
}

.so-table tbody tr:not(.so-empty-row):hover {
  background: var(--so-parchment);
}

.so-row-abbr {
  margin-left: 8px;
  color: var(--so-graphite);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.24px;
}

.so-row-session,
.so-row-sub,
.so-cell-note {
  display: block;
  margin-top: 2px;
  color: var(--so-graphite);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.13px;
}

.so-row-sub {
  display: none;
}

.so-cell-note {
  font-size: 12px;
  letter-spacing: 0;
}

.so-table .is-muted {
  color: var(--so-graphite);
  font-size: 13px;
  letter-spacing: -0.13px;
}

.so-table tr.is-zero td.num:first-of-type {
  color: var(--so-graphite);
}

.so-empty {
  padding: 32px 12px;
  color: var(--so-graphite);
}

.so-clear {
  min-height: 32px;
  margin-left: 8px;
  border: 1px solid var(--so-control-line);
  border-radius: 100px;
  background: transparent;
  color: var(--so-ink);
  padding: 0 14px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
}

.so-clear:hover {
  border-color: var(--so-ink);
}

@container so-list (max-width: 599px) {
  .so-table col.col-passed,
  .so-table col.col-date {
    width: 0;
  }

  .so-table .col-passed,
  .so-table .col-date,
  .so-row-abbr {
    display: none;
  }

  .so-table col.col-num { width: 56px; }
  .so-table col.col-pet { width: 104px; }

  .so-row-sub {
    display: block;
  }

  .so-table tbody th,
  .so-table tbody td {
    padding: 12px 8px;
  }

  .so-table thead th {
    padding: 0 8px;
  }

  .so-table {
    width: calc(100% + 16px);
    margin-inline: -8px;
  }
}

/* ----------------------------------------------------------------- notes -- */
.so-notes dl {
  display: grid;
  margin-top: 8px;
}

.so-notes dl > div {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: 4px 24px;
  border-bottom: 1px solid var(--so-fog);
  padding: 14px 0;
}

.so-notes dt {
  color: var(--so-ink);
  font-size: 14px;
  font-weight: 600;
}

.so-notes dd {
  max-width: 68ch;
  color: var(--so-graphite);
  font-size: 14px;
  line-height: 1.55;
  letter-spacing: -0.28px;
}

.so-notes-link {
  margin-top: 16px;
  font-size: 14px;
}

/* ------------------------------------------------------------ responsive -- */
@media (max-width: 960px) {
  html.epieme-authenticated[data-app-shell] .so-table thead th {
    top: 56px;
  }

  html.epieme-authenticated[data-app-shell] {
    scroll-padding-top: 104px;
  }
}

@media (max-width: 720px) {
  .so-main {
    padding-top: 40px;
    padding-bottom: 56px;
  }

  .so-summary {
    font-size: 16px;
    letter-spacing: -0.32px;
  }

  .so-section {
    margin-top: 48px;
  }

  .so-asof {
    display: block;
    margin: 2px 0 0;
  }

  .so-swatch {
    width: 44px;
  }

  .so-search {
    flex-basis: 100%;
  }

  .so-input {
    font-size: 16px;
  }

  .so-count {
    margin-left: 0;
  }

  .so-notes dl > div {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (prefers-reduced-motion: reduce) {
  .us-map:empty {
    animation: none;
  }
}

/* High-contrast modes would flatten every tile and swatch to Canvas and
   turn the sort mark's transparent borders solid; the map keeps its own
   colours (each label already clears 4.5:1) and the counts always show. */
@media (forced-colors: active) {
  .so-tile,
  .so-swatch,
  .so-sort-mark {
    forced-color-adjust: none;
  }

  .so-tile {
    border: 1px solid CanvasText;
  }

  .so-tile-count {
    display: block;
  }

  .so-sort-mark {
    border-right-color: transparent;
    border-left-color: transparent;
    color: CanvasText;
  }
}
