:root {
  --ink: #132033;
  --ink-soft: #3a4a5c;
  --muted: #566270;
  --paper: #f4f6f8;
  --surface: #ffffff;
  --line: #d8dfe6;
  --line-strong: #b2bfcd;
  --accent: #0f6e6a;
  --accent-deep: #0a4f4c;
  --accent-soft: #e0f0ee;
  /* Metric series, matching METRIC_COLORS in app.js and the paper figures:
     one slate family separated by luminance, not hue, so the three bars stay
     three distinct greys in print. --ground-edge outlines the light fill, which
     is otherwise close to the empty track in brightness. */
  --corr: #2f5a7e;
  --ground: #93b4c9;
  --ground-edge: #6f97b1;
  --both: #132033;
  --yes-soft: #e2eee8;
  --fail: #8c4033;
  --fail-soft: #f6e6e2;
  --shadow: 0 1px 2px rgba(19, 32, 51, 0.05), 0 8px 24px rgba(19, 32, 51, 0.045);
  --radius: 12px;
  /* One panel inset, shared by the panels and by the question view's own
     headings, so a page has a single left gutter to read down. */
  --panel-pad: 1.15rem;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Source Sans 3", "Segoe UI", system-ui, sans-serif;
  --max: 1180px;
}

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

/* Sticky footer: fill the Space iframe / window when content is short.
   min-height: 100vh belongs on this page shell only. Putting it (or 70vh)
   on .main, .app-shell, or .sheet-wrap recreates the blank band under
   the Responses table, with the footer stranded in leftover viewport. */
html {
  height: 100%;
}

body {
  margin: 0;
  min-height: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
  overflow-wrap: break-word;
}

/* Every long string in this dataset (URLs, citations, question ids) must wrap
   rather than push its container wider than the page. */
p,
li,
td,
th,
h1,
h2,
h3,
.chip,
.prose-block,
.meta {
  overflow-wrap: anywhere;
}

a {
  color: var(--accent-deep);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

a:hover {
  color: var(--accent);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: #fff;
  padding: 0.5rem 0.75rem;
  border-radius: 0 0 8px 0;
  z-index: 100;
}

.skip-link:focus {
  left: 0.75rem;
  top: 0.75rem;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- shell ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(244, 246, 248, 0.94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}

.header-inner,
.footer-inner,
.app-shell {
  width: min(100% - 2rem, var(--max));
  margin-inline: auto;
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.25rem;
  flex-wrap: wrap;
  padding: 0.8rem 0;
  min-width: 0;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--ink);
  text-decoration: none;
  min-width: 0;
  flex: 1 1 16rem;
}

.brand-mark {
  width: 2rem;
  height: 2rem;
  flex: 0 0 auto;
  color: var(--ink);
}

.brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.brand-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -0.01em;
  line-height: 1.25;
}

.brand-sub {
  color: var(--muted);
  font-size: 0.76rem;
  line-height: 1.35;
}

.nav {
  display: flex;
  gap: 0.25rem;
  flex-wrap: wrap;
  justify-content: flex-end;
  min-width: 0;
}

.nav a {
  display: inline-flex;
  align-items: center;
  gap: 0.38rem;
  color: var(--ink-soft);
  text-decoration: none;
  padding: 0.4rem 0.75rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.92rem;
  white-space: nowrap;
  border: 1px solid transparent;
}

.nav-icon {
  width: 0.98rem;
  height: 0.98rem;
  flex: none;
  color: currentColor;
}

.nav a:hover {
  color: var(--ink);
  border-color: var(--line);
  background: var(--surface);
}

.nav a[aria-current="page"] {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

.main {
  flex: 1 0 auto;
  padding: 1.5rem 0 1.5rem;
  min-height: 0;
}

.app-shell {
  min-width: 0;
  min-height: 0;
  height: auto;
}

.loading,
.error {
  padding: 2rem;
  text-align: center;
  color: var(--muted);
}

.error {
  color: var(--fail);
}

/* ---------- headings ---------- */

.page-hero {
  display: grid;
  gap: 0.6rem;
  margin-bottom: 1.4rem;
  min-width: 0;
}

.page-hero h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 1.2rem + 1.8vw, 2.3rem);
  letter-spacing: -0.02em;
  line-height: 1.18;
}

.page-hero p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1.55;
}

.eyebrow {
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ---------- stats ---------- */

.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.75rem;
  margin: 0 0 1.25rem;
}

.stat-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.8rem 0.95rem;
  min-width: 0;
}

.stat-card .label {
  display: block;
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.stat-card .value {
  display: block;
  margin-top: 0.15rem;
  font-family: var(--font-body);
  font-size: 1.55rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums lining-nums;
}

.stat-card .value.is-name {
  font-size: 1.12rem;
  letter-spacing: -0.02em;
  line-height: 1.25;
  margin-top: 0.28rem;
}

/* ---------- panels ---------- */

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.1rem var(--panel-pad) 1.2rem;
  min-width: 0;
  overflow: clip;
}

.panel + .panel {
  margin-top: 1rem;
}

.panel h2 {
  margin: 0 0 0.3rem;
  font-family: var(--font-display);
  font-size: 1.2rem;
  line-height: 1.3;
}

.panel-note {
  margin: 0 0 0.9rem;
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1.55;
}

/* ---------- tables ---------- */

.table-wrap {
  width: 100%;
  overflow-x: auto;
  /* Keep the focus ring and sticky header from being clipped. */
  padding-bottom: 0.15rem;
}

/* A table that is wider than its panel needs to say so, or a phone reader takes
   the first three visible columns for the whole grid. The two `local` layers
   scroll with the content and rub out the shadow at whichever end has been
   reached, so the shading only ever appears where there is more to see. */
.table-wrap.is-scroller {
  background:
    linear-gradient(to right, var(--surface) 40%, rgba(255, 255, 255, 0)) left center / 2.4rem 100%
      no-repeat local,
    linear-gradient(to left, var(--surface) 40%, rgba(255, 255, 255, 0)) right center / 2.4rem 100%
      no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(19, 32, 51, 0.2), rgba(19, 32, 51, 0)) left center /
      0.7rem 100% no-repeat,
    radial-gradient(farthest-side at 100% 50%, rgba(19, 32, 51, 0.2), rgba(19, 32, 51, 0)) right
      center / 0.7rem 100% no-repeat;
}

/* Only shown where a panel actually scrolls sideways — see the responsive
   section at the end of the file. */
.scroll-hint {
  display: none;
  margin: 0.55rem 0 0;
  color: var(--muted);
  font-size: 0.8rem;
}

.leaderboard-table {
  width: 100%;
  min-width: 44rem;
  border-collapse: collapse;
  font-size: 0.94rem;
}

.leaderboard-table th,
.leaderboard-table td {
  padding: 0.65rem 0.6rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.leaderboard-table th {
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 700;
  white-space: nowrap;
  border-bottom: 1px solid var(--line-strong);
}

.leaderboard-table tbody tr {
  cursor: pointer;
  transition: background 0.15s ease;
}

.leaderboard-table tbody tr:hover,
.leaderboard-table tbody tr:focus-visible {
  background: #f3f8f8;
}

.leaderboard-table tbody tr:last-child td {
  border-bottom: 0;
}

.col-num {
  width: 5.5rem;
}

.rank-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6rem;
  height: 1.6rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums lining-nums;
}

/* Places 1–3: clean flat discs with muted metallic tones.
   4+ stay the numbered accent pills above. */
.rank-pill.is-medal {
  width: 1.6rem;
  min-width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  font-size: 0.78rem;
  line-height: 1;
}

.rank-pill.is-medal .medal-num {
  font-weight: 700;
  font-variant-numeric: tabular-nums lining-nums;
}

.rank-pill.medal-gold {
  background: #b8962a;
  color: #fff;
  box-shadow: 0 1px 2px rgba(140, 110, 20, 0.25);
}

.rank-pill.medal-silver {
  background: #8e8e8e;
  color: #fff;
  box-shadow: 0 1px 2px rgba(80, 80, 80, 0.2);
}

.rank-pill.medal-bronze {
  background: #9e6b3a;
  color: #fff;
  box-shadow: 0 1px 2px rgba(120, 80, 40, 0.22);
}

.provider-cell {
  font-weight: 700;
  min-width: 8rem;
}

/* ---------- provider marks ---------- */

/* Each system's own logo, beside its name in the sheet, the cards, the tabs,
   the charts, the comparison table, and the heatmap. The box is sized in `em`, so
   a mark is always the height of the text it labels: large enough to tell six
   systems apart at a glance, never large enough to set the line height. */
.provider-logo {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 1.2em;
  height: 1.2em;
  vertical-align: -0.22em;
}

/* The marks are square; `contain` means a future one is letterboxed rather
   than stretched or cropped. */
.provider-logo-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* The system's initial, added only when a mark file fails to load, so a row
   loses the artwork and nothing else. */
.provider-logo-mono {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 0.68em;
  font-weight: 700;
  line-height: 1;
}

.provider-logo.is-fallback .provider-logo-img {
  display: none;
}

/* Mark and name travel as one unit, so a narrow column can wrap the name but
   never strand the logo on a line of its own. */
.provider-name {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  min-width: 0;
}

.provider-name-text {
  min-width: 0;
}

/* In the About list the mark sits with the system name rather than with the
   bullet, so the six names still start on one left edge. */
.system-list .provider-name {
  vertical-align: -0.28em;
}

/* Two of the marks are near-black tiles, which would sink into an ink pill when
   that system is the selected tab, chart row, or filter. A hairline of the
   pill's own text colour keeps every mark on its own edge. */
.provider-tabs button[aria-selected="true"] .provider-logo,
.provider-tabs a[aria-current="page"] .provider-logo,
button.hbar-name.is-active .provider-logo,
.pill[aria-checked="true"] .provider-logo {
  border-radius: 0.28em;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.45);
}

.metric-cell {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}

.metric-sub {
  display: block;
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 500;
  white-space: nowrap;
}

/* HTML progress bars. Scoped to div so SVG <rect> never inherits these. */
div.bar-track {
  height: 0.4rem;
  border-radius: 999px;
  background: #eef2f6;
  overflow: hidden;
  margin-top: 0.35rem;
  min-width: 3.5rem;
}

div.bar-fill {
  height: 100%;
  border-radius: inherit;
}

div.bar-fill.corr {
  background: var(--corr);
}

div.bar-fill.ground {
  background: var(--ground);
  box-shadow: inset 0 0 0 1px var(--ground-edge);
}

div.bar-fill.both {
  background: var(--both);
}

/* ---------- charts ---------- */

.chart-wrap {
  width: 100%;
  min-width: 0;
}

.chart-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  font-family: var(--font-body);
}

.chart-svg text {
  font-family: var(--font-body);
}

/* Horizontal grouped bars, laid out in HTML so labels are real text: they never
   scale down with an SVG viewBox and never end up drawn underneath a bar.
   Source order is name, label, value, track; every item below is pinned to its
   own column, so the phone layout can reflow the same markup into two columns
   with the track on its own line. */
.hbar-chart {
  display: grid;
  grid-template-columns: minmax(5rem, 8.5rem) 6.2rem minmax(4rem, 1fr) 3.6rem;
  grid-auto-flow: dense;
  align-items: center;
  gap: 0.3rem 0.7rem;
  min-width: 0;
}

/* Single-metric comparison charts drop the repeated series label (the panel
   title already names it) so the count (percentage) has a column of its own. */
.hbar-chart.is-single {
  grid-template-columns: minmax(7rem, 11rem) minmax(4rem, 1fr) 7.5rem;
}

.hbar-chart.is-single:has(.hbar-name.is-ranked) {
  grid-template-columns: minmax(8.75rem, 13.5rem) minmax(4rem, 1fr) 7.5rem;
}

.hbar-chart.is-single .hbar-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.hbar-chart.is-single .hbar-track,
.hbar-chart.is-single .hbar-axis,
.hbar-chart.is-single .hbar-direction {
  grid-column: 2;
}

.hbar-chart.is-single .hbar-value {
  grid-column: 3;
}

/* Two series per system instead of three. */
.hbar-chart.pairs .hbar-name {
  grid-row: span 2;
}

.hbar-chart.is-single .hbar-name {
  grid-row: span 1;
}

.hbar-name.is-ranked {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  max-width: 100%;
}

.hbar-name.is-ranked .rank-pill {
  flex: none;
  align-self: center;
}

.hbar-name.is-ranked .provider-name {
  flex: 1 1 auto;
}

.hbar-name {
  grid-column: 1;
  grid-row: span 3;
  font-weight: 700;
  font-size: 0.94rem;
  line-height: 1.25;
  padding-right: 0.2rem;
  color: var(--ink);
}

/* The question chart's system names double as the answer selector. */
button.hbar-name {
  justify-self: start;
  align-self: center;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  padding: 0.2rem 0.45rem;
  margin-left: -0.45rem;
  font: inherit;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

button.hbar-name:hover {
  border-color: var(--accent);
  color: var(--accent-deep);
}

button.hbar-name.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

.hbar-label {
  grid-column: 2;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
}

.hbar-track {
  grid-column: 3;
  position: relative;
  display: block;
  height: 0.95rem;
  min-width: 0;
  background-color: #f0f4f7;
  background-image: linear-gradient(to right, var(--line) 0 1px, transparent 1px 100%);
  background-size: 25% 100%;
  border-left: 1px solid var(--line-strong);
  border-radius: 0 3px 3px 0;
}

.hbar-fill {
  position: absolute;
  inset-block: 0;
  left: 0;
  display: block;
  border-radius: 0 2px 2px 0;
}

/* Bars are painted inline from METRIC_COLORS in app.js; these declarations are
   the fallback if the inline style is ever stripped. */
.hbar-fill.both {
  background-color: var(--both);
}

.hbar-fill.corr {
  background-color: var(--corr);
}

/* The light slate fill is only about twice as bright as the empty track, so it
   gets a half-tone edge to keep the bar end obvious. */
.hbar-fill.ground {
  background-color: var(--ground);
  box-shadow: inset 0 0 0 1px var(--ground-edge);
}

/* A binary grade is full or empty, so the quarter gridlines would only mislead. */
.hbar-chart.binary .hbar-track {
  background-image: none;
}

/* Wilson interval: a hairline rule with end caps in one ink for every series.
   It crosses its own fill and the empty track, so it is cased in white — the
   casing is what keeps it visible where it runs over the ink "both" bar. */
.hbar-ci {
  --ci-ink: #132033;
  position: absolute;
  top: 50%;
  height: 0.62rem;
  transform: translateY(-50%);
  border-left: 1.5px solid var(--ci-ink);
  border-right: 1.5px solid var(--ci-ink);
  filter: drop-shadow(0 0 0.5px #ffffff) drop-shadow(0 0 1.5px rgba(255, 255, 255, 0.95));
}

.hbar-ci::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  border-top: 1.5px solid var(--ci-ink);
}

.hbar-value {
  grid-column: 4;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.86rem;
  text-align: right;
  white-space: nowrap;
}

.hbar-axis {
  grid-column: 3;
  position: relative;
  height: 1.3rem;
  margin-top: 0.15rem;
  border-top: 1px solid var(--line-strong);
  color: var(--muted);
  font-size: 0.74rem;
}

.hbar-axis span {
  position: absolute;
  top: 0.1rem;
  transform: translateX(-50%);
  white-space: nowrap;
}

.hbar-axis span:first-child {
  transform: none;
}

.hbar-axis span:last-child {
  transform: translateX(-100%);
}

/* Direction cue: which end of the scale is the good one. Every series in this
   chart is a rate of answers that met a measure, so it points at 100%. It sits
   in the track column under the ticks, spanning exactly the bars it describes. */
.hbar-direction {
  grid-column: 3;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
  max-width: 100%;
  color: var(--ink-soft);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.hbar-direction-text {
  flex: none;
  white-space: nowrap;
}

/* The rule and its arrowhead take whatever width is left, so the cue reads as
   an axis annotation rather than as another bar. */
.hbar-direction-line {
  position: relative;
  flex: 1 1 auto;
  min-width: 1.5rem;
  height: 1px;
  background: var(--line-strong);
}

.hbar-direction-line::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  border-left: 5px solid var(--line-strong);
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
}

/* Latency / cost charts point at the origin instead of at 100%. */
.hbar-direction.is-shorter {
  flex-direction: row-reverse;
}

.hbar-direction.is-shorter .hbar-direction-line::after {
  right: auto;
  left: 0;
  border-left: 0;
  border-right: 5px solid var(--line-strong);
}

/* ---------- heat table ---------- */

.heat-table {
  width: 100%;
  min-width: 40rem;
  border-collapse: separate;
  border-spacing: 3px;
  font-size: 0.86rem;
}

.heat-table th[scope="col"] {
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 700;
  text-align: center;
  padding: 0 0 0.2rem;
  white-space: nowrap;
}

/* The system name is what a scrolled-away column of numbers means, so it holds
   the left edge of the scroll port. */
.heat-table th[scope="row"] {
  position: sticky;
  left: 0;
  z-index: 1;
  text-align: right;
  font-weight: 600;
  white-space: nowrap;
  padding: 0.42rem 0.5rem 0.42rem 0;
  vertical-align: middle;
  background: var(--surface);
  color: var(--ink);
}

.heat-system {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.4rem;
}

.heat-table thead th:first-child,
.heat-table thead th.heat-corner {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
  text-align: right;
  font-size: 0;
  line-height: 0;
  padding: 0 0.5rem 0.2rem 0;
}

/* `border-spacing` leaves a gap above and below every cell, and a cell scrolling
   under the pinned name would show through that gap as a stray dash. The pinned
   cell carries its own backdrop, tall enough to close it. */
.heat-table th[scope="row"]::before,
.heat-table thead th:first-child::before {
  content: "";
  position: absolute;
  inset-block: -4px;
  inset-inline: 0;
  background: var(--surface);
  z-index: -1;
}

.heat-cell {
  text-align: center;
  padding: 0.42rem 0.3rem;
  border-radius: 4px;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  margin-top: 0.9rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.85rem;
}

.legend span {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

.swatch {
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 3px;
  flex: 0 0 auto;
  border: 1px solid rgba(19, 32, 51, 0.18);
}

.swatch.corr {
  background: var(--corr);
}

.swatch.ground {
  background: var(--ground);
  border-color: var(--ground-edge);
}

/* Not ".empty": that class is the no-results block, and it would win on padding. */
.swatch.blank {
  background: #f0f4f7;
  border-left: 1px solid var(--line-strong);
}

.swatch.both {
  background-color: var(--both);
}

.swatch.ci {
  --ci-ink: #132033;
  background: transparent;
  border: 0;
  border-left: 1.5px solid var(--ci-ink);
  border-right: 1.5px solid var(--ci-ink);
  position: relative;
  border-radius: 0;
  width: 0.9rem;
}

.swatch.ci::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  border-top: 1.5px solid var(--ci-ink);
}

.chart-note-mark {
  margin-left: 0.08em;
  font-weight: 700;
  font-size: 0.78em;
  line-height: 0;
  color: #c44;
}

.chart-footnote {
  margin: 0.7rem 0 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
  line-height: 1.45;
}

/* LawNet hallucination ranking note: same red as the matching asterisk. */
.chart-footnote.is-alert {
  color: #c44;
}

.chart-footnote + .chart-caption {
  margin-top: 0.4rem;
}

.chart-caption {
  margin: 0.75rem 0 0;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* Heatmap key: number → category name, kept to one compact block. */
.heat-key {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 0.1rem 1rem;
  margin: 0.85rem 0 0;
  padding: 0.75rem 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
  color: var(--muted);
  font-size: 0.8rem;
}

.heat-key li {
  min-width: 0;
}

.heat-key b {
  color: var(--ink-soft);
}

.heat-scale {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.85rem;
  color: var(--muted);
  font-size: 0.8rem;
}

.heat-scale i {
  width: 1.6rem;
  height: 0.8rem;
  border-radius: 2px;
  border: 1px solid rgba(19, 32, 51, 0.14);
}

/* Reads before the swatches: the cells are a rate of correct-and-grounded
   answers, so the dark end of the ramp is the good end. */
.heat-scale-dir {
  margin-right: 0.35rem;
  color: var(--ink-soft);
  font-weight: 700;
}

/* ---------- filter bar ---------- */

/* One stack of labelled rows, read down the same left gutter: the label sits in
   its own column, the control sits in the column beside it, and a dotted rule
   separates one filter from the next. Nothing here is a native <select>: the
   pills are the header nav's pills and the popover is the same paper as a
   panel, so the filters look like part of this site rather than the OS. */
.filter-bar {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0 0 1rem;
  padding: 0.8rem 0.9rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fafcfc;
  min-width: 0;
}

.filter-field {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: 0.2rem 1rem;
  align-items: start;
  min-width: 0;
}

.filter-field + .filter-field {
  border-top: 1px dotted var(--line-strong);
  padding-top: 0.5rem;
}

.filter-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  /* Level with the text inside the first pill on the row. */
  padding-top: 0.42rem;
}

.filter-control {
  display: grid;
  gap: 0.3rem;
  min-width: 0;
}

.filter-hint {
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
}

.filter-bar .filter-field.is-search {
  width: 100%;
  min-width: 0;
}

.filter-bar .filter-field.is-search .filter-input {
  max-width: none;
}

.filter-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
  gap: 0.75rem 1rem;
  min-width: 0;
}

.filter-row .filter-field {
  border-top: 0;
  padding-top: 0;
  grid-template-columns: minmax(0, 1fr);
}

.filter-row .filter-label {
  padding-top: 0;
}

.filter-row .listbox {
  max-width: none;
}

.filter-input {
  width: 100%;
  max-width: 34rem;
  min-width: 0;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.42rem 0.85rem;
  font: inherit;
  font-size: 0.92rem;
  color: var(--ink);
  background: #fff;
}

.filter-input:focus {
  outline: 2px solid rgba(15, 110, 106, 0.35);
  outline-offset: 0;
  border-color: var(--accent);
}

/* ---------- pill group ---------- */

/* Chips wrap onto as many rows as the panel needs; they never scroll sideways
   and never push the panel wider than the page. */
.pill-group {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-width: 0;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 100%;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  background: #fff;
  color: var(--ink-soft);
  font: inherit;
  font-size: 0.86rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.pill:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--ink);
}

/* The chosen chip is ink, exactly like the current page in the header nav and
   the selected system tab in the question view. */
.pill[aria-checked="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

.pill[aria-checked="true"]:hover {
  border-color: var(--ink);
  color: #fff;
}

.pill:disabled {
  cursor: default;
  color: var(--muted);
  border-color: var(--line);
  background: #f2f5f7;
  opacity: 0.7;
}

.pill-count {
  font-variant-numeric: tabular-nums;
  font-size: 0.78rem;
  font-weight: 700;
  opacity: 0.7;
}

/* ---------- listbox ---------- */

/* Eight category names are sentences, so they go behind a trigger instead of
   into a wall of chips. Same pill silhouette, opened by click or keyboard. */
.listbox {
  position: relative;
  min-width: 0;
  max-width: 26rem;
}

.listbox-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.26rem 0.35rem 0.26rem 0.85rem;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.listbox-button:hover {
  border-color: var(--accent);
}

.listbox-current {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A filter that is actually set reads as set from across the panel, in the
   slate of the correctness series rather than a second green. */
.listbox.is-set .listbox-button {
  border-color: var(--corr);
  background: #eef3f8;
  color: #24425c;
}

.listbox.is-set .listbox-caret {
  background: var(--corr);
}

.listbox.is-set .listbox-caret::before {
  border-color: #fff;
}

.listbox-caret {
  flex: 0 0 auto;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 999px;
  background: #eef2f5;
  display: inline-grid;
  place-items: center;
}

.listbox-caret::before {
  content: "";
  width: 0.38rem;
  height: 0.38rem;
  border-right: 1.5px solid var(--ink-soft);
  border-bottom: 1.5px solid var(--ink-soft);
  transform: translateY(-0.1rem) rotate(45deg);
}

.listbox.is-open .listbox-caret::before {
  transform: translateY(0.1rem) rotate(225deg);
}

.listbox-popover {
  position: absolute;
  z-index: 30;
  top: calc(100% + 0.35rem);
  left: 0;
  min-width: 100%;
  width: max-content;
  max-width: min(26rem, calc(100vw - 3rem));
  padding: 0.3rem;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

/* The panel clips its content, which would cut the popover off; while one is
   open the panel stops clipping. */
.panel:has(.listbox.is-open) {
  overflow: visible;
}

.listbox-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 17rem;
  overflow-y: auto;
}

/* Focus is on the list, but the reader's eye needs it on the active option, so
   the list itself shows no ring. */
.listbox-list:focus {
  outline: none;
}

.listbox-option {
  display: grid;
  grid-template-columns: 0.95rem auto minmax(0, 1fr);
  align-items: baseline;
  gap: 0.45rem;
  padding: 0.34rem 0.5rem;
  border-radius: 7px;
  color: var(--ink-soft);
  font-size: 0.9rem;
  cursor: pointer;
}

/* "All categories" carries no number, so its text spans the lead column. */
.listbox-option:not(:has(.listbox-lead)) {
  grid-template-columns: 0.95rem minmax(0, 1fr);
}

.listbox-option.is-active {
  background: #eef2f5;
  color: var(--ink);
}

.listbox-option[aria-selected="true"] {
  color: #24425c;
  font-weight: 700;
}

.listbox-tick {
  width: 0.95rem;
  color: var(--corr);
  font-size: 0.85rem;
  line-height: 1.3;
}

.listbox-option[aria-selected="true"] .listbox-tick::before {
  content: "✓";
}

.listbox-lead {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--muted);
  background: #eef2f5;
  border-radius: 4px;
  padding: 0 0.3rem;
}

.listbox-option[aria-selected="true"] .listbox-lead {
  color: #fff;
  background: var(--corr);
}

.result-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.75rem;
  align-items: center;
  justify-content: space-between;
  margin: 0 0 0.75rem;
  color: var(--muted);
  font-size: 0.9rem;
  min-width: 0;
}

.result-meta strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.reset-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--accent-deep);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ---------- chips ---------- */

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-width: 0;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.16rem 0.5rem;
  border-radius: 6px;
  font-size: 0.78rem;
  font-weight: 600;
  border: 1px solid transparent;
  max-width: 100%;
}

.chip .glyph {
  font-weight: 700;
  font-size: 0.85em;
}

.chip.ok {
  background: var(--yes-soft);
  color: #23543c;
  border-color: #bcd6c7;
}

.chip.bad {
  background: var(--fail-soft);
  color: var(--fail);
  border-color: #e3c3bb;
}

.chip.neutral {
  background: #eef2f5;
  color: var(--ink-soft);
  border-color: #dbe2e9;
}

.chip.accent {
  background: var(--accent-soft);
  color: var(--accent-deep);
  border-color: #b7d9d5;
}

a.chip {
  text-decoration: none;
}

a.chip:hover {
  border-color: var(--accent);
}

.chip.id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.74rem;
  letter-spacing: 0.01em;
}

/* ---------- result cards ---------- */

/* Two columns of cards on anything wider than a tablet, so a page of results
   fills the panel instead of leaving a column of whitespace beside it. */
.card-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 26rem), 1fr));
  gap: 0.65rem;
  align-items: stretch;
  min-width: 0;
}

.result-card {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fcfdfd;
  cursor: pointer;
  min-width: 0;
  height: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.result-card:hover,
.result-card:focus-visible {
  border-color: var(--accent);
  box-shadow: var(--shadow);
}

.result-card > * {
  min-width: 0;
}

/* The clamp itself lives on .expandable-text, so the card only sets type. */
.result-card h3 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.42;
}

.card-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem 0.6rem;
  margin-top: auto;
  padding-top: 0.15rem;
}

.card-open {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent-deep);
  white-space: nowrap;
}

.outcome-pair {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  min-width: 0;
}

.outcome {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.5rem;
  padding: 0.22rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}

.outcome .verdict {
  font-weight: 700;
}

.outcome.yes {
  border-color: #bcd6c7;
  background: var(--yes-soft);
}

.outcome.yes .verdict {
  color: #23543c;
}

.outcome.no {
  border-color: #e3c3bb;
  background: var(--fail-soft);
}

.outcome.no .verdict {
  color: var(--fail);
}

.outcome.unscored .verdict {
  color: var(--muted);
}

/* ---------- expandable text ---------- */

/* Clipped text is its own control: the line ending in an ellipsis is the hit
   target, and the Show more button below repeats the action for the keyboard.
   Neither appears unless the text is measured as actually overflowing. */
.expandable {
  display: grid;
  gap: 0.15rem;
  justify-items: start;
  min-width: 0;
}

.expandable-text {
  display: -webkit-box;
  -webkit-line-clamp: var(--clamp-lines, 3);
  line-clamp: var(--clamp-lines, 3);
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-width: 0;
  max-width: 100%;
}

.expandable.is-open .expandable-text {
  display: block;
  -webkit-line-clamp: none;
  line-clamp: none;
  overflow: visible;
}

/* Only clipped text invites a click, so only clipped text takes the cursor. */
.expandable[data-truncated="1"] .expandable-text {
  cursor: pointer;
}

.expandable[data-truncated="1"] .expandable-text:hover {
  text-decoration: underline dotted var(--line-strong);
  text-underline-offset: 3px;
}

.expandable-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1rem 0.3rem;
  margin-left: -0.3rem;
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--accent-deep);
  cursor: pointer;
}

.expandable-toggle:hover {
  background: var(--accent-soft);
}

.expandable-chevron {
  font-size: 0.85em;
  line-height: 1;
  transition: transform 0.15s ease;
}

.expandable.is-open .expandable-chevron {
  transform: rotate(180deg);
}

/* Inside a card the question is the card's own heading, so the control sits
   tight under it rather than reading as a second paragraph. */
.expandable.card-question {
  gap: 0.1rem;
}

/* In the sheet the cell text is the reader's target; the button is the
   keyboard's, so it stays small and out of the column's way. */
.expandable.in-cell .expandable-text {
  line-height: 1.4;
  color: var(--ink-soft);
}

.expandable.in-cell .expandable-toggle {
  font-size: 0.74rem;
}

/* A thousand-word answer opened in a 17rem column would make one row taller
   than the whole sheet, so an opened cell scrolls inside its own box. */
.expandable.in-cell.is-open .expandable-text,
.expandable.in-cell.is-open .expandable-rich {
  max-height: 16rem;
  overflow: auto;
  scrollbar-gutter: stable;
  padding-right: 0.15rem;
}

/* The collapsed cell is one flat line of the stored text; the open cell is the
   same answer rendered, so nobody reads "## Short answer" in a spreadsheet. */
.expandable-rich {
  display: none;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--ink-soft);
}

.expandable.has-rich.is-open .expandable-text {
  display: none;
}

.expandable.has-rich.is-open .expandable-rich {
  display: block;
}

.expandable-rich .md-table-wrap {
  max-width: 100%;
}

/* ---------- pagination ---------- */

.pager {
  display: grid;
  justify-items: center;
  gap: 0.4rem;
  margin-top: 0.9rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line);
}

.pager-status {
  margin: 0;
  color: var(--muted);
  font-size: 0.86rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.pager-status strong {
  color: var(--ink);
}

.pager-hint {
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
}

.pager-hint kbd {
  font-family: inherit;
  font-size: 0.95em;
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0 0.25rem;
  background: #fff;
}

.pager-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
}

.pager-pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pager-btn,
.pager-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-width: 2.15rem;
  min-height: 2.15rem;
  padding: 0 0.55rem;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}

.pager-btn:hover:not([disabled]),
.pager-num:hover:not(.is-current) {
  border-color: var(--accent);
  color: var(--accent-deep);
  background: var(--accent-soft);
}

.pager-btn[disabled] {
  opacity: 0.45;
  cursor: default;
}

.pager-glyph {
  font-size: 1.15em;
  line-height: 1;
}

.pager-num.is-current {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: #fff;
  cursor: default;
}

.pager-gap {
  padding: 0 0.15rem;
  color: var(--muted);
}

/* The compact pager rides along the result count line. */
.pager.is-compact {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
  border-top: 0;
  vertical-align: middle;
}

.pager.is-compact .pager-btn {
  min-width: 1.9rem;
  min-height: 1.9rem;
  padding: 0 0.4rem;
  font-size: 0.82rem;
}

.pager-of {
  color: var(--ink-soft);
  font-size: 0.84rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.result-meta-side {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.85rem;
}

/* ---------- question detail ---------- */

.detail-heading {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.02rem;
  line-height: 1.3;
}

.prose-block {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 0.93rem;
  line-height: 1.6;
  max-height: 30rem;
  overflow: auto;
  /* Reserve the scrollbar track in both columns so a long answer and a short
     source list keep the same inner measure instead of one text block sitting
     a scrollbar's width further left than the other. */
  scrollbar-gutter: stable;
  padding: 0.8rem 0.95rem;
  background: #f8fafb;
  border: 1px solid var(--line);
  border-radius: 10px;
  min-width: 0;
}

.prose-block.tall {
  max-height: 42rem;
}

/* ---------- rendered answers ---------- */

/* Answers arrive as Markdown, so they are rendered as a document: the block
   keeps its own white space rules out of the way and the elements below carry
   the structure the system actually wrote. */
.prose-block.md {
  white-space: normal;
}

.md > :first-child {
  margin-top: 0;
}

.md > :last-child {
  margin-bottom: 0;
}

.md p {
  margin: 0 0 0.7rem;
}

.md h1,
.md h2,
.md h3,
.md h4,
.md h5,
.md h6 {
  font-family: var(--font-display);
  line-height: 1.28;
  margin: 1.15rem 0 0.45rem;
  color: var(--ink);
}

.md h1 {
  font-size: 1.18rem;
}

.md h2 {
  font-size: 1.08rem;
}

.md h3 {
  font-size: 1rem;
}

.md h4,
.md h5,
.md h6 {
  font-size: 0.94rem;
}

/* A heading that opens the answer should not push the text off its own top. */
.md > h1:first-child,
.md > h2:first-child,
.md > h3:first-child {
  margin-top: 0;
}

.md ul,
.md ol {
  margin: 0 0 0.7rem;
  padding-left: 1.35rem;
}

.md li {
  margin-bottom: 0.25rem;
}

.md li > ul,
.md li > ol {
  margin: 0.25rem 0 0.35rem;
}

.md blockquote {
  margin: 0 0 0.75rem;
  padding: 0.15rem 0 0.15rem 0.85rem;
  border-left: 3px solid var(--accent);
  color: var(--ink-soft);
}

.md blockquote > :last-child {
  margin-bottom: 0;
}

.md code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.86em;
  background: #eef2f5;
  padding: 0.05rem 0.3rem;
  border-radius: 4px;
}

.md pre {
  margin: 0 0 0.75rem;
  padding: 0.7rem 0.8rem;
  background: #eef2f5;
  border-radius: 8px;
  overflow-x: auto;
}

.md pre code {
  background: none;
  padding: 0;
  font-size: 0.85em;
}

.md hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1rem 0;
}

.md strong {
  font-weight: 700;
  color: var(--ink);
}

.md-table-wrap {
  width: 100%;
  overflow-x: auto;
  margin: 0 0 0.8rem;
}

.md-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.md-table th,
.md-table td {
  border: 1px solid var(--line);
  padding: 0.4rem 0.55rem;
  text-align: left;
  vertical-align: top;
}

.md-table th {
  background: #eef4f5;
  font-weight: 700;
}

/* The citation anchor the runners wrote into the answer text. Marked, not
   turned into a link: the numbered list below the answer is where it resolves. */
.cite {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78em;
  font-weight: 600;
  white-space: nowrap;
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-radius: 4px;
  padding: 0.02rem 0.28rem;
}

.source-list {
  margin: 0;
  padding-left: 0;
  list-style: none;
  display: grid;
  gap: 0.45rem;
}

.source-list li {
  display: grid;
  gap: 0.1rem;
  padding-left: 0;
  font-size: 0.9rem;
  line-height: 1.45;
}

.source-title {
  color: var(--ink);
  font-weight: 600;
}

.source-list a {
  font-size: 0.85rem;
  overflow-wrap: anywhere;
}

.empty-note {
  margin: 0;
  color: var(--muted);
  font-style: italic;
}

/* The response panel is one three-row grid: title + tabs, then the grades,
   then the two answer columns. Every row starts on the panel's own left
   gutter, so headings, chips, and body text share a single indent. */
.response-panel {
  display: grid;
  gap: 0.85rem;
  align-content: start;
}

.response-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  min-width: 0;
}

.response-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.2rem;
  line-height: 1.3;
  flex: 0 0 auto;
}

/* Row 2 uses the same two tracks as the answer columns below it, so the grades
   start on the Answer gutter and the collection metadata starts exactly where
   the Sources column does. */
.response-scores {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: 0.5rem 1.25rem;
  align-items: center;
  min-width: 0;
}

.grade-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.85rem;
  min-width: 0;
}

/* Two equal columns, so "Correct" and "Grounded" read as one aligned pair
   rather than two chips of whatever width their words happen to need. */
.grade-chips {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 11rem));
  gap: 0.4rem;
  min-width: 0;
}

.grade-chip {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.4rem;
  padding: 0.28rem 0.45rem 0.28rem 0.6rem;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  font-size: 0.84rem;
  font-weight: 600;
  min-width: 0;
}

.grade-chip-name {
  min-width: 0;
  overflow-wrap: normal;
  white-space: nowrap;
}

/* The digit is the released grade, so it gets the strongest treatment on the
   chip; the word beside it repeats the same fact for anyone reading in
   greyscale or with colour vision deficiency. */
.grade-chip-bit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  padding: 0 0.25rem;
  border-radius: 5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
}

.grade-chip-word {
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
}

.grade-chip.is-yes {
  background: var(--yes-soft);
  border-color: #bcd6c7;
  color: #23543c;
}

.grade-chip.is-yes .grade-chip-bit {
  background: #23543c;
  color: #fff;
}

.grade-chip.is-no {
  background: var(--fail-soft);
  border-color: #e3c3bb;
  color: var(--fail);
}

.grade-chip.is-no .grade-chip-bit {
  background: var(--fail);
  color: #fff;
}

.grade-chip.is-none {
  background: #eef2f5;
  border-color: #dbe2e9;
  color: var(--muted);
}

.grade-chip.is-none .grade-chip-bit {
  background: #dbe2e9;
  color: var(--ink-soft);
}

.grade-note {
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.response-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
}

/* Answer and Sources are equal-top columns: both stretch to the same height,
   so the two headings sit on one baseline and the two panels end together. */
.response-columns {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: 1.25rem;
  align-items: stretch;
  min-width: 0;
}

.response-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.col-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.3rem 0.75rem;
  min-height: 1.75rem;
  margin-bottom: 0.45rem;
  min-width: 0;
}

.col-note {
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* One cap for both columns, and the shorter one grows into it, so neither
   column trails a strip of empty panel beside the other. */
.response-col .prose-block,
.response-col .prose-block.tall {
  flex: 1 1 auto;
  min-height: 14rem;
  max-height: min(38rem, 62vh);
}

/* The question is the subject of the page, so it spans the whole panel rather
   than sitting in a narrow measure with two thirds of the row left empty. */
.question-panel {
  border-left: 4px solid var(--accent);
}

.question-label {
  margin: 0 0 0.45rem;
  color: var(--muted);
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.question-text {
  margin: 0;
  max-width: none;
  color: var(--ink);
  font-size: 1.06rem;
  line-height: 1.65;
}

.provider-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  min-width: 0;
}

.provider-tabs button,
.provider-tabs a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  border: 1px solid var(--line-strong);
  background: #fff;
  color: var(--ink-soft);
  border-radius: 999px;
  padding: 0.32rem 0.7rem;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  max-width: 100%;
  text-decoration: none;
}

.provider-tabs button:hover,
.provider-tabs a:hover {
  border-color: var(--accent);
}

.provider-tabs button[aria-selected="true"],
.provider-tabs a[aria-current="page"] {
  background: var(--ink);
  color: #fff;
  border-color: var(--ink);
}

.provider-dash .provider-switch {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.4rem;
  width: 100%;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line);
}

.provider-dash .provider-switch a {
  justify-content: center;
  min-width: 0;
  max-width: none;
}

.provider-dash .provider-switch .provider-name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

/* The question view is read as one column of prose, so its back link and page
   title sit on the same gutter as the panel contents below them. */
.app-shell[data-view="question"] > .back-link,
.app-shell[data-view="question"] > .page-hero {
  padding-inline: var(--panel-pad);
}

.about-list {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--ink-soft);
  min-width: 0;
  font-size: 1rem;
  line-height: 1.55;
}

.about-list li + li {
  margin-top: 0.4rem;
}

.about-list code {
  font-size: 0.85em;
  background: #eef2f5;
  padding: 0.05rem 0.3rem;
  border-radius: 4px;
}

/* ---------- footer ---------- */

.site-footer {
  flex: 0 0 auto;
  margin-top: auto;
  border-top: 1px solid var(--line);
  padding: 1.1rem 0 1.4rem;
  color: var(--muted);
  font-size: 0.88rem;
  background: var(--surface);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.5rem;
  justify-content: space-between;
  align-items: baseline;
  min-width: 0;
}

.footer-inner p {
  margin: 0;
  max-width: 60ch;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin: 0;
}

.empty {
  padding: 1.5rem;
  text-align: center;
  color: var(--muted);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
}

/* ---------- responses sheet ---------- */

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

.grade-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.95rem;
  margin: 0 0 0.9rem;
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fafcfc;
  color: var(--ink-soft);
  font-size: 0.88rem;
}

.grade-legend span {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.legend-title {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The released grades are 1/0, so the cell shows the digit itself rather than
   translating it into a glyph the CSV does not use. */
.bit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6rem;
  padding: 0.08rem 0.35rem;
  border: 1px solid transparent;
  border-radius: 6px;
  font-style: normal;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.bit.yes {
  background: var(--yes-soft);
  color: #23543c;
  border-color: #bcd6c7;
}

.bit.no {
  background: var(--fail-soft);
  color: var(--fail);
  border-color: #e3c3bb;
}

.bit.none {
  background: #eef2f5;
  color: var(--muted);
  border-color: #dbe2e9;
}

.sheet-actions {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  min-width: 0;
  max-width: 100%;
}

/* Own row above the pager so the CSV controls cannot clip behind overflow:clip
   on .panel or sit in the site footer. */
.sheet-downloads {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.65rem;
  align-items: center;
  margin: 0 0 0.75rem;
  min-width: 0;
}

.sheet-download {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.42rem 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.25;
  cursor: pointer;
}

.sheet-download:hover {
  border-color: var(--accent);
  background: #d4ebe8;
}

.sheet-download:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.sheet-download-hint {
  flex: 1 1 100%;
  margin: 0;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.35;
}

/* Own scroll container: the sticky header needs one, and it keeps the wide
   sheet inside the panel instead of pushing the page sideways. */
.sheet-wrap {
  width: 100%;
  max-height: 36rem;
  min-height: 0;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  overscroll-behavior-x: contain;
}

.sheet-wrap:focus-visible {
  outline: 2px solid rgba(15, 110, 106, 0.35);
  outline-offset: 2px;
}

.sheet {
  width: 100%;
  /* The sum of the column widths at the end of this block. With
     `table-layout: fixed` a smaller total would make the browser scale every
     column instead of honouring those widths. */
  min-width: 125.5rem;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  font-size: 0.88rem;
}

.sheet thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: #eef4f5;
  color: var(--ink);
  text-align: left;
  padding: 0.45rem 0.6rem;
  border-bottom: 1px solid var(--line-strong);
  font-size: 0.71rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.sheet tbody td {
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.sheet tbody tr:hover td {
  background: #f7fbfb;
}

.sheet tbody tr.is-open td {
  background: #f1f8f7;
}

.sheet code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82rem;
}

.sheet .cat-num {
  font-weight: 700;
  color: var(--accent-deep);
}

.sheet .clip {
  line-height: 1.4;
  color: var(--ink-soft);
}

.sheet .empty-cell {
  color: var(--muted);
  font-style: italic;
}

/* Abbreviated header spelling for a column too narrow to hold the full one.
   Swapped in by the phone block; the full label stays in the a11y tree. */
.col-label-short {
  display: none;
}

.sort-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.sort-btn:hover {
  color: var(--accent-deep);
}

.sort-btn.is-active {
  color: var(--accent-deep);
}

.sort-arrow {
  font-size: 0.7em;
  opacity: 0.65;
}

.sort-btn.is-active .sort-arrow {
  opacity: 1;
}

.row-toggle {
  width: 1.5rem;
  height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: #fff;
  color: var(--ink-soft);
  font: inherit;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.row-toggle:hover {
  border-color: var(--accent);
  color: var(--accent-deep);
}

.row-toggle[aria-expanded="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

/* Secondary affordance: the cells expand on their own, and this opens the whole
   response. A chevron that turns says which of the two states the row is in. */
.row-toggle-chevron {
  display: block;
  font-size: 1.05em;
  line-height: 1;
  transition: transform 0.15s ease;
}

.row-toggle[aria-expanded="true"] .row-toggle-chevron {
  transform: rotate(90deg);
}

.sheet-detail td {
  background: #f8fafb;
  padding: 0.85rem 0.9rem 1rem;
  border-bottom: 2px solid var(--line-strong);
}

/* The detail cell spans the full 118rem sheet, so its content sticks to the
   left edge of the scroll port and stays readable without scrolling back. */
.sheet-detail .detail-body {
  position: sticky;
  left: 0;
  width: min(100%, calc(100vw - 5rem));
  max-width: 66rem;
}

.sheet-detail .detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 0.6rem;
}

.sheet-detail .detail-heading {
  margin: 0.75rem 0 0.35rem;
  font-size: 0.95rem;
}

.sheet-detail .prose-block {
  max-height: 22rem;
  background: #fff;
}

.sheet-empty {
  padding: 1.5rem;
  text-align: center;
  color: var(--muted);
}

.sheet .col-toggle {
  /* Sized from the chevron button, which grows on a touch screen, rather than
     from the header text, which is screen-reader only. */
  width: 2.6rem;
  padding-inline: 0.25rem;
}
.sheet .col-system {
  width: 7.5rem;
}
.sheet .col-qid {
  /* Wide enough for the header "Question ID" and its sort arrow to stay on one
     line; the ids themselves are four characters. */
  width: 6.2rem;
}
.sheet .col-cat {
  width: 9rem;
}
/* Holds "Grounded" and its sort arrow, not just the 1/0 below it. */
.sheet .col-bit {
  width: 5.6rem;
}
.sheet .col-meta {
  width: 10rem;
}
.sheet .col-time {
  width: 9rem;
}
.sheet .col-text {
  width: 17rem;
}

/* The sheet is far wider than any screen, so the two columns that say which
   response a row is — the system and the question id — hold the left edge while
   the rest scrolls under them. The `left` offsets are the running total of the
   column widths above, so any change to those widths has to be made in both
   places (see the phone block in the responsive section). */
.sheet .col-toggle,
.sheet .col-system,
.sheet .col-qid {
  position: sticky;
  background: #fff;
}

.sheet .col-toggle {
  left: 0;
}

.sheet .col-system {
  left: 2.6rem;
}

/* Last of the pinned columns, so it carries the rule that separates what is
   held in place from what is scrolling past. */
.sheet .col-qid {
  left: 10.1rem;
  box-shadow: 1px 0 0 var(--line-strong);
}

/* Header cells are pinned on both axes; the three corners have to sit above
   both the rest of the header row and the pinned body cells. */
.sheet thead th.col-toggle,
.sheet thead th.col-system,
.sheet thead th.col-qid {
  z-index: 3;
  background: #eef4f5;
}

.sheet tbody td.col-toggle,
.sheet tbody td.col-system,
.sheet tbody td.col-qid {
  z-index: 1;
}

/* ---------- responsive ----------

   The blocks below run widest first, so a narrower one may override the one
   above it: 900 (stack the two answer columns) → 700 (filters lose their label
   gutter, wide tables gain a scroll hint) → 620 (phone: finger-sized controls,
   the comparison table becomes cards) → 480 (phone portrait: the bar chart puts
   each track on its own line) → 380 (the narrowest phones). Finger-sized
   controls also have a pointer query of their own, and a short viewport — a
   phone held sideways — has a height query, both after the width blocks.  */

@media (max-width: 900px) {
  .response-columns {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
  }

  .response-scores {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the two blocks no longer need to match heights, and a full-height
     answer would push the sources off the screen. */
  .response-col .prose-block,
  .response-col .prose-block.tall {
    min-height: 0;
    max-height: min(30rem, 55vh);
  }

  .outcome-pair {
    flex: 1 1 100%;
  }

  .outcome-pair .outcome {
    flex: 1 1 8rem;
  }
}

/* Finger-sized controls. Keyed on the pointer as well as the width, because a
   phone held sideways is about 740px across and would otherwise be handed the
   desktop's 26px chips and 35px nav links. */
@media (max-width: 620px), (pointer: coarse) {
  .brand {
    min-height: 2.75rem;
  }

  .nav a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0 0.72rem;
  }

  /* A chip that is a link is an action, so it gets the 44px box; the chips that
     only label a card stay the size of their text. */
  .chip-row a.chip,
  .sheet-detail .detail-head a.chip {
    min-height: 2.75rem;
    padding-inline: 0.7rem;
  }

  .footer-links a,
  .back-link {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
  }

  .filter-input {
    min-height: 2.75rem;
    /* iOS zooms the page in on any field whose text is smaller than this, and
       leaves the reader scrolled sideways afterwards. */
    font-size: 1rem;
  }

  /* The filter chips are the one control kept under 44px: at 44 the outcome,
     system, and category rows would fill a phone screen on their own, and the
     whole point of them is that the reader sees the full set at once. */
  .pill {
    min-height: 2.5rem;
    padding: 0.3rem 0.7rem;
    font-size: 0.86rem;
  }

  .listbox-button {
    min-height: 2.75rem;
  }

  .listbox-option {
    min-height: 2.5rem;
    align-items: center;
    padding: 0.4rem 0.5rem;
  }

  .provider-tabs button,
  .provider-tabs a,
  button.hbar-name {
    min-height: 2.75rem;
  }

  .pager-btn,
  .pager-num {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  .pager.is-compact .pager-btn {
    min-width: 2.5rem;
    min-height: 2.5rem;
  }

  .expandable-toggle,
  .reset-link,
  .sheet-download,
  .sort-btn {
    min-height: 2.25rem;
    padding-block: 0.35rem;
  }

  /* The whole header cell sorts, not just the words in it. */
  .sort-btn {
    width: 100%;
  }

  .row-toggle {
    width: 1.9rem;
    height: 2.5rem;
  }
}

@media (max-width: 700px) {
  /* Below about 709px the 40rem heatmap no longer fits its panel. */
  .scroll-hint {
    display: block;
  }

  /* No room for a label gutter beside wrapping chips: the label goes above its
     control and the chips use the full width of the panel. */
  .filter-field {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.25rem;
  }

  .filter-label {
    padding-top: 0;
  }

  .filter-bar {
    padding: 0.7rem 0.75rem 0.75rem;
  }

  .listbox {
    max-width: none;
  }

  .sheet-detail .prose-block {
    max-height: 16rem;
  }
}

@media (max-width: 620px) {
  /* Narrow screens tighten the gutter; the panels and the question view's
     headings both read it from the variable so they cannot drift apart. */
  :root {
    --panel-pad: 0.85rem;
  }

  /* ---- header ---- */

  .header-inner {
    padding: 0.55rem 0;
    gap: 0.4rem 1rem;
  }

  .brand {
    flex: 1 1 100%;
    gap: 0.6rem;
    min-height: 2.75rem;
  }

  .brand-mark {
    width: 2.1rem;
    height: 2.1rem;
  }

  .brand-title {
    font-size: 1rem;
  }

  /* The four routes get their own row and each becomes a 44px target, which is
     what the sticky header costs on a phone: one row of real buttons. */
  .nav {
    justify-content: flex-start;
    flex: 1 1 100%;
    gap: 0.3rem;
  }

  .nav a {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    padding: 0 0.72rem;
    font-size: 0.9rem;
  }

  .panel {
    padding-block: 0.9rem 1rem;
  }

  .filter-input {
    max-width: none;
  }

  /* First and last page. Dropping them is what lets the row hold prev, the page
     numbers, and next on one line; page 1 and the last page are already in that
     number list, and Home and End still work from the keyboard. */
  .pager-btn.is-edge {
    display: none;
  }

  /* Word labels would wrap the pager onto four lines on a phone; the arrow
     glyphs plus the aria-labels carry the same meaning. */
  .pager-word {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .pager-hint {
    display: none;
  }

  /* ---- charts ---- */

  /* Stack the system name above its own bars instead of squeezing a label
     column that would clip the longer names. Source order is label, value,
     track, and grid fills forward only, so the columns follow that order. */
  .hbar-chart {
    grid-template-columns: 5.4rem 3.1rem minmax(3rem, 1fr);
    gap: 0.25rem 0.5rem;
  }

  .hbar-name,
  .hbar-chart.pairs .hbar-name {
    grid-column: 1 / -1;
    grid-row: auto;
    margin-top: 0.6rem;
  }

  .hbar-chart > .hbar-name:first-child {
    margin-top: 0;
  }

  .hbar-label {
    grid-column: 1;
  }

  .hbar-value {
    grid-column: 2;
  }

  .hbar-track,
  .hbar-axis,
  .hbar-direction {
    grid-column: 3;
  }

  .hbar-chart.is-single {
    grid-template-columns: 7.4rem minmax(3rem, 1fr);
  }

  .hbar-chart.is-single .hbar-value {
    grid-column: 1;
    text-align: left;
  }

  .hbar-chart.is-single .hbar-track,
  .hbar-chart.is-single .hbar-axis,
  .hbar-chart.is-single .hbar-direction {
    grid-column: 2;
  }

  /* ---- comparison table ---- */

  /* Six columns of rates are off the right edge of a phone, so each row becomes
     a card: system on the first line, then one labelled line per measure. The
     inline bar is dropped — the charts in the panels above already draw it —
     which leaves the rate and its Wilson interval. */
  .leaderboard-table {
    display: block;
    min-width: 0;
    font-size: 0.92rem;
  }

  .leaderboard-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .leaderboard-table tbody {
    display: grid;
    gap: 0.5rem;
  }

  /* System on the first line, the measures side by side on the second, the
     sample size on the third. */
  .leaderboard-table tbody tr {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.4rem 0.5rem;
    padding: 0.6rem 0.7rem 0.65rem;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: #fcfdfd;
  }

  .leaderboard-table tbody td,
  .leaderboard-table tbody tr:last-child td {
    padding: 0;
    border-bottom: 0;
  }

  .leaderboard-table tbody td.cell-provider {
    grid-area: 1 / 1 / 2 / -1;
    font-size: 1rem;
  }

  .leaderboard-table tbody td.cell-metric {
    grid-row: 2;
    display: grid;
    padding-top: 0.3rem;
    border-top: 1px dotted var(--line-strong);
  }

  .cell-metric::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 0.72rem;
    font-weight: 700;
  }

  .cell-metric .metric-value {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
  }

  .cell-metric .metric-sub {
    font-size: 0.72rem;
  }

  /* The panel above this one already draws the bars, with the intervals. */
  .cell-metric .bar-track {
    display: none;
  }

  .leaderboard-table tbody td.cell-n {
    grid-row: 3;
    grid-column: 1 / -1;
    display: flex;
    align-items: baseline;
    gap: 0.3rem;
    padding-top: 0.3rem;
    border-top: 1px dotted var(--line-strong);
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 600;
  }

  .cell-n::before {
    content: attr(data-label) " =";
  }

  /* ---- category heatmap ---- */

  .heat-table {
    min-width: 25rem;
    border-spacing: 2px;
    font-size: 0.8rem;
  }

  .heat-table th[scope="row"] {
    padding: 0.4rem 0.35rem 0.4rem 0;
    font-size: 0.78rem;
  }

  .heat-cell {
    padding: 0.4rem 0.15rem;
  }

  /* ---- responses sheet ---- */

  /* Narrower columns all round, so the whole sheet is fewer swipes wide, and a
     header that may wrap rather than run into its neighbour. */
  .sheet {
    min-width: 90.2rem;
    font-size: 0.82rem;
  }

  .sheet thead th {
    padding: 0.4rem 0.45rem;
    white-space: normal;
    line-height: 1.3;
  }

  .sheet tbody td {
    padding: 0.45rem;
  }

  .sheet .col-toggle {
    width: 2.5rem;
  }

  .sheet .col-system {
    width: 5.6rem;
    left: 2.5rem;
  }

  /* Holds the abbreviated header and its sort arrow. */
  .sheet .col-qid {
    width: 3.6rem;
    left: 8.1rem;
  }

  .sheet .col-cat {
    width: 6.5rem;
  }

  .sheet .col-bit {
    width: 4rem;
  }

  .sheet .col-text {
    width: 12rem;
  }

  .sheet .col-meta {
    width: 7.5rem;
  }

  .sheet .col-time {
    width: 6.5rem;
  }

  /* Pinned to a 5.6rem column, the mark keeps its line and the name wraps under
     it rather than being broken mid-word. */
  .sheet .col-system .provider-name {
    flex-wrap: wrap;
    row-gap: 0.1rem;
  }

  .col-label-full {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .col-label-short {
    display: inline;
  }

  .sheet-wrap {
    max-height: min(30rem, 68vh);
  }

  /* ---- question detail ---- */

  /* A phone has room for the pair of grade chips only if they may shrink. */
  .grade-chips {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    flex: 1 1 100%;
  }
}

@media (max-width: 480px) {
  /* One phone-wide track per measure. A 5.4rem label column would leave the bar
     about 170px, which is not enough for a Wilson interval to read as an
     interval, so the label and the rate share the line above and the track gets
     the full width of the panel. */
  .hbar-chart {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.1rem 0.6rem;
  }

  .hbar-label {
    grid-column: 1;
    font-size: 0.8rem;
  }

  .hbar-value {
    grid-column: 2;
  }

  .hbar-track,
  .hbar-axis,
  .hbar-direction {
    grid-column: 1 / -1;
  }

  /* The stacked layout puts the cue under a full-width axis, where it has room
     for the words and the arrow on one line. */
  .hbar-direction {
    margin-top: 0.1rem;
    font-size: 0.74rem;
  }

  /* The track sits below the label and rate it belongs to, so it keeps a hair's
     space above it and a clear one below, or a reader cannot tell which of two
     measures a bar is drawn for. */
  .hbar-track {
    height: 0.85rem;
    margin-bottom: 0.5rem;
  }

  .hbar-ci {
    height: 0.72rem;
  }

  .hbar-name,
  .hbar-chart.pairs .hbar-name {
    margin-top: 0.85rem;
  }

  /* The binary chart's value is a 1/0 chip rather than a percentage, and it
     reads better beside its label than under an empty track. */
  .hbar-chart.binary .hbar-track {
    height: 0.6rem;
  }
}

@media (max-width: 380px) {
  /* Two grade chips side by side would break "Grounded" mid-word here. */
  .grade-chips {
    grid-template-columns: minmax(0, 1fr);
  }

  .grade-chip-name {
    white-space: normal;
  }

  .nav a {
    padding: 0 0.6rem;
    font-size: 0.86rem;
  }

  .heat-table {
    min-width: 23rem;
  }

  /* A third of this card is narrower than the word "Groundedness", so the three
     measures give up the matrix and take a labelled line each. */
  .leaderboard-table tbody td.cell-metric {
    grid-row: auto;
    grid-column: 1 / -1;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: baseline;
    gap: 0 0.5rem;
  }

  .cell-metric::before {
    font-size: 0.76rem;
  }

  .cell-metric .metric-value {
    font-size: 0.92rem;
  }

  .cell-metric .metric-sub {
    min-width: 4rem;
    text-align: right;
  }

  .leaderboard-table tbody td.cell-n {
    grid-row: auto;
  }
}

/* A phone held sideways: about 360px of height, most of which the sticky header
   and a 30rem scroll box would take between them. */
@media (max-height: 520px) and (orientation: landscape) {
  .site-header {
    position: static;
  }

  .main {
    padding-top: 1rem;
    min-height: 0;
  }

  .sheet-wrap {
    max-height: min(24rem, 72vh);
  }

  .prose-block,
  .response-col .prose-block,
  .response-col .prose-block.tall,
  .sheet-detail .prose-block {
    max-height: 70vh;
  }

  .expandable.in-cell.is-open .expandable-text,
  .expandable.in-cell.is-open .expandable-rich {
    max-height: 60vh;
  }

  .listbox-list {
    max-height: 60vh;
  }
}

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

.headline-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
  gap: 0.75rem;
}

.provider-dash .dash-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem 0.45rem;
  width: 100%;
  margin: 0.85rem 0 0.7rem;
}

.provider-dash .headline-metrics,
.headline-metrics.is-compact {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.65rem;
  align-items: stretch;
}

#provider-dash-slot:not(:empty) {
  margin-bottom: 1rem;
}

@media (max-width: 960px) {
  .provider-dash .provider-switch {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .provider-dash .headline-metrics,
  .headline-metrics.is-compact {
    grid-template-columns: repeat(5, minmax(8.75rem, 1fr));
    overflow-x: auto;
  }
}

.headline-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.85rem 0.95rem 0.95rem;
  box-shadow: var(--shadow);
}

.headline-card .label {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
}

.headline-card .value {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--font-display);
  font-size: 1.15rem;
  line-height: 1.25;
}

.headline-card .sub {
  display: block;
  margin-top: 0.2rem;
  color: var(--muted);
  font-size: 0.82rem;
}

.headline-card.metric-hall { border-top: 4px solid #8c4033; }
.headline-card.metric-incorr { border-top: 4px solid #2f5a7e; }
.headline-card.metric-misg { border-top: 4px solid #93b4c9; }
.headline-card.metric-inc { border-top: 4px solid #c9a66b; }
.headline-card.metric-sub { border-top: 4px solid #4e7a63; }

.overlap-note,
.overlap-grid + .panel-note {
  max-width: 46rem;
}

.overlap-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
  margin: 0.85rem 0 0.55rem;
}

@media (min-width: 560px) {
  .overlap-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.95rem 1.1rem;
  }
}

.overlap-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.15rem 1.15rem;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.overlap-card .label {
  display: block;
  margin-bottom: 0.55rem;
  color: var(--ink-soft);
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.35;
}

.overlap-card .value {
  display: block;
  font-family: var(--font-display);
  font-size: 2.15rem;
  font-weight: 700;
  line-height: 1.05;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink);
}

.overlap-card .sub {
  display: block;
  margin-top: 0.28rem;
  color: var(--muted);
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
}

.overlap-card.is-h-yes {
  border-top: 4px solid #8c4033;
}

.overlap-card.is-h-no {
  border-top: 4px solid #4e7a63;
}

.overlap-card.is-h-yes.is-s-yes {
  background: #f7eeeb;
}

.overlap-card.is-h-no.is-s-yes {
  background: #eef5f1;
}

.diag-list {
  display: grid;
  gap: 0.35rem;
  margin: 0.4rem 0 1rem;
}

.diag-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 2.4rem minmax(4rem, 12rem);
  gap: 0.55rem;
  align-items: center;
}

.diag-label {
  font-size: 0.9rem;
}

.diag-count {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.diag-track {
  display: block;
  height: 0.55rem;
  background: #e7eef3;
  border-radius: 99px;
  overflow: hidden;
}

.diag-fill {
  display: block;
  height: 100%;
  background: #2f5a7e;
}

.subhead {
  margin: 1.2rem 0 0.45rem;
  font-size: 1.05rem;
}

.grade-chips.is-five {
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}

.outcome-pair {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.bar-fill.hall { background: #8c4033; }
.bar-fill.incorr { background: #2f5a7e; }
.bar-fill.misg { background: #93b4c9; }
.bar-fill.inc { background: #c9a66b; }
.bar-fill.sub { background: #4e7a63; }

.filter-bar {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
