:root {
  --bg: #ffffff;
  --bg-alt: #f5f7fa;
  --fg: #1a1d21;
  --fg-muted: #5b6470;
  --border: #d8dee5;
  --accent: #2b6cb0;
  --ok: #2f855a;
  --warn: #b7791f;
  --bad: #c53030;
  --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  --radius: 8px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #14171a;
    --bg-alt: #1c2126;
    --fg: #e6e9ec;
    --fg-muted: #9aa4b0;
    --border: #2b323a;
    --accent: #63b3ed;
    --ok: #68d391;
    --warn: #f6ad55;
    --bad: #fc8181;
    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  }
}

* {
  box-sizing: border-box;
}

html {
  /* Full-bleed sections use 100vw, which includes a classic scrollbar's
     width; clip so that never turns into a horizontal page scroll. */
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--fg);
  line-height: 1.5;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--accent);
  color: #fff;
  padding: 0.5rem 1rem;
  z-index: 10;
}
.skip-link:focus {
  left: 0;
}

.site-header {
  padding: 2rem 1.5rem 1rem;
  max-width: 60rem;
  margin: 0 auto;
}
.site-header h1 {
  margin: 0 0 0.25rem;
  font-size: 1.75rem;
}
.site-title-link {
  color: inherit;
  text-decoration: none;
}
.tagline {
  color: var(--fg-muted);
  margin: 0;
}

/* --- Header project switcher (issue #171) --------------------------------
   A pure-markup `<details>`/`<summary>` dropdown -- works with no JS, no
   polyfill, same "progressive, not polyfilled" stance the collapsible
   page sections (issue #144) and the chart-expand dialog (issue #156)
   already take. Hidden entirely (no markup at all) on a single-project
   build, since `base.html` only renders it when more than one project is
   available. */
.site-header-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.project-switcher {
  position: relative;
  font-size: 0.9rem;
}
.project-switcher > summary {
  cursor: pointer;
  list-style: none;
  color: var(--fg-muted);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.35rem 0.75rem;
  background: var(--bg-alt);
  user-select: none;
}
.project-switcher > summary::-webkit-details-marker {
  display: none;
}
.project-switcher[open] > summary {
  color: var(--fg);
}
.project-switcher ul {
  position: absolute;
  right: 0;
  top: calc(100% + 0.35rem);
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  min-width: 12rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--card-shadow);
  z-index: 5;
}
.project-switcher li {
  margin: 0;
}
.project-switcher a {
  display: block;
  padding: 0.4rem 0.6rem;
  border-radius: calc(var(--radius) - 2px);
  color: var(--fg);
  text-decoration: none;
  white-space: nowrap;
}
.project-switcher a:hover {
  background: var(--bg-alt);
}
.project-switcher a[aria-current="page"] {
  color: var(--accent);
  font-weight: 600;
}

@media (max-width: 480px) {
  /* At narrow widths `.site-header-row` wraps (flex-wrap above) and the
     switcher button ends up flush against the page's own left edge, not
     the right -- anchoring the dropdown from its own `right: 0` then
     pushes the (wider) list mostly off-screen to the left, clipped by
     `html`'s own `overflow-x: clip`. Anchoring from `left: 0` instead
     keeps it growing rightward, inside the viewport. */
  .project-switcher ul {
    left: 0;
    right: auto;
    min-width: 10rem;
    max-width: calc(100vw - 2rem);
  }
}

.site-nav {
  max-width: 60rem;
  margin: 0 auto 1rem;
  padding: 0 1.5rem;
  display: flex;
  gap: 1.25rem;
  border-bottom: 1px solid var(--border);
  /* A narrow viewport (e.g. 390px) can't always fit all four tabs at full
     size without wrapping; scroll horizontally within the nav itself
     rather than letting it (or the page) overflow (issue #34). */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.site-nav a {
  display: inline-block;
  flex: none;
  padding: 0.6rem 0.1rem;
  color: var(--fg-muted);
  text-decoration: none;
  font-weight: 600;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.site-nav a:hover {
  color: var(--fg);
}
.site-nav a[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

@media (max-width: 480px) {
  .site-nav {
    gap: 0.85rem;
    padding: 0 1rem;
  }
  .site-header {
    padding: 1.5rem 1rem 1rem;
  }
  main {
    padding: 0 1rem 3rem;
  }
}

.page-intro {
  margin: 1.5rem 0;
  color: var(--fg-muted);
}

.banner {
  max-width: 60rem;
  margin: 0 auto 1rem;
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius);
}
.banner--stale {
  background: var(--bg-alt);
  border: 1px solid var(--warn);
  color: var(--fg);
}

.source-badges {
  max-width: 60rem;
  margin: 0 auto 1rem;
  padding: 0 1.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.badge {
  display: inline-block;
  font-size: 0.75rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--bg-alt);
}
.badge--ok {
  border-color: var(--ok);
  color: var(--ok);
}
.badge--stale {
  border-color: var(--warn);
  color: var(--warn);
}
.badge--failed {
  border-color: var(--bad);
  color: var(--bad);
}

.badge--tier {
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.badge--tier-established {
  border-color: var(--ok);
  color: var(--ok);
}
.badge--tier-proxy {
  border-color: var(--accent);
  color: var(--accent);
}
.badge--tier-experimental {
  border-color: var(--warn);
  color: var(--warn);
}
.badge--tier-classified {
  border-color: var(--bad);
  color: var(--bad);
}

main {
  max-width: 60rem;
  margin: 0 auto;
  padding: 0 1.5rem 3rem;
}

.dimension {
  margin-bottom: 2.5rem;
}
.dimension h2 {
  text-transform: capitalize;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}

.card {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--card-shadow);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.card-header h3,
.card-header h4 {
  margin: 0;
  font-size: 1rem;
}

.card-value {
  margin: 0.5rem 0 0.25rem;
}
.value {
  font-size: 1.75rem;
  font-weight: 600;
}
.value--insufficient {
  font-size: 1rem;
  font-weight: 500;
  color: var(--fg-muted);
}
.value-period {
  display: block;
  font-size: 0.8rem;
  color: var(--fg-muted);
}

.badge--backfill-pending {
  border-color: var(--warn);
  color: var(--warn);
  margin-left: 0.4rem;
}

/* Per-card staleness badge (issue #86, ARCHITECTURE.md §7.3) -- reuses the
   header pill's badge--ok/--stale/--failed color scale so a card's own
   badge reads consistently with the site-wide source pills above it. */
.card-staleness {
  margin: 0 0 0.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.card-staleness .badge {
  white-space: normal;
  text-align: left;
}

.card-status {
  font-size: 0.8rem;
  color: var(--fg-muted);
  margin: 0.25rem 0;
}

.chart {
  display: block;
  width: 100%;
  min-height: 160px;
  margin: 0.5rem 0;
}

/* --- Chart time-window toggle + low-n legend note (issue #28) ---------- */

.chart-window-bar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 0 0 0.5rem;
}
.chart-window-hint {
  color: var(--fg-muted);
  font-size: 0.85rem;
}
.chart-window-toggle {
  border: 1px solid var(--accent);
  background: transparent;
  color: var(--accent);
  border-radius: 6px;
  padding: 0.2rem 0.6rem;
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}
.chart-window-toggle[aria-pressed="true"] {
  background: var(--accent);
  color: var(--bg);
}
.chart-legend-note {
  color: var(--fg-muted);
  font-size: 0.8rem;
  margin: 0 0 1.5rem;
}

.card-links {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
}
.card-links a {
  color: var(--accent);
}

/* "Based on" prior-art line (issue #134): same muted treatment as
   .card-status -- informational, not a verdict or a badge. */
.card-prior-art {
  font-size: 0.8rem;
  color: var(--fg-muted);
  margin: 0.25rem 0;
}
.card-prior-art a {
  color: var(--accent);
}

/* Prominent cross-link button (issue #124): "Explore individual threads"
   on /conversations/ -> /conversations/threads/. Deliberately a filled
   pill, not a plain inline link, so it reads as a clear call to action
   next to the section header and after the summary table. */
.explorer-cta {
  margin: 0.75rem 0 1.25rem;
}
.btn-cta {
  display: inline-block;
  background: var(--accent);
  color: var(--bg);
  border-radius: 6px;
  padding: 0.45rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}
.btn-cta:hover,
.btn-cta:focus-visible {
  opacity: 0.85;
}

/* --- Home page: CHAOSS Starter Project Health block (issue #136,
   DECISIONS.md D29 -- replaces the retired D20 composite score). Reuses
   .card/.card-grid/.card-value from the metric-card styles below; these
   rules are the small CHAOSS-block-specific additions on top. */

.chaoss-starter-section {
  margin: 1.5rem 0;
}
.chaoss-starter-section h2 {
  margin: 0 0 0.25rem;
  font-size: 1.1rem;
}
.chaoss-series {
  margin: 0.75rem 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}
.chaoss-series:first-of-type {
  border-top: none;
  padding-top: 0;
}
.chaoss-series-label {
  margin: 0 0 0.25rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.chart--small {
  height: 110px;
}

/* --- Home page: one summary card per top-level page (D13) -------------- */

.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
  margin: 1.5rem 0 3rem;
}

.card--summary .card-header h2 {
  margin: 0;
  font-size: 1.15rem;
}
.card--summary .card-header h2 a {
  color: var(--fg);
  text-decoration: none;
}
.card--summary .card-header h2 a:hover {
  color: var(--accent);
}

.card-summary-blurb {
  color: var(--fg-muted);
  font-size: 0.9rem;
  margin: 0.5rem 0;
}

.headline-metrics {
  list-style: none;
  margin: 0.75rem 0;
  padding: 0;
}
.headline-metrics li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.35rem 0;
  border-top: 1px solid var(--border);
}
.headline-metrics li:first-child {
  border-top: none;
}
.headline-metric-name {
  font-size: 0.85rem;
  color: var(--fg-muted);
}
.headline-metric-value {
  font-weight: 600;
}
.headline-metric-value--insufficient {
  font-weight: 500;
  font-size: 0.85rem;
  color: var(--fg-muted);
}
.headline-metric-period {
  font-size: 0.75rem;
  color: var(--fg-muted);
}

.card-more {
  font-size: 0.8rem;
  color: var(--fg-muted);
  margin: 0.25rem 0;
}

.card-empty-state {
  color: var(--fg-muted);
  font-size: 0.9rem;
  margin: 0.75rem 0;
}

/* --- Conversations / Governance: empty state + "what's coming" --------- */

.empty-state {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.5rem;
  margin-bottom: 2rem;
}
.empty-state h2 {
  margin-top: 0;
}

.whats-coming h2 {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}

.phase-card {
  margin-bottom: 1.5rem;
}
.phase-card h3 {
  margin-bottom: 0.35rem;
}
.phase-card p {
  color: var(--fg-muted);
}

.site-footer {
  max-width: 60rem;
  margin: 0 auto;
  padding: 1.5rem;
  color: var(--fg-muted);
  font-size: 0.85rem;
  border-top: 1px solid var(--border);
}
.site-footer a {
  color: var(--accent);
}

/* --- Governance: backfill banner, trends, commit history table ---------- */
/* (issue #37, D14/D15; rebuilt fact-only by issue #97) -------------------- */

.governance-backfill,
.governance-trends,
.governance-commits,
.governance-references {
  margin: 2rem 0;
}
.governance-backfill h2,
.governance-trends h2,
.governance-commits h2,
.governance-references h2 {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}
.governance-note {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  font-size: 0.9rem;
}
/* Methodology page's data-branch layout block (issue #160) -- wraps rather
   than overflowing horizontally at narrow (390px) viewport widths. */
.code-block {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  font-size: 0.85rem;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.governance-reference-list {
  list-style: none;
  padding: 0;
  margin: 0 0 1rem;
}
.governance-reference-list li {
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--border);
}
.governance-reference-list a {
  color: var(--accent);
}

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

.gov-toggle {
  display: inline-flex !important;
  flex-direction: row !important;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  margin-right: 1rem;
}

.gov-commits-table td {
  font-size: 0.85rem;
  vertical-align: top;
}
/* 11 columns: tighter cell padding than the other security tables so the
   whole commit history fits a ~1366px window. */
.gov-commits-table th,
.gov-commits-table td {
  padding: 0.45rem 0.5rem;
}
.gov-commits-table thead th {
  white-space: normal;
  vertical-align: bottom;
  line-height: 1.25;
}
.gov-commits-table .gov-nowrap,
.gov-commits-table a.gov-nowrap,
.gov-commits-table td code {
  white-space: nowrap;
}
.gov-author {
  color: var(--fg-muted);
  font-size: 0.8rem;
}

.gov-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 1rem 0;
}
.gov-filters label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.8rem;
  color: var(--fg-muted);
}
.gov-filters select,
.gov-filters input[type="text"],
.gov-filters input[type="date"] {
  padding: 0.35rem 0.5rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
  font: inherit;
}

.gov-status {
  color: var(--fg-muted);
  font-size: 0.85rem;
}

.gov-table-wrap {
  overflow-x: auto;
}
.gov-commits-table {
  width: 100%;
  min-width: 60rem;
}

/* The commit history section breaks out of the 60rem reading column and
   uses the full window width, so the whole table is visible at once. */
.governance-commits {
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-left: 1rem;
  padding-right: 1rem;
}

/* Sortable column headers (keyboard + aria-sort, issue #97). */
.gov-commits-table th[data-gov-sort] {
  cursor: pointer;
  user-select: none;
  position: relative;
  padding-right: 1.25rem;
}
.gov-commits-table th[data-gov-sort]:hover,
.gov-commits-table th[data-gov-sort]:focus-visible {
  color: var(--accent);
}
.gov-commits-table th[data-gov-sort]::after {
  content: "";
  position: absolute;
  right: 0.4rem;
  opacity: 0.4;
}
.gov-commits-table th[aria-sort="ascending"]::after {
  content: "\2191";
  opacity: 1;
}
.gov-commits-table th[aria-sort="descending"]::after {
  content: "\2193";
  opacity: 1;
}

/* Thread explorer (issue #122, D27): same sortable-header treatment as the
   governance commit table, keyed off its own `data-threads-sort` attribute. */
.threads-table th[data-threads-sort] {
  cursor: pointer;
  user-select: none;
  position: relative;
  padding-right: 1.25rem;
}
.threads-table th[data-threads-sort]:hover,
.threads-table th[data-threads-sort]:focus-visible {
  color: var(--accent);
}
.threads-table th[data-threads-sort]::after {
  content: "";
  position: absolute;
  right: 0.4rem;
  opacity: 0.4;
}
.threads-table th[aria-sort="ascending"]::after {
  content: "\2191";
  opacity: 1;
}
.threads-table th[aria-sort="descending"]::after {
  content: "\2193";
  opacity: 1;
}
.thread-flag {
  display: inline-block;
  border: 1px solid var(--border);
  background: var(--bg-alt);
  border-radius: 4px;
  padding: 0.05rem 0.35rem;
  margin: 0 0.15rem 0.15rem 0;
  font-size: 0.75rem;
  white-space: nowrap;
}
.thread-nowrap {
  white-space: nowrap;
}

.gov-expand-cell {
  width: 2rem;
}
.gov-expand-btn {
  border: 1px solid var(--border);
  background: var(--bg-alt);
  color: var(--fg);
  border-radius: 4px;
  width: 1.5rem;
  height: 1.5rem;
  line-height: 1;
  cursor: pointer;
  font: inherit;
}
.gov-row-detail td {
  background: var(--bg-alt);
}
.gov-evidence-trail {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.25rem 1rem;
  margin: 0;
  font-size: 0.85rem;
}
.gov-evidence-trail dt {
  color: var(--fg-muted);
  font-weight: 600;
}
.gov-evidence-trail dd {
  margin: 0;
}

.gov-pagination {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.75rem;
  font-size: 0.85rem;
}
.gov-pagination button {
  border: 1px solid var(--border);
  background: var(--bg-alt);
  color: var(--fg);
  border-radius: 6px;
  padding: 0.25rem 0.75rem;
  cursor: pointer;
}
.gov-pagination button:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Mobile cards (design doc "Performance and mobile"): each row collapses to
   a labeled-line card instead of a horizontally-scrolling table. */
@media (max-width: 640px) {
  .gov-commits-table {
    min-width: 0;
  }
  .gov-commits-table thead {
    display: none;
  }
  .gov-commits-table,
  .gov-commits-table tbody,
  .gov-commits-table tr {
    display: block;
    width: 100%;
  }
  .gov-commits-table tr {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 0.75rem;
    padding: 0.5rem 0.75rem;
  }
  .gov-commits-table tr.gov-row-detail {
    border-top: none;
    margin-top: -0.75rem;
  }
  .gov-commits-table td {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 0.75rem;
    text-align: right;
    padding: 0.3rem 0;
    border-bottom: none;
  }
  .gov-commits-table td.gov-expand-cell {
    justify-content: flex-end;
    width: auto;
  }
  .gov-commits-table td[data-label]::before {
    content: attr(data-label);
    color: var(--fg-muted);
    font-weight: 600;
    text-align: left;
    margin-right: auto;
  }
}

/* --- Governance: Security section (OpenSSF Scorecard + advisories, #55) - */

.security-section {
  margin-top: 2.5rem;
}
.security-section h2 {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}
.security-subsection {
  margin: 1.5rem 0 2rem;
}
.security-meta {
  color: var(--fg-muted);
  font-size: 0.85rem;
  margin: 0.15rem 0 1rem;
}
.security-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  margin-bottom: 1rem;
}
.security-table th,
.security-table td {
  text-align: left;
  vertical-align: top;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
}
.security-table th {
  color: var(--fg-muted);
  font-weight: 600;
  white-space: nowrap;
}
.security-note {
  color: var(--fg-muted);
  font-size: 0.85rem;
  margin: 0.15rem 0 0;
}
.security-history {
  font-size: 0.85rem;
  color: var(--fg-muted);
}
.security-by-year {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  list-style: none;
  padding: 0;
  margin: 0 0 1rem;
  font-size: 0.9rem;
}

/* Security tables scroll inside their own box on narrow screens instead of
   widening the page (390px phones; found with the full-width commit table). */
@media (max-width: 640px) {
  .security-section .security-table {
    display: block;
    overflow-x: auto;
    max-width: 100%;
  }
}

/* --- Conversation patterns (issue #118, D26) ---------------------------- */

.banner--preliminary {
  background: var(--bg-alt);
  border: 1px solid var(--warn);
  color: var(--fg);
  max-width: none;
  margin: 1rem 0 1.5rem;
}
.banner--preliminary a {
  color: var(--accent);
}

.badge--preliminary {
  border-color: var(--warn);
  color: var(--warn);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.conversation-patterns h3,
.conversation-patterns h4 {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.35rem;
  margin-top: 2rem;
}
.conversation-patterns h5 {
  margin: 1rem 0 0.5rem;
  color: var(--fg-muted);
}

.conv-patterns-jump {
  font-size: 0.9rem;
  margin: 0.5rem 0 1.5rem;
}
.conv-patterns-jump a {
  color: var(--accent);
}

/* Full-width, horizontally-scrollable tables on narrow screens -- the
   per-label tables here can run to 12+ data columns (one per message-level
   label), well beyond a 390px phone's viewport, same reasoning as the
   Security section's own `.security-table` scroll wrapper above. */
.conv-patterns-table-wrap {
  overflow-x: auto;
  max-width: 100%;
  margin-bottom: 1.5rem;
}
.conv-patterns-table {
  min-width: 40rem;
}
@media (max-width: 640px) {
  .conv-patterns-table {
    min-width: 32rem;
  }
}

.conv-facet-chart {
  min-height: 260px;
}

/* --- Year-over-year grouped-bar chart controls + chart (issue #120) ---- */

.conv-yoy-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 1rem 0;
}
.conv-yoy-controls label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.8rem;
  color: var(--fg-muted);
}
.conv-yoy-controls select {
  padding: 0.35rem 0.5rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
  font: inherit;
}

/* Issue #133: small multiples (one mini-chart per label, computed/sized by
   `app.js`'s `applyFacetColumns`) wrap to however many columns fit the
   container instead of ever needing the horizontal scroll this used to
   rely on (issue #120's original grouped-bar design) -- `overflow-x: auto`
   stays only as a defensive fallback, never the primary mechanism. */
.conv-yoy-chart-wrap {
  overflow-x: auto;
  max-width: 100%;
  margin-bottom: 1rem;
}
.conv-yoy-chart {
  min-height: 160px;
}

/* --- Thread explorer charts (issue #124) -------------------------------- */

.thread-explorer-charts {
  margin: 1rem 0 2rem;
}
.thread-chart-block {
  margin-bottom: 1.5rem;
}
.thread-chart-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}
/* Issue #133: taller floor than before -- the color legend moved below
   the plot (see `_year_outcome_chart_spec`'s own docstring) needs its own
   vertical room now instead of sharing a row with the plot to its right. */
.thread-outcome-chart {
  min-height: 340px;
}
/* Issue #133: see `.conv-yoy-chart-wrap`'s comment -- same small-multiples
   wrap-not-scroll fix, applied to this chart too (reviewer feedback
   covered both #120's and #124's label charts). */
.thread-label-chart-wrap {
  overflow-x: auto;
  max-width: 100%;
}
.thread-label-chart {
  min-height: 160px;
}
@media (max-width: 640px) {
  .thread-chart-toolbar {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* --- Collapsible page sections (issue #144) ---------------------------- */

.page-section-nav {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  padding: 0.6rem 0;
  margin-bottom: 1.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  font-size: 0.85rem;
}
.page-section-nav-label {
  font-weight: 600;
  color: var(--fg-muted);
}
.page-section-nav a {
  color: var(--accent);
  text-decoration: none;
}
.page-section-nav a:hover {
  text-decoration: underline;
}
.page-section-nav-controls {
  margin-left: auto;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.page-section-expand-all,
.page-section-collapse-all {
  font-size: 0.8rem;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--bg-alt);
  color: var(--fg);
  cursor: pointer;
}

.page-section {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 1.25rem;
  background: var(--bg-alt);
  /* Every element this box contains (the summary row's sparklines, and
     every card/chart/table in the expanded body) must stay inside this
     border at any viewport width -- never force a horizontal page scroll. */
  overflow-x: hidden;
}
.page-section-summary {
  cursor: pointer;
  padding: 0.85rem 1rem;
  list-style: none;
}
.page-section-summary::-webkit-details-marker {
  display: none;
}
.page-section-summary-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem;
}
.page-section-title {
  font-size: 1.1rem;
  font-weight: 600;
}
.page-section-chaoss-link {
  font-size: 0.8rem;
  color: var(--fg-muted);
}
.page-section-body {
  padding: 0 1rem 1rem;
  border-top: 1px solid var(--border);
}
/* The body's own direct `.dimension`/section children keep their usual
   bottom margin, but the body itself already carries side/bottom padding
   above, so the last child's margin would otherwise double up. */
.page-section-body > :last-child {
  margin-bottom: 0;
}

.section-headline-metrics {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
}
.section-headline-metric {
  display: flex;
  flex-direction: column;
  min-width: 100px;
  max-width: 100%;
  flex: 1 1 130px;
}
.section-headline-metric-name {
  font-size: 0.75rem;
  color: var(--fg-muted);
}
.section-headline-metric-value {
  font-size: 1.15rem;
  font-weight: 600;
}
.section-headline-metric-value--insufficient {
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--fg-muted);
}
.section-headline-metric-period {
  font-size: 0.7rem;
  color: var(--fg-muted);
}
.chart--sparkline {
  width: 100%;
  display: block;
  min-height: 28px;
  height: 28px;
  margin: 0.15rem 0 0;
}

/* --- Tone over time (issue #153) ---------------------------------------
   Lives inside a `<details class="page-section">`'s always-visible
   `<summary>` (never its collapsible body), so it must stay visible and
   usable while the summary row itself keeps its own `cursor: pointer`
   click-to-toggle affordance -- `cursor: default` here, plus `app.js`'s
   `stopPropagation` guard on `.page-section-summary-extra`, keeps a click
   on the cutoff/mode selects or the chart from also collapsing the
   section underneath them. */
.page-section-summary-extra {
  cursor: default;
  margin-top: 0.75rem;
  max-width: 100%;
  overflow-x: hidden;
}
.conv-tone-mix-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}
.conv-tone-mix-title {
  font-size: 0.95rem;
  font-weight: 600;
}
.conv-tone-mix-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.conv-tone-mix-controls label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.8rem;
  color: var(--fg-muted);
}
.conv-tone-mix-controls select {
  padding: 0.3rem 0.45rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
  font: inherit;
}
.conv-tone-mix-chart {
  min-height: 220px;
  max-width: 100%;
  margin-bottom: 0.75rem;
}
@media (max-width: 480px) {
  .conv-tone-mix-chart {
    min-height: 180px;
  }
}

@media (max-width: 480px) {
  .page-section-nav-controls {
    margin-left: 0;
  }
  .page-section-summary {
    padding: 0.75rem 0.85rem;
  }
  .page-section-body {
    padding: 0 0.85rem 0.85rem;
  }
}

/* --- Peer context (issue #145, D30) -------------------------------------
   A plain, neutral banner -- never `.banner--stale`/`.banner--preliminary`'s
   warning-amber border, since the CHAOSS disclaimer it carries isn't a
   caveat about this project's own data, just a standing fact about what
   the page is (no targets, no ranking). */
.banner--neutral {
  background: var(--bg-alt);
  border: 1px solid var(--border);
  color: var(--fg);
  max-width: none;
  margin: 1rem 0 1.5rem;
}

.peer-table-row--cassandra {
  font-weight: 600;
}

/* --- Expand chart (issue #156) -------------------------------------------
   `.chart-shell` (`templates/_charts.html`) wraps exactly one chart `<div>`
   plus its own Expand button -- `position: relative` here is what lets
   the button sit absolutely in that one chart's own top-right corner
   rather than the page's. */
.chart-shell {
  position: relative;
}
.chart-expand-btn {
  position: absolute;
  top: 0.25rem;
  right: 0.25rem;
  z-index: 2;
  width: 1.75rem;
  height: 1.75rem;
  line-height: 1;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--fg-muted);
  font-size: 0.95rem;
  cursor: pointer;
}
.chart-expand-btn:hover,
.chart-expand-btn:focus-visible {
  color: var(--fg);
  border-color: var(--accent);
}

/* The dialog itself: ~90vw x 85vh on desktop, full-screen at <=640px
   (issue #156's own spec) -- `<dialog>` handles the backdrop, focus trap
   and Esc-to-close natively, so none of that is reimplemented here. */
/* `display` set only while open: an author `display` on a <dialog> overrides
   the browser's own hiding of a closed dialog, which left an empty box at
   the bottom of every page. */
.chart-expand-dialog:not([open]) {
  display: none;
}
.chart-expand-dialog[open] {
  display: flex;
}
.chart-expand-dialog {
  width: 90vw;
  height: 85vh;
  max-width: none;
  max-height: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--fg);
  padding: 1rem;
  flex-direction: column;
  gap: 0.5rem;
  /* A chart with many controls (tone-over-time's 7 series checkboxes
     plus mode/cutoff) or a tall legend can exceed this fixed height on a
     short viewport -- scroll the dialog itself rather than silently
     clipping the actions row/legend past its own bottom edge (verified:
     without this, the tone-mix legend was cut off at a 390x844 phone
     size). */
  overflow-y: auto;
}
.chart-expand-dialog::backdrop {
  background: rgba(0, 0, 0, 0.5);
}
.chart-expand-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.chart-expand-title {
  margin: 0;
  font-size: 1.1rem;
}
.chart-expand-close {
  border: none;
  background: transparent;
  color: var(--fg-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.25rem;
}
.chart-expand-close:hover,
.chart-expand-close:focus-visible {
  color: var(--fg);
}
.chart-expand-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0;
  padding: 0;
  border: none;
}
.chart-expand-control {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.85rem;
}
.chart-expand-control legend {
  font-size: 0.75rem;
  color: var(--fg-muted);
  padding: 0;
}
.chart-expand-control select,
.chart-expand-control input,
.chart-expand-param select,
.chart-expand-param input {
  font: inherit;
  padding: 0.2rem 0.3rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--fg);
}
.chart-expand-series-item {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-right: 0.5rem;
}
.chart-expand-presets {
  display: inline-flex;
  gap: 0.25rem;
}
.chart-expand-presets button {
  font-size: 0.75rem;
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--bg-alt);
  color: var(--fg);
  cursor: pointer;
}
.chart-expand-param {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.85rem;
}
/* Main chart + overview strip: one flex column, no internal gap -- the
   strip sits directly under the chart it's a miniature/brushable summary
   of (orchestrator review of PR #157). */
.chart-expand-chart-group {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.chart-expand-main {
  flex: 1 1 auto;
  min-height: 200px;
  width: 100%;
}
.chart-expand-overview {
  flex: none;
  height: 80px;
  width: 100%;
}
.chart-expand-overview[hidden] {
  display: none;
}
.chart-expand-actions {
  margin: 0;
  display: flex;
  gap: 0.5rem;
}
.chart-expand-actions button {
  font-size: 0.85rem;
  padding: 0.3rem 0.7rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg-alt);
  color: var(--fg);
  cursor: pointer;
}
.chart-expand-actions button:hover,
.chart-expand-actions button:focus-visible {
  border-color: var(--accent);
  color: var(--accent);
}

@media (max-width: 640px) {
  .chart-expand-dialog {
    width: 100vw;
    height: 100vh;
    max-width: 100vw;
    max-height: 100vh;
    border: none;
    border-radius: 0;
    inset: 0;
  }
}
