/*
 * L7 — public Research composition for MLB/NFL matchup slates and game detail.
 * This file owns route geometry. It consumes L2 roles and does not redefine tokens.
 */

body[data-ca-product="research"] {
  min-width: 0;
  overflow-x: clip;
}

.ca-public-page,
.ca-opening-desk {
  width: min(100%, var(--shell-max));
  margin: 0 auto;
  padding: var(--space-6) var(--shell-gutter) var(--space-9);
}

.ca-public-page__head,
.ca-opening-desk__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--space-6);
  padding: 0 0 var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
}

.ca-public-page__copy,
.ca-opening-desk__copy {
  min-width: 0;
}

.ca-public-page__eyebrow,
.ca-detail-eyebrow {
  margin: 0 0 var(--space-1);
  color: var(--text-accent);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.ca-public-page__title,
.ca-opening-desk__title {
  margin: 0;
  font-size: clamp(var(--type-28), 3vw, var(--type-32));
  line-height: 1;
}

.ca-public-page__lede,
.ca-opening-desk__lede {
  max-width: 720px;
  margin: var(--space-2) 0 0;
  color: var(--text-secondary);
}

.ca-public-page__links {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}

.ca-public-page__links a,
.ca-embedded-slate-head a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  font-weight: 700;
}

.ca-public-page__links a:hover,
.ca-embedded-slate-head a:hover {
  border-color: var(--border-accent);
  background: var(--accent-soft);
}

.ca-public-page__content {
  padding-top: var(--space-4);
}

.ca-desk-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-1);
}

.ca-desk-toolbar__primary,
.ca-desk-toolbar__secondary,
.ca-desk-dates {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.ca-desk-toolbar__primary {
  flex: 1;
}

.ca-desk-dates button,
.ca-desk-chip {
  min-height: var(--touch-min);
  white-space: nowrap;
}

.ca-desk-dates__today {
  min-width: 190px;
  color: var(--text-primary);
  font-weight: 700;
}

.ca-desk-search {
  display: block;
  width: min(100%, 360px);
  margin-left: auto;
}

.ca-desk-search input {
  width: 100%;
}

.ca-desk-chip.is-on {
  color: var(--text-accent);
  border-color: var(--border-accent);
  background: var(--accent-soft);
}

.ca-desk-count,
.ca-desk-window-label {
  color: var(--text-secondary);
  font-size: var(--type-12);
  white-space: nowrap;
}

.ca-slate-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  gap: var(--space-3);
}

.ca-kickoff-window + .ca-kickoff-window {
  margin-top: var(--space-5);
}

.ca-kickoff-window > header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0 var(--space-1) var(--space-2);
  border-bottom: 1px solid var(--border-subtle);
  margin-bottom: var(--space-3);
}

.ca-kickoff-window > header h2 {
  margin: 0;
  font-size: var(--type-18);
}

.ca-kickoff-window > header span {
  color: var(--text-meta);
  font-size: var(--type-12);
}

.ca-matchup-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  min-height: 272px;
  padding: var(--space-3);
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-1);
}

.ca-matchup-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  border-radius: var(--radius-md) 0 0 var(--radius-md);
  background: var(--accent);
}

.ca-matchup-card:hover,
.ca-matchup-card:focus-within {
  border-color: var(--border-strong);
  box-shadow: var(--elevation-2);
}

.ca-matchup-card.is-expanded {
  grid-column: 1 / -1;
}

.ca-matchup-card__head,
.ca-matchup-card__actions,
.ca-embedded-slate-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.ca-matchup-card__head {
  min-height: 24px;
  padding-left: var(--space-1);
}

.ca-matchup-card__kick {
  min-width: 0;
  color: var(--text-primary);
  font-size: var(--type-14);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ca-matchup-card__broadcast {
  display: inline-block;
  max-width: 20ch;
  margin-left: var(--space-2);
  padding-left: var(--space-2);
  border-left: 1px solid var(--border-default);
  color: var(--text-meta);
  font-size: var(--type-12);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
  white-space: nowrap;
}

.ca-status-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  background: var(--surface-raised);
  font-size: var(--type-12);
  font-weight: 700;
  white-space: nowrap;
}

.ca-status-chip.is-live,
.ca-status-chip.is-ok {
  color: var(--status-live);
  border-color: color-mix(in srgb, var(--status-live) 38%, transparent);
  background: color-mix(in srgb, var(--status-live) 12%, transparent);
}

.ca-status-chip.is-watch {
  color: var(--status-stale);
  border-color: color-mix(in srgb, var(--status-stale) 38%, transparent);
}

.ca-matchup-card__teams {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24px minmax(0, 1fr);
  align-items: center;
  gap: var(--space-2);
  min-height: 64px;
  padding: var(--space-2) var(--space-1);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-matchup-card__club {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.ca-matchup-card__club--home {
  flex-direction: row-reverse;
  text-align: right;
}

.ca-matchup-logo,
.ca-detail-team__logo {
  display: block;
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  object-fit: contain;
}

.ca-matchup-card__club-copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.ca-matchup-card__name {
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: var(--type-16);
  font-weight: 700;
  line-height: 1.05;
}

.ca-matchup-card__record {
  margin-top: var(--space-1);
  color: var(--text-meta);
  font-size: var(--type-12);
}

.ca-matchup-card__versus {
  color: var(--text-muted);
  font-size: var(--type-12);
  font-weight: 700;
  text-align: center;
  text-transform: uppercase;
}

  .ca-matchup-card__summary,
  .ca-matchup-card__detail-grid,
.ca-matchup-card__environment {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
}

.ca-matchup-card__detail-grid,
.ca-matchup-card__environment {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ca-matchup-card__fact {
  min-width: 0;
  padding: var(--space-2);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}

.ca-matchup-card__fact > span,
.ca-matchup-card__fact > strong {
  display: block;
  min-width: 0;
}

.ca-matchup-card__fact > span {
  color: var(--text-meta);
  font-size: var(--type-12);
}

.ca-matchup-card__fact > strong {
  margin-top: 2px;
  color: var(--text-secondary);
  font-size: var(--type-12);
  font-weight: 600;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.ca-matchup-card__fact > strong.is-ok { color: var(--status-ok); }
.ca-matchup-card__fact > strong.is-watch { color: var(--status-stale); }

.ca-matchup-card__actions {
  margin-top: auto;
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-subtle);
}

.ca-matchup-card__expand-btn,
.ca-matchup-card__detail-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--touch-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--type-12);
  font-weight: 700;
}

.ca-matchup-card__expand-btn {
  color: var(--text-primary);
}

.ca-matchup-card__detail-link {
  color: var(--text-accent);
}

.ca-matchup-card__expand {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-3) 0 0;
  border-top: 1px solid var(--border-subtle);
}

.ca-matchup-card__expand[hidden] {
  display: none;
}

.ca-matchup-card__starters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.ca-matchup-card__starter {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-3);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-matchup-card__shot {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface-raised);
}

.ca-matchup-card__shot--empty {
  border: 1px solid var(--border-default);
}

.ca-matchup-card__starter div,
.ca-matchup-card__starter span,
.ca-matchup-card__starter strong {
  display: block;
  min-width: 0;
}

.ca-matchup-card__starter-label {
  color: var(--text-meta);
  font-size: var(--type-12);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

.ca-matchup-card__starter strong {
  color: var(--text-primary);
  font-size: var(--type-14);
}

.ca-matchup-card__starter strong + span {
  color: var(--text-secondary);
  font-size: var(--type-12);
}

.ca-loading-state,
.ca-error-state,
.ca-empty-state {
  display: grid;
  place-items: center;
  min-height: 220px;
  padding: var(--space-6);
  text-align: center;
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
}

.ca-error-state h2,
.ca-empty-state h2 {
  margin: 0;
}

.ca-opening-desk__head {
  grid-template-columns: 1fr;
}

.ca-opening-desk__slates {
  display: grid;
  gap: var(--space-7);
  padding-top: var(--space-6);
}

.ca-opening-sport__head,
.ca-embedded-slate-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.ca-opening-sport__head h2 {
  margin: 0;
}

.ca-embedded-slate-head {
  align-items: center;
  color: var(--text-meta);
  font-size: var(--type-12);
}

/* Factual game detail */
.ca-detail-page {
  width: min(100%, var(--shell-max));
  margin: 0 auto;
  padding: var(--space-5) var(--shell-gutter) var(--space-9);
}

.ca-detail-back {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  margin-bottom: var(--space-2);
  color: var(--text-secondary);
  font-weight: 700;
}

.ca-detail-hero,
.ca-detail-section {
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-1);
}

.ca-detail-hero {
  position: relative;
  padding: var(--space-4);
  overflow: hidden;
}

.ca-detail-hero::before,
.ca-detail-section::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--accent);
}

.ca-detail-hero__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}

.ca-detail-hero__teams {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(170px, auto) minmax(0, 1fr);
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-6) var(--space-4);
}

.ca-detail-team {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
}

.ca-detail-team--home {
  flex-direction: row-reverse;
  text-align: right;
}

.ca-detail-team__logo {
  width: 76px;
  height: 76px;
}

.ca-detail-team h1 {
  margin: 0;
  font-size: clamp(var(--type-24), 3vw, var(--type-32));
}

.ca-detail-team p,
.ca-detail-center p {
  margin: var(--space-1) 0 0;
  color: var(--text-secondary);
}

.ca-detail-center {
  text-align: center;
}

.ca-detail-center strong {
  display: block;
  color: var(--text-primary);
  font-family: var(--font-display);
  font-size: var(--type-24);
}

.ca-detail-facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
}

.ca-detail-fact {
  padding: var(--space-3);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-detail-fact span,
.ca-detail-fact strong {
  display: block;
}

.ca-detail-fact span {
  color: var(--text-meta);
  font-size: var(--type-12);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
}

.ca-detail-fact strong {
  margin-top: var(--space-1);
  color: var(--text-primary);
  font-size: var(--type-14);
}

.ca-detail-nav {
  position: sticky;
  top: calc(var(--shell-header-h) + var(--shell-context-h));
  z-index: calc(var(--z-header) - 1);
  display: flex;
  gap: var(--space-1);
  margin: var(--space-3) 0;
  padding: var(--space-1);
  overflow-x: auto;
  background: var(--surface-inset);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
}

.ca-detail-nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--touch-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-xs);
  color: var(--text-secondary);
  font-size: var(--type-12);
  font-weight: 700;
  white-space: nowrap;
}

.ca-detail-nav a:hover,
.ca-detail-nav a:focus-visible {
  color: var(--text-primary);
  background: var(--accent-soft);
}

.ca-detail-stack {
  display: grid;
  gap: var(--space-3);
}

.ca-detail-section {
  position: relative;
  padding: var(--space-4);
  overflow: hidden;
  scroll-margin-top: calc(var(--shell-header-h) + var(--shell-context-h) + 64px);
}

.ca-detail-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.ca-detail-section__head h2 {
  margin: 0;
}

.ca-detail-section__head p {
  margin: 0;
  color: var(--text-meta);
  font-size: var(--type-12);
}

.ca-detail-duo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.ca-detail-team-panel {
  min-width: 0;
  padding: var(--space-3);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-detail-team-panel__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.ca-detail-team-panel__head img {
  width: 44px;
  height: 44px;
  object-fit: contain;
}

.ca-detail-team-panel__head h3,
.ca-detail-team-panel__head p {
  margin: 0;
}

.ca-detail-team-panel__head p {
  color: var(--text-meta);
  font-size: var(--type-12);
}

.ca-detail-list {
  display: grid;
  gap: 0;
  margin: 0;
}

.ca-detail-list div {
  display: grid;
  grid-template-columns: minmax(120px, 0.45fr) minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-top: 1px solid var(--border-subtle);
}

.ca-detail-list dt {
  color: var(--text-meta);
}

.ca-detail-list dd {
  margin: 0;
  color: var(--text-primary);
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

.ca-detail-source-note {
  color: var(--text-secondary);
  line-height: 1.6;
}

@media (max-width: 1100px) {
  .ca-slate-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ca-detail-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 820px) {
  .ca-public-page,
  .ca-opening-desk,
  .ca-detail-page {
    padding-inline: var(--shell-gutter-md);
  }
  .ca-public-page__head { grid-template-columns: 1fr; align-items: start; }
  .ca-public-page__links { justify-content: flex-start; }
  .ca-desk-toolbar { align-items: stretch; flex-direction: column; }
  .ca-desk-toolbar__primary,
  .ca-desk-toolbar__secondary { width: 100%; }
  .ca-desk-search { width: 100%; }
  .ca-detail-hero__teams { grid-template-columns: 1fr; gap: var(--space-3); }
  .ca-detail-team,
  .ca-detail-team--home { justify-content: center; flex-direction: column; text-align: center; }
}

@media (max-width: 680px) {
  .ca-public-page,
  .ca-opening-desk,
  .ca-detail-page {
    padding: var(--space-4) var(--shell-gutter-sm) var(--space-8);
  }
  .ca-slate-grid { grid-template-columns: 1fr; }
  .ca-matchup-card { min-height: 0; }
  .ca-matchup-card.is-expanded { grid-column: auto; }
  .ca-matchup-card__teams { grid-template-columns: minmax(0, 1fr) 16px minmax(0, 1fr); }
  .ca-matchup-card__club,
  .ca-matchup-card__club--home { flex-direction: column; gap: var(--space-1); text-align: center; }
  .ca-matchup-card__versus { display: block; }
  .ca-matchup-card__summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ca-matchup-card__summary .ca-matchup-card__fact:last-child { grid-column: 1 / -1; }
  .ca-matchup-card__detail-grid,
  .ca-matchup-card__environment,
  .ca-matchup-card__starters,
  .ca-detail-facts,
  .ca-detail-duo { grid-template-columns: 1fr; }
  .ca-matchup-card__summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ca-matchup-card__summary .ca-matchup-card__fact:last-child { grid-column: 1 / -1; }
  .ca-matchup-card__actions { align-items: stretch; }
  .ca-matchup-card__expand-btn,
  .ca-matchup-card__detail-link { flex: 1; min-width: 0; padding-inline: var(--space-2); text-align: center; }
  .ca-desk-toolbar__primary,
  .ca-desk-toolbar__secondary,
  .ca-desk-dates { align-items: stretch; flex-wrap: wrap; }
  .ca-desk-dates { width: 100%; }
  .ca-desk-dates__today { flex: 1; min-width: 0; }
  .ca-desk-search { order: 2; margin: 0; }
  .ca-desk-count { align-self: center; margin-left: auto; }
  .ca-opening-sport__head { align-items: flex-start; flex-direction: column; }
  .ca-detail-hero__meta { align-items: flex-start; flex-direction: column; }
  .ca-detail-team__logo { width: 64px; height: 64px; }
  .ca-detail-list div { grid-template-columns: 1fr; gap: var(--space-1); }
  .ca-detail-list dd { text-align: left; }
}

@media (max-width: 420px) {
  .ca-matchup-card__name { font-size: var(--type-14); }
  .ca-matchup-logo { width: 44px; height: 44px; }
  .ca-matchup-card__head { align-items: flex-start; }
  .ca-matchup-card__broadcast { display: block; max-width: 24ch; margin: var(--space-1) 0 0; padding: 0; border: 0; }
}

/* ===========================================================================
 * DESK RESTORE - 2026-09-09
 * Implements design/GPT_IMAGE_PROMPTS_CHASE_DESK.md prompt 1/2/4 against the
 * existing public markup. Appended last so equal-specificity flat rules above
 * are superseded by source order. Public content stays factual: no projected
 * score, probability, market line, or edge metric appears in this file.
 * ======================================================================== */

body[data-ca-product="research"] {
  background-image: var(--canvas-ambient);
  background-attachment: fixed;
  background-repeat: no-repeat;
}

/* Desk masthead */
.ca-public-page__title,
.ca-opening-desk__title {
  font-size: var(--type-display);
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.02;
  text-wrap: balance;
}

.ca-public-page__lede,
.ca-opening-desk__lede {
  max-width: 68ch;
  font-size: var(--type-16);
}

/* Slate boards. Each sport section and kickoff window is a lacquered board
   with the 3px violet edge, so the slate reads as one surface instead of
   loose cards on bare canvas. */
.ca-opening-sport,
.ca-kickoff-window,
.ca-slate-board {
  position: relative;
  padding: var(--space-5) var(--space-5) var(--space-5) calc(var(--space-5) + 3px);
  background: var(--surface-board);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--elevation-2);
  overflow: hidden;
}

.ca-opening-sport::before,
.ca-kickoff-window::before,
.ca-slate-board::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--edge-brand);
}

.ca-opening-sport::after,
.ca-kickoff-window::after,
.ca-slate-board::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 3px;
  height: 1px;
  background: var(--edge-glint);
}

.ca-kickoff-window + .ca-kickoff-window { margin-top: var(--space-4); }

.ca-opening-sport__head h2,
.ca-kickoff-window > header h2 {
  font-size: var(--type-section);
  font-weight: 800;
  letter-spacing: 0.01em;
}

.ca-kickoff-window > header {
  border-bottom: 1px solid var(--border-default);
  padding-bottom: var(--space-3);
}

.ca-kickoff-window > header span,
.ca-desk-count,
.ca-desk-window-label {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Toolbar */
.ca-desk-toolbar {
  padding: var(--space-3) var(--space-4);
  background: var(--surface-board-raised);
  border-color: var(--border-default);
  box-shadow: var(--elevation-2);
  flex-wrap: wrap;
}

.ca-desk-dates button,
.ca-desk-chip,
.ca-desk-view-toggle button {
  background: var(--surface-inset);
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
  font-weight: 600;
}
.ca-desk-dates button:hover,
.ca-desk-chip:hover { background: var(--control-bg-hover); color: var(--text-primary); }

.ca-desk-dates__today {
  font-family: var(--font-display);
  font-size: var(--type-16);
  letter-spacing: 0.01em;
  color: var(--text-primary);
}

.ca-desk-chip.is-on {
  background: var(--accent-soft);
  border-color: var(--border-accent);
  color: var(--text-accent);
}

/* The grid. AUDIT D5: this was a flat repeat(3, 1fr), so a one-game kickoff
   window rendered a narrow card beside two empty tracks.

   A single auto-fit minmax() cannot express the documented breakpoints - the
   style lock and scripts/public_site_runtime_diag.py both want 3 columns at
   1440, 2 from 720 to 1099, and 1 below that, and no single track minimum
   yields 3-at-1440 and 2-at-720. So the counts stay explicit, and :has()
   handles the real D5 case: a window holding fewer cards than the track count
   drops to that many columns instead of leaving dead tracks. */
.ca-slate-grid { gap: var(--space-3); }

@media (min-width: 1100px) {
  .ca-slate-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ca-slate-grid:not(:has(> :nth-child(2))) { grid-template-columns: minmax(0, 1fr); }
  .ca-slate-grid:has(> :nth-child(2)):not(:has(> :nth-child(3))) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 620px) and (max-width: 1099px) {
  .ca-slate-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ca-slate-grid:not(:has(> :nth-child(2))) { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 619px) {
  .ca-slate-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Matchup card */
.ca-matchup-card {
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface-board-raised);
  border: 1px solid var(--border-default);
  box-shadow: var(--elevation-2);
  transition: box-shadow var(--motion-base) var(--motion-ease),
              border-color var(--motion-base) var(--motion-ease);
}

.ca-matchup-card::before { background: var(--edge-brand); }

.ca-matchup-card:hover,
.ca-matchup-card:focus-within {
  border-color: var(--border-accent);
  box-shadow: var(--elevation-glow);
}

.ca-matchup-card__head {
  align-items: center;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}

.ca-matchup-card__kick {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--type-16);
  font-weight: 700;
  color: var(--text-primary);
  letter-spacing: 0.01em;
}

.ca-matchup-card__broadcast {
  font-family: var(--font-ui);
  font-size: var(--type-12);
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--text-muted);
  text-transform: none;
  overflow-wrap: anywhere;
  white-space: normal;
}

/* Identity band: two inset fields, logo left, abbreviation as display type,
   full team name and record beneath. Full names stay visible per the public
   content rules; the abbreviation is a scan aid, not the identity. */
.ca-matchup-card__teams {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: stretch;
  gap: var(--space-2);
}

.ca-matchup-card__club {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-matchup-card__club--home { flex-direction: row; text-align: left; }

.ca-matchup-card__club .ca-matchup-logo,
.ca-matchup-card__club img {
  width: 40px;
  height: 40px;
  object-fit: contain;
  flex: 0 0 auto;
}

.ca-matchup-card__club-copy {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
  align-items: flex-start;
  text-align: left;
}

.ca-matchup-card__abbr {
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: 0.02em;
  color: var(--text-primary);
}

.ca-matchup-card__name {
  font-family: var(--font-ui);
  font-size: var(--type-12);
  font-weight: 500;
  line-height: 1.25;
  color: var(--text-secondary);
  white-space: normal;
  overflow-wrap: anywhere;
}

.ca-matchup-card__record {
  font-size: var(--type-12);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.ca-matchup-card__versus {
  align-self: center;
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Factual cells */
.ca-matchup-card__summary,
.ca-matchup-card__detail-grid,
.ca-matchup-card__environment {
  gap: var(--space-2);
}

.ca-matchup-card__fact {
  padding: var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-matchup-card__fact > span {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-matchup-card__fact > strong {
  font-size: var(--type-14);
  font-weight: 600;
  color: var(--text-primary);
}

/* Starter fields */
.ca-matchup-card__starter {
  padding: var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.ca-matchup-card__starter strong {
  font-size: var(--type-14);
  font-weight: 700;
  color: var(--text-primary);
}

.ca-matchup-card__starter-label {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Actions */
.ca-matchup-card__actions {
  align-items: center;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
}

.ca-matchup-card__expand-btn {
  background: var(--surface-inset);
  border: 1px solid var(--border-default);
  color: var(--text-primary);
  font-weight: 600;
}
.ca-matchup-card__expand-btn:hover {
  background: var(--control-bg-hover);
  border-color: var(--border-accent);
}

.ca-matchup-card__detail-link {
  color: var(--text-accent);
  font-weight: 600;
}
.ca-matchup-card__detail-link:hover { color: var(--text-primary); }

.ca-matchup-card__updated {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Status chips read as lit controls rather than grey outlines. */
.ca-status-chip {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: 0.06em;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.ca-status-chip.is-live {
  background: var(--tint-positive);
  border: 1px solid var(--mark-positive);
  color: var(--metric-elite);
}
.ca-status-chip.is-final {
  background: var(--surface-inset);
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
}
.ca-status-chip.is-ok {
  background: var(--accent-soft);
  border: 1px solid var(--border-accent);
  color: var(--metric-elite);
}
.ca-status-chip.is-watch {
  background: var(--tint-caution);
  border: 1px solid var(--mark-caution);
  color: var(--value-caution);
}
.ca-status-chip.is-muted {
  background: var(--surface-inset);
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
}

/* Expanded panel sits on the darker inset so it reads as beneath the card. */
.ca-matchup-card__expand {
  padding: var(--space-3);
  background: var(--surface-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

@media (max-width: 620px) {
  .ca-matchup-card__teams { grid-template-columns: minmax(0, 1fr); }
  .ca-matchup-card__versus { justify-self: start; }
}

/* --- Desk restore, pass 2: card rhythm ----------------------------------
 * Pass 1 restored the surfaces; these rules fix the geometry the first local
 * capture exposed - ragged card heights inside a row, a 3-line broadcast
 * string, and fact labels wrapping onto two lines inside a 130px cell. */

/* Cards in a row share a height, and the action row is pinned to the bottom so
 * the "Expand matchup" controls line up across the row. */
.ca-slate-grid { align-items: stretch; }
.ca-slate-grid > .ca-matchup-card { height: 100%; }
.ca-matchup-card__actions { margin-top: auto; }

/* The card header stays one line tall: time and status on the baseline, the
 * broadcast list clamped to a single line that ends at a word. */
.ca-matchup-card__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-3);
}

.ca-matchup-card__kick {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-2);
  min-width: 0;
}

.ca-matchup-card__broadcast {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-width: 0;
}

/* Identity band: a fixed logo track means the logo and the copy always sit
 * side by side, whatever intrinsic width the crest image reports. */
.ca-matchup-card__club {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  align-items: center;
  column-gap: var(--space-3);
}
.ca-matchup-card__club > img,
.ca-matchup-card__club > .ca-matchup-logo,
.ca-matchup-card__club > .ca-team-logo-placeholder {
  grid-column: 1;
  width: 40px;
  height: 40px;
  justify-self: center;
}
.ca-matchup-card__club-copy { grid-column: 2; }

/* Fact cells: give the wide label the room it needs so "Probable starters"
 * stays on one line, and let the value wrap under it. */
.ca-matchup-card__summary {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1.2fr);
  align-items: stretch;
}

.ca-matchup-card__fact {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.ca-matchup-card__fact > span {
  line-height: 1.2;
  letter-spacing: 0.05em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ca-matchup-card__fact > strong {
  line-height: 1.3;
  overflow-wrap: anywhere;
}

@media (max-width: 620px) {
  .ca-matchup-card__summary { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .ca-matchup-card__summary > .ca-matchup-card__fact:first-child { grid-column: 1 / -1; }
}

/* The base rule caps this at 20ch with white-space:nowrap, which is what cut
   "Broadcast not published" to "Broadcast not..." mid-word (AUDIT B6). The
   clamp above already ends the line at a word, so the character cap goes. */
.ca-matchup-card__broadcast {
  max-width: none;
  margin-left: 0;
  padding-left: var(--space-3);
  border-left: 1px solid var(--border-default);
  vertical-align: baseline;
}

/* On a phone the status chip takes the header's auto track and the broadcast
   list is squeezed to two characters ("D.."). Give it its own line there. */
@media (max-width: 620px) {
  .ca-matchup-card__kick {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--space-1);
  }
  .ca-matchup-card__broadcast {
    padding-left: 0;
    border-left: 0;
    -webkit-line-clamp: 2;
  }
}

/* --- Club-coloured abbreviation tab ---------------------------------------
 * Replaced the crest in the card identity band on 2026-09-09 (owner decision,
 * following the Model Center reference renderings). Ground and ink arrive as
 * --team-bg / --team-ink from MLBMAAssets.teamTabHtml, which derives the
 * ink from the ground's luminance, so a gold club gets dark text. An unknown
 * club sets neither and falls back to the neutral inset below.
 *
 * Player headshots are unaffected: they stay on the starter panels and the
 * profile pages, where a face is the subject rather than a club identity. */
.ca-team-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  min-width: 58px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-xs);
  background: var(--team-bg, var(--surface-inset));
  color: var(--team-ink, var(--text-primary));
  border: 1px solid var(--border-subtle);
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.ca-matchup-card__club {
  grid-template-columns: auto minmax(0, 1fr);
}

.ca-matchup-card__tab { min-width: 58px; }

@media (max-width: 400px) {
  .ca-team-tab { min-width: 50px; font-size: var(--type-16); }
}

/* --- Collapsed card height contract ---------------------------------------
 * scripts/public_site_runtime_diag.py holds the collapsed card to 240-360px on
 * desktop, and the style lock says 272-350px. The identity tab and the fact
 * cells added rhythm that pushed it to 362-380px, so the internal spacing is
 * tightened rather than the content cut - every published fact stays. */
.ca-matchup-card {
  padding: var(--space-3);
  gap: var(--space-2);
}

.ca-matchup-card__club { padding: var(--space-2) var(--space-3); }

.ca-matchup-card__head { padding-bottom: var(--space-2); }

.ca-matchup-card__actions { padding-top: var(--space-2); }

.ca-matchup-card__fact { padding: var(--space-2) var(--space-3); }

/* --- Card text fitting at 3-column width ----------------------------------
 * Two defects visible on the live 1440px slate after the club tabs narrowed
 * the cells:
 *
 * 1. The fact label was nowrap + ellipsis, so a ~230px cell cut
 *    "Probable starters" to "PROBABLE START..." - the same mid-word clip this
 *    pass already fixed on the broadcast line. Labels wrap to two lines now.
 * 2. .ca-matchup-card__name used overflow-wrap:anywhere, which breaks INSIDE a
 *    word rather than at a space: "Washingto / n Nationals". break-word only
 *    breaks a word that cannot fit a line on its own, so multi-word club names
 *    wrap where they should. */
.ca-matchup-card__fact > span {
  white-space: normal;
  text-overflow: clip;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ca-matchup-card__name {
  overflow-wrap: break-word;
  word-break: normal;
}

/* ===========================================================================
 * FLAT WIDE DESK - 2026-09-10
 *
 * Three corrections against the reference renderings:
 *
 * 1. DE-NEST. The slate had four levels of rounded container - section board >
 *    grid wrapper > card > inner field - so every card sat inside two boxes
 *    that carry no information. The renderings put cards DIRECTLY on the desk:
 *    a section is an eyebrow and a heading in open space, nothing more.
 * 2. FLATTEN. Ambient violet washes and lacquered gradients are gone (see
 *    chase-semantic.css). The desk is matte near-black; colour is reserved for
 *    team identity, status and data.
 * 3. WIDEN. The shell fills the display, and extra width buys more columns
 *    rather than wider cards.
 * ======================================================================== */

/* --- 1. De-nest: sections are headings in open space, not boards ---------- */
.ca-opening-sport,
.ca-kickoff-window,
.ca-slate-board {
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}

/* The violet rail and the top glint belonged to the wrapper boards. With the
   wrappers gone the accent lives on the card itself, where it marks a game. */
.ca-opening-sport::before,
.ca-opening-sport::after,
.ca-kickoff-window::before,
.ca-kickoff-window::after,
.ca-slate-board::before,
.ca-slate-board::after {
  content: none;
}

.ca-opening-desk__slates {
  display: grid;
  gap: var(--space-9);
}

.ca-kickoff-window + .ca-kickoff-window { margin-top: var(--space-8); }

/* Section head: eyebrow over heading, count/action pushed right, one hairline
   under it. This is the whole chrome a section gets. */
.ca-opening-sport__head,
.ca-kickoff-window > header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
  padding: 0 0 var(--space-3);
  border-bottom: 1px solid var(--border-default);
}

.ca-opening-sport__head h2,
.ca-kickoff-window > header h2 {
  margin: 0;
  font-size: var(--type-section);
  font-weight: 800;
  letter-spacing: 0.01em;
}

/* The embedded slate header ("15 games" + "View full MLB slate") was a boxed
   strip inside the wrapper. It joins the section head line instead. */
.ca-embedded-slate-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin: 0 0 var(--space-4);
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}

/* --- 2. Flat surfaces ----------------------------------------------------- */
.ca-desk-toolbar {
  padding: 0 0 var(--space-4);
  margin-bottom: var(--space-5);
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border-default);
  border-radius: 0;
  box-shadow: none;
}

.ca-matchup-card {
  background: var(--surface-board-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  box-shadow: none;
}

/* Hover reads as the edge lighting up, not the card floating. */
.ca-matchup-card:hover,
.ca-matchup-card:focus-within {
  border-color: var(--border-accent);
  box-shadow: none;
}

.ca-matchup-card__club,
.ca-matchup-card__fact,
.ca-matchup-card__starter,
.ca-matchup-card__expand {
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}

/* --- 3. Width and columns -------------------------------------------------
 * More display buys more tracks. The counts at and below 1440 are held by
 * scripts/public_site_runtime_diag.py; the wider steps are additive. */
@media (min-width: 1680px) {
  .ca-slate-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .ca-slate-grid:not(:has(> :nth-child(2))) { grid-template-columns: minmax(0, 1fr); }
  .ca-slate-grid:has(> :nth-child(2)):not(:has(> :nth-child(3))) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .ca-slate-grid:has(> :nth-child(3)):not(:has(> :nth-child(4))) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 2080px) {
  .ca-slate-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Page shell gutters follow the wider frame. */
.ca-public-page,
.ca-opening-desk {
  padding-left: var(--shell-gutter);
  padding-right: var(--shell-gutter);
}

/* ===========================================================================
 * WIDER CARDS, CHROME TITLES, TIGHTER MASTHEAD - 2026-09-10
 * ======================================================================== */

/* --- 1. Chrome display titles --------------------------------------------
 * .ca-page-title (Model Center, 404, glossary) already painted its h1 with the
 * metallic silver fill while the matchup routes rendered flat white, so the
 * site read as two different products. Same treatment everywhere now.
 * Guarded: without background-clip:text a transparent color would erase the
 * heading, so the fill only applies where the browser supports it. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ca-public-page__title,
  .ca-opening-desk__title {
    background: var(--text-display-metal);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

/* --- 2. Wider cards -------------------------------------------------------
 * The previous pass bought extra COLUMNS with the extra width, which made each
 * card narrower - 457px at 1920 and 399px at 2560, against 453px at 1440. So
 * a bigger display produced a more cramped card: team names wrapped to two
 * lines and the fact labels wrapped at 2560.
 *
 * Extra width now goes into the cards. Three columns hold until the shell is
 * wide enough that a fourth still leaves each card above ~600px, which is
 * where the internals stop wrapping. Counts at and below 1440 are unchanged -
 * scripts/public_site_runtime_diag.py holds them. */
@media (min-width: 1441px) {
  .ca-slate-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ca-slate-grid:not(:has(> :nth-child(2))) { grid-template-columns: minmax(0, 1fr); }
  .ca-slate-grid:has(> :nth-child(2)):not(:has(> :nth-child(3))) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* No fourth column. The shell caps at 2100px, so four tracks can never exceed
   ~516px per card - narrower than the 613px three tracks give at 1920. Three
   columns hold all the way up, which puts ~690px into each card at 2560. */

/* --- 3. Let the card breathe ---------------------------------------------
 * With ~610px to work in, the internals get room back: the identity band and
 * the fact cells stop fighting for the same 130px.
 *
 * Scoped to 1441px and up. At 1440 the card is 453px and still holds three
 * columns, where the same padding pushed the collapsed card to 363px against
 * the 240-360px contract in scripts/public_site_runtime_diag.py. */
@media (min-width: 1441px) {
  .ca-matchup-card {
    padding: var(--space-4);
    gap: var(--space-3);
  }

  .ca-matchup-card__club { padding: var(--space-3); }

  .ca-matchup-card__fact { padding: var(--space-3); }

  /* The club name sits at reading size and on one line wherever it fits. */
  .ca-matchup-card__name {
    font-size: var(--type-14);
    line-height: 1.3;
  }
}

/* At a comfortable card width the label no longer needs the two-line clamp. */
@media (min-width: 1441px) {
  .ca-matchup-card__fact > span {
    -webkit-line-clamp: 1;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
}

/* --- 4. Tighten the masthead ---------------------------------------------
 * The block above the first card ran ~270px of mostly empty space. */
.ca-public-page,
.ca-opening-desk {
  padding-top: var(--space-5);
  padding-bottom: var(--space-8);
}

.ca-public-page__head,
.ca-opening-desk__head {
  padding-bottom: var(--space-4);
}

.ca-public-page__lede,
.ca-opening-desk__lede {
  margin-top: var(--space-1);
}

.ca-opening-desk__slates { gap: var(--space-7); }

.ca-opening-sport__head,
.ca-kickoff-window > header { margin-bottom: var(--space-3); }

.ca-embedded-slate-head { margin-bottom: var(--space-3); }

/* --- Masthead density -----------------------------------------------------
 * At 1920 the band above the first card ran 364px, and most of it was the
 * standfirst wrapping to two lines inside a 68ch cap while ~900px of the row
 * sat empty. The reading cap is right for a paragraph; this line is a one-line
 * deck, so it gets the room it needs and the block loses a line. */
@media (min-width: 1200px) {
  .ca-public-page__lede,
  .ca-opening-desk__lede {
    max-width: 108ch;
  }
}

.ca-desk-toolbar { margin-bottom: var(--space-4); }

/* ===========================================================================
 * SYMMETRIC CARD BODY + COLLAPSED TOP CHROME - 2026-09-10
 * ======================================================================== */

/* --- Controls join the title row -----------------------------------------
 * The date/filter band was a row of its own holding three controls in a
 * 1561px track, most of it empty. It now sits opposite the title, which is
 * where the reference chrome puts it and removes a whole band. */
.ca-public-page__head,
.ca-opening-desk__head {
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  align-items: end;
  column-gap: var(--space-6);
}

.ca-public-page__controls { min-width: 0; justify-self: end; }

.ca-public-page__controls .ca-desk-toolbar {
  margin: 0;
  padding: 0;
  border: 0;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.ca-public-page__controls .ca-desk-toolbar__primary { flex: 0 0 auto; }
.ca-public-page__controls .ca-desk-toolbar__secondary { flex: 0 0 auto; }

/* The context strip already reports the slate size. */
.ca-public-page__controls .ca-desk-count { display: none; }

@media (max-width: 1100px) {
  .ca-public-page__head,
  .ca-opening-desk__head { grid-template-columns: minmax(0, 1fr); }
  .ca-public-page__controls { justify-self: start; }
  .ca-public-page__controls .ca-desk-toolbar { justify-content: flex-start; }
}

/* --- Starter faces --------------------------------------------------------
 * Two equal columns so the row stays symmetric whichever side has data. */
.ca-matchup-card__arms {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2);
}

.ca-matchup-card__arm {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  align-items: center;
  column-gap: var(--space-3);
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}

.ca-matchup-card__arm .ca-matchup-card__shot {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-pill);
  object-fit: cover;
  background: var(--surface-raised);
  border: 1px solid var(--border-default);
}

.ca-matchup-card__arm-copy { display: grid; gap: 1px; min-width: 0; }

.ca-matchup-card__arm-name {
  font-size: var(--type-14);
  font-weight: 700;
  color: var(--text-primary);
  line-height: 1.25;
  overflow-wrap: break-word;
}

.ca-matchup-card__arm-meta {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* --- Meta strip: four equal cells ---------------------------------------- */
.ca-matchup-card__summary {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 1441px) {
  .ca-matchup-card__summary { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .ca-matchup-card__arms { grid-template-columns: minmax(0, 1fr); }
  .ca-matchup-card__summary > .ca-matchup-card__fact:first-child { grid-column: auto; }
}

/* An absent season line is muted prose, not tracked caps - it was shouting
   "SEASON LINE NOT PUBLISHED" once per starter, twice per card. */
.ca-matchup-card__arm-meta.is-absent {
  font-family: var(--font-ui);
  font-size: var(--type-12);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-muted);
}

/* Secondary page links (Results) join the control row instead of stranding
   themselves on a line of their own under the title. */
.ca-public-page__head { row-gap: var(--space-2); }

.ca-public-page__links {
  grid-column: 2;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

@media (max-width: 1100px) {
  .ca-public-page__links { grid-column: 1; justify-self: start; }
}

/* --- Team offensive context ----------------------------------------------
 * OSI / wRC+ / wOBA / ABQ with a league rank beside each, from the published
 * team-rankings snapshot. Value and rank sit together so the number always
 * reads as a description of the season, never as a forecast. */
.ca-ctx-duo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.ca-ctx-head {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-ctx-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2);
}

.ca-ctx-cell {
  display: grid;
  gap: 1px;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  min-width: 0;
}

.ca-ctx-label {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  /* No uppercase transform: wRC+ and wOBA are proper metric names and
     "WRC+" / "WOBA" are simply wrong. The renderer supplies the exact
     casing. */
  color: var(--text-muted);
}

.ca-ctx-value {
  font-family: var(--font-display);
  font-size: var(--type-20);
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}

.ca-ctx-rank {
  font-size: var(--type-12);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.ca-ctx-note {
  margin: var(--space-3) 0 0;
  font-size: var(--type-12);
  color: var(--text-muted);
}

@media (max-width: 760px) {
  .ca-ctx-duo { grid-template-columns: minmax(0, 1fr); }
  .ca-ctx-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- NFL availability ------------------------------------------------------
 * Official injury-report designations. Status carries colour because it is a
 * factual severity, not a grade: out / doubtful / questionable. */
.ca-avail-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-1);
}

.ca-avail-row {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) minmax(0, auto) auto;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  min-width: 0;
}

.ca-avail-pos {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 800;
  letter-spacing: .04em;
  color: var(--text-muted);
}

.ca-avail-name {
  font-size: var(--type-14);
  font-weight: 600;
  color: var(--text-primary);
  overflow-wrap: break-word;
  min-width: 0;
}

.ca-avail-detail {
  font-size: var(--type-12);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ca-avail-status {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: 2px var(--space-2);
  border-radius: var(--radius-xs);
  white-space: nowrap;
}
.ca-avail-status.is-out { background: var(--tint-negative); color: var(--value-negative); }
.ca-avail-status.is-doubtful { background: var(--tint-caution); color: var(--value-caution); }
.ca-avail-status.is-questionable { background: var(--surface-inset); color: var(--text-secondary); }

.ca-avail-empty,
.ca-avail-more {
  margin: var(--space-2) 0 0;
  font-size: var(--type-12);
  color: var(--text-muted);
}

@media (max-width: 620px) {
  .ca-avail-row { grid-template-columns: 34px minmax(0, 1fr) auto; }
  .ca-avail-detail { display: none; }
}

/* --- Club identity: crest first ------------------------------------------
 * Back to official crests (2026-09-10). The club colour stays as a 3px left
 * rule on the identity block - present enough to separate the two sides at a
 * glance, restrained enough that the crest is what carries the club, which is
 * what the matchup IA asks for.
 *
 * Crest sizing and variant selection are measured in mlbma_assets.js. */
.ca-matchup-card__club {
  grid-template-columns: 44px minmax(0, 1fr);
  border-left: 3px solid var(--team-accent, var(--border-default));
  padding-left: var(--space-3);
}

.ca-matchup-card__club .ca-matchup-logo,
.ca-matchup-card__club > img {
  width: 44px;
  height: 44px;
  object-fit: contain;
  /* The crests are transparent PNGs served at 3x; let the browser scale them
     smoothly rather than pixel-doubling. */
  image-rendering: auto;
}

.ca-matchup-card__tab { display: none; }

@media (max-width: 400px) {
  .ca-matchup-card__club { grid-template-columns: 38px minmax(0, 1fr); }
  .ca-matchup-card__club .ca-matchup-logo,
  .ca-matchup-card__club > img { width: 38px; height: 38px; }
}

/* The four-cell strip clamped labels to one nowrap line, so at three columns
   "Lineup status" became "LINEUP STA...". Two lines, ending at a word. */
.ca-matchup-card__fact > span {
  white-space: normal;
  text-overflow: clip;
  -webkit-line-clamp: 2;
  line-height: 1.2;
}

@media (min-width: 1441px) {
  .ca-matchup-card__fact > span {
    -webkit-line-clamp: 2;
    white-space: normal;
    text-overflow: clip;
  }
}

/* --- Matchup breakdown evidence -------------------------------------------
 * Starter panels, the lineup-versus-starter tables and the league-relative
 * form grid. Flat surfaces, tabular numbers, every value beside its rank or
 * its sample. */
.ca-detail-stack-inner { display: grid; gap: var(--space-4); }

.ca-starter-panel,
.ca-lineup-panel,
.ca-form-panel {
  padding: var(--space-4);
  background: var(--surface-board-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  min-width: 0;
}

.ca-starter-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}

.ca-starter-shot {
  width: 72px;
  height: 72px;
  border-radius: var(--radius-pill);
  object-fit: cover;
  background: var(--surface-raised);
  border: 1px solid var(--border-default);
  flex: 0 0 auto;
}

.ca-starter-team {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-starter-name {
  margin: 2px 0 0;
  font-family: var(--font-display);
  font-size: var(--type-section);
  font-weight: 800;
  color: var(--text-primary);
}

.ca-lineup-panel > h3,
.ca-form-panel > h3 {
  margin: 0 0 var(--space-1);
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  color: var(--text-primary);
}

/* The resolved context is stated, so the reader never has to rebuild it from
   filters: which lineup, home or away, against which hand. */
.ca-lineup-context {
  margin: 0 0 var(--space-3);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-accent);
}

.ca-lineup-scroll { overflow-x: auto; }

.ca-lineup-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: var(--type-14);
  font-variant-numeric: tabular-nums;
}

.ca-lineup-table th {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-default);
  white-space: nowrap;
}

.ca-lineup-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
  /* Defers to the cell's own grade when it carries one. */
  color: var(--grade, var(--text-secondary));
}
.ca-lineup-table tbody tr:last-child td { border-bottom: 0; }

.ca-lineup-table .num { text-align: right; }
.ca-lineup-slot { color: var(--text-muted); font-family: var(--font-display); font-weight: 700; }
.ca-lineup-name { color: var(--text-primary); font-weight: 600; white-space: nowrap; }

.ca-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 140px), 1fr));
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.ca-form-cell {
  display: grid;
  gap: 1px;
  padding: var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}

.ca-form-label {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
}

.ca-form-value {
  font-family: var(--font-display);
  font-size: var(--type-24);
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}

.ca-form-rank {
  font-size: var(--type-12);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* A percentile bar carries one meaning only: where this rate sits in its own
   league pool. It is drawn from the value beside it, never from a rating. */
.ca-pct-bar {
  display: block;
  height: 4px;
  margin: var(--space-1) 0 3px;
  background: var(--surface-raised);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.ca-pct-bar__fill {
  display: block;
  height: 100%;
  min-width: 2px;
  background: var(--accent);
  border-radius: var(--radius-pill);
}

.ca-form-grid--tight {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 92px), 1fr));
  margin: 0 0 var(--space-3);
}
.ca-form-grid--tight .ca-form-value { font-size: var(--type-18); }

/* --- Pitch mix -------------------------------------------------------------
 * Each row is one offering: name, its share of this pitcher's own pitches,
 * the share as a number, then velocity and sample. The bars sum to 100%. */
.ca-arsenal-panel {
  padding: var(--space-4);
  background: var(--surface-board-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  min-width: 0;
}

.ca-arsenal-panel > h3 {
  margin: 0 0 var(--space-1);
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  color: var(--text-primary);
}

.ca-arsenal-list {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-3) 0;
}

.ca-arsenal-row {
  display: grid;
  grid-template-columns: minmax(88px, 1fr) minmax(60px, 2fr) auto;
  grid-template-areas: "name bar pct" "meta meta meta";
  align-items: center;
  gap: 2px var(--space-3);
}

.ca-arsenal-name {
  grid-area: name;
  font-size: var(--type-14);
  color: var(--text-primary);
  font-weight: 600;
}

.ca-arsenal-bar {
  grid-area: bar;
  display: block;
  height: 8px;
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  overflow: hidden;
}

.ca-arsenal-bar__fill {
  display: block;
  height: 100%;
  background: var(--accent);
}

.ca-arsenal-pct {
  grid-area: pct;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--type-14);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.ca-arsenal-meta {
  grid-area: meta;
  font-size: var(--type-12);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* --- Bullpen workload ---------------------------------------------------- */
.ca-bullpen-panel {
  padding: var(--space-4);
  background: var(--surface-board-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  min-width: 0;
}

.ca-bullpen-panel > h3 {
  margin: 0 0 var(--space-1);
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  color: var(--text-primary);
}

/* An arm that worked yesterday and the day before is the one fact a workload
   table exists to surface, so it is marked rather than left to be counted. */
.ca-flag {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 1px 6px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-accent);
}

/* --- Scheme confrontation --------------------------------------------------
 * One panel per direction: this offence against that defence. Every block
 * inside states a charted rate, and the stacked bars are shares of the charted
 * sample, so they can only ever sum to 100%. */
.ca-scheme-panel,
.ca-avail-panel {
  padding: var(--space-4);
  background: var(--surface-board-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  min-width: 0;
}

.ca-scheme-panel > h3,
.ca-avail-panel > h3 {
  margin: 0 0 var(--space-1);
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  color: var(--text-primary);
}

/* Two columns, split the way the confrontation is: that defence on one side,
   this offence on the other. */
.ca-scheme-duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  align-items: start;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.ca-scheme-col { display: grid; align-content: start; gap: var(--space-3); min-width: 0; }

.ca-scheme-col__head {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-accent);
}

.ca-rate-block {
  padding: var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  min-width: 0;
}

.ca-rate-block h4 {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-rate-block .ca-detail-source-note { margin-bottom: 0; }

.ca-rate-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--type-14);
  font-variant-numeric: tabular-nums;
}

.ca-rate-table td {
  padding: 5px 0;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--grade, var(--text-secondary));
}
.ca-rate-table tr:last-child td { border-bottom: 0; }

/* The bar sits under the label at its own scale, so a column of shares can be
   read by shape before any of the numbers are read at all. */
.ca-rate-bar {
  display: block;
  height: 3px;
  margin-top: 3px;
  background: var(--surface-raised);
  border-radius: var(--radius-pill);
  overflow: hidden;
}

.ca-rate-bar > span {
  display: block;
  height: 100%;
  min-width: 2px;
  background: var(--accent);
  border-radius: var(--radius-pill);
}
.ca-rate-table td.num {
  text-align: right;
  color: var(--text-primary);
  font-weight: 700;
  font-family: var(--font-display);
}

/* The segments are categories, not a scale, so they take the series palette
   rather than anything that reads as good-to-bad. */
.ca-stack {
  display: flex;
  height: 14px;
  border-radius: var(--radius-xs);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
}

.ca-stack__seg { display: block; height: 100%; }

.ca-stack__key {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 3px var(--space-3);
  font-size: var(--type-12);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.ca-stack__key li { display: flex; align-items: center; gap: 5px; }
.ca-stack__key strong { color: var(--text-primary); }

.ca-stack__swatch {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  flex: 0 0 auto;
}

.ca-stack__seg--1, .ca-stack__swatch--1 { background: var(--series-1); }
.ca-stack__seg--2, .ca-stack__swatch--2 { background: var(--series-2); }
.ca-stack__seg--3, .ca-stack__swatch--3 { background: var(--series-3); }
.ca-stack__seg--4, .ca-stack__swatch--4 { background: var(--series-4); }
.ca-stack__seg--5, .ca-stack__swatch--5 { background: var(--series-5); }
.ca-stack__seg--6, .ca-stack__swatch--6 { background: var(--series-6); }
.ca-stack__seg--7, .ca-stack__swatch--7 { background: var(--series-7); }

/* A designation is state, so it reads as a chip rather than as another word in
   the row. Out and doubtful carry the weight; questionable stays quieter. */
.ca-status-pill {
  display: inline-block;
  padding: 1px 7px;
  border-radius: var(--radius-xs);
  border: 1px solid var(--border-default);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  white-space: nowrap;
}

.ca-status-pill[data-status="out"],
.ca-status-pill[data-status="injured-reserve"],
.ca-status-pill[data-status="suspension"],
.ca-status-pill[data-status="suspended"] {
  color: var(--status-error);
  border-color: var(--status-error);
}

.ca-status-pill[data-status="doubtful"],
.ca-status-pill[data-status="pup"] {
  color: var(--status-stale);
  border-color: var(--status-stale);
}

/* --- The named offence ---------------------------------------------------- */
.ca-person-row {
  list-style: none;
  margin: var(--space-3) 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 128px), 1fr));
  gap: var(--space-2);
}

.ca-person {
  display: grid;
  justify-items: center;
  gap: 3px;
  padding: var(--space-2);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  text-align: center;
  min-width: 0;
}

.ca-person__shot {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-pill);
  object-fit: cover;
  background: var(--surface-raised);
  border: 1px solid var(--border-default);
}

.ca-person__slot {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  color: var(--text-accent);
}

.ca-person__name {
  font-size: var(--type-14);
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.25;
  overflow-wrap: anywhere;
}

/* ===========================================================================
 * CARD: VENUE FIRST, WEATHER AS A SYMBOL, NUMBERS THAT CARRY THEIR GRADE
 * ======================================================================== */

/* Where the game is played is the first thing a reader orients on, so it gets
   the top edge of the card rather than fourth place in a row of small facts. */
.ca-matchup-card__venue {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 2px var(--space-2);
  padding: var(--space-2) var(--space-4);
  background: var(--surface-field);
  border-bottom: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  margin: calc(-1 * var(--space-4)) calc(-1 * var(--space-4)) var(--space-3);
}

.ca-matchup-card__venue-name {
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--text-primary);
  min-width: 0;
}

.ca-matchup-card__venue-city {
  font-size: var(--type-12);
  color: var(--text-muted);
  min-width: 0;
}

.ca-matchup-card__venue .ca-status-chip { margin-left: auto; flex: 0 0 auto; }

/* Conditions read as a symbol first and words second. The symbol is a second
   channel, never the only one - the text stays beside it. */
.ca-matchup-card__wx {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--type-12);
  color: var(--text-secondary);
  min-width: 0;
}

.ca-wx {
  flex: 0 0 auto;
  color: var(--text-accent);
}

/* The starter's ERA, graded against the published league baseline, so the
   number says how good it is without the reader having to know the league. */
/* The chip reads on one line. Stacking the value over its label made the
   starter row the tallest block on the card and pushed it out of the 272-350px
   band the style lock sets. */
.ca-matchup-card__arm-era {
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  gap: 4px;
  margin-left: auto;
  padding: 3px 7px;
  min-width: 46px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  flex: 0 0 auto;
}

.ca-matchup-card__arm-era i {
  font-style: normal;
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
}

/* The five-step grade chips, shared lineage with the rest of the desk. They
   colour the number itself and tint its frame; the value is never carried by
   colour alone, because the rank or the label always sits beside it. */

/* --- Chrome on every title and sub-title ---------------------------------
 * The metallic fill was reserved for page h1s while every section heading
 * under them rendered flat white, so a page read as two typographic systems
 * stacked. One treatment now, down to the panel headings.
 *
 * Guarded: without background-clip:text a transparent colour erases the text,
 * so the fill only applies where the browser supports it. Small uppercase
 * labels and table headers are deliberately excluded - a gradient across
 * 11px tracked caps reads as a rendering fault, not as chrome. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ca-public-page__title,
  .ca-opening-desk__title,
  .ca-opening-sport__head h2,
  .ca-detail-section__head h2,
  .ca-detail-team h1,
  .ca-starter-name,
  .ca-lineup-panel > h3,
  .ca-form-panel > h3,
  .ca-arsenal-panel > h3,
  .ca-scheme-panel > h3,
  .ca-avail-panel > h3,
  .ca-bullpen-panel > h3,
  .ca-matchup-card__venue-name,
  .ca-matchup-card__name {
    background: var(--text-display-metal);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

/* The building's own facts ride with its name rather than taking a cell in the
   row below, where they would sit beside things that change hour to hour. */
.ca-matchup-card__venue-tag {
  padding: 1px 6px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Two cells, one row, every card. A three-cell grid left the third alone on a
   row of its own and added sixty pixels of nothing to every card on the page. */
.ca-matchup-card__summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ===========================================================================
 * THE MIRRORED COMPARISON
 *
 * One metric per row, both clubs on one axis, bars growing out from a centre
 * column that names the metric. The reader compares by looking at one line
 * instead of carrying a number across a gutter.
 * ======================================================================== */
.ca-mirror {
  display: grid;
  gap: 0;
  margin: var(--space-3) 0 var(--space-4);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--surface-board-raised);
  overflow: hidden;
}

.ca-mirror__head,
.ca-mirror__row {
  display: grid;
  grid-template-columns:
    minmax(64px, 88px) minmax(0, 1fr) minmax(120px, 190px) minmax(0, 1fr) minmax(64px, 88px);
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.ca-mirror__head {
  grid-template-columns: minmax(0, 1fr) minmax(120px, 190px) minmax(0, 1fr);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-field);
  border-bottom: 1px solid var(--border-default);
}

.ca-mirror__team {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  color: var(--text-primary);
}

.ca-mirror__team--home { justify-content: flex-end; text-align: right; }

.ca-mirror__crest { width: 28px; height: 28px; object-fit: contain; flex: 0 0 auto; }

.ca-mirror__axis {
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-mirror__row {
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}
.ca-mirror__row:last-child { border-bottom: 0; }

.ca-mirror__label {
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
  line-height: 1.25;
}

.ca-mirror__value {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.ca-mirror__value i {
  font-style: normal;
  font-size: var(--type-12);
  font-weight: 600;
  color: var(--text-muted);
}

.ca-mirror__value.is-absent { color: var(--text-muted); font-weight: 600; }

/* The away bar fills from the centre outward, so both bars grow away from the
   label and their tips are what the eye compares. */
.ca-mirror__track {
  display: flex;
  height: 10px;
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  overflow: hidden;
  min-width: 0;
}

/* The away bar grows leftward from the centre so both bars run outward from
   the label and their tips are what the eye compares. */
.ca-mirror__track--away { justify-content: flex-end; }

.ca-mirror__fill {
  display: block;
  height: 100%;
  background: var(--accent);
  min-width: 2px;
}

/* The better season carries the emphasis, so a scan down the column shows who
   wins each row before a single number is read. Never colour alone: the rank
   sits under every value and the bar length says the same thing. */
.ca-mirror__row.is-away .ca-mirror__track--away .ca-mirror__fill,
.ca-mirror__row.is-home .ca-mirror__track--home .ca-mirror__fill {
  background: var(--metric-elite);
}

/* Superseded further down: the losing side used to be dimmed to secondary
   text regardless of how good its season was, which outranked the grade on
   specificity and left a club ranked third in the league drawn in the same
   grey as one ranked thirtieth. The row's winner is carried by the bars. */
.ca-mirror__row.is-away .ca-mirror__value--home,
.ca-mirror__row.is-home .ca-mirror__value--away {
  color: var(--grade, var(--text-secondary));
}

@media (max-width: 720px) {
  /* Stacked, the mirror stops being a mirror, so each row becomes a plain
     three-part line: away, metric, home - still one row per metric. */
  .ca-mirror__head { grid-template-columns: 1fr auto 1fr; gap: var(--space-2); }
  .ca-mirror__axis { display: none; }
  .ca-mirror__row {
    grid-template-columns: minmax(56px, auto) minmax(0, 1fr) minmax(56px, auto);
    padding: var(--space-2) var(--space-3);
  }
  .ca-mirror__row > .ca-mirror__track { display: none; }
  .ca-mirror__value { font-size: var(--type-14); }
}

/* The home value mirrors the away one, so its rank hangs off the same edge as
   its number rather than drifting back toward the centre. */
.ca-mirror__value--home { align-items: flex-end; text-align: right; }

/* --- Headline stats ------------------------------------------------------
 * The four numbers a scout reads first, at the size that says so. Everything
 * behind them stays in the list underneath, where "Batters Faced" belongs. */
.ca-stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 76px), 1fr));
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
}

.ca-stat {
  display: grid;
  gap: 1px;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  text-align: center;
}

.ca-stat__label {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-stat__value {
  font-family: var(--font-display);
  font-size: var(--type-24);
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}

/* --- Tables that can be scanned -----------------------------------------
 * A batting order is read down one column at a time, so the rows alternate
 * and the name column carries the weight. Headers hold at the top of a long
 * scroll instead of leaving the reader guessing which column is which. */
.ca-lineup-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-board-raised);
}

.ca-lineup-table tbody tr:nth-child(even) { background: var(--surface-field); }
.ca-lineup-table tbody tr:hover { background: var(--surface-raised); }

.ca-lineup-table .ca-lineup-slot {
  font-size: var(--type-14);
  color: var(--text-accent);
  text-align: center;
}

/* --- Pitch mix, with weight ---------------------------------------------- */
.ca-arsenal-bar { height: 12px; }

.ca-arsenal-row:first-child .ca-arsenal-name,
.ca-arsenal-row:first-child .ca-arsenal-pct { color: var(--text-primary); }

/* --- The hero, at the scale a hero needs -------------------------------- */
.ca-detail-center strong {
  font-family: var(--font-display);
  font-size: clamp(30px, 2rem + 1.4vw, 50px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}

.ca-detail-team h1 {
  font-size: clamp(22px, 1rem + 1.3vw, 34px);
  line-height: 1.08;
  text-wrap: balance;
}

/* ===========================================================================
 * THE GRADE RAMP - LAST, ON PURPOSE
 *
 * A graded number is applied on top of a component that already sets its own
 * colour (.ca-stat__value, .ca-ctx-value), and at equal specificity the later
 * rule wins. Stated once here at the end of the route layer, the grade always
 * beats the component it decorates instead of silently losing to whichever
 * block happened to be written second.
 *
 * Colour is never the only channel: every graded number has its rank, its
 * label or its bar beside it.
 * ======================================================================== */
/* Each grade publishes its colour as --grade as well as painting itself.
   `.ca-lineup-table td` is one class plus one element, which outranks a bare
   `.c-elite`, so every graded figure inside a table rendered in the default
   text colour and the colour coding silently did nothing. Rather than escalate
   specificity rule by rule, a context that wants to defer to a grade reads the
   custom property with its own colour as the fallback - custom properties are
   not subject to the cascade conflict that caused this. */
.c-elite { --grade: var(--metric-elite); }
.c-good  { --grade: var(--metric-good); }
.c-mid   { --grade: var(--metric-neutral); }
.c-weak  { --grade: var(--metric-weak); }
.c-poor  { --grade: var(--metric-poor); }
.c-na    { --grade: var(--text-muted); }

.c-elite, .c-good, .c-mid, .c-weak, .c-poor, .c-na {
  color: var(--grade);
  border-color: var(--grade);
}

/* Inside a bordered frame the grade tints the frame too; inline in a table it
   must not draw a box round a single figure. */
.ca-ctx-value.c-elite, .ca-ctx-value.c-good, .ca-ctx-value.c-mid,
.ca-ctx-value.c-weak, .ca-ctx-value.c-poor,
.ca-stat__value.c-elite, .ca-stat__value.c-good, .ca-stat__value.c-mid,
.ca-stat__value.c-weak, .ca-stat__value.c-poor { border-color: transparent; }

/* ===========================================================================
 * THE STYLE LOCK'S OWN NUMBERS
 *
 * design/GPT_IMAGE_PROMPTS_CHASE_DESK.md fixes the collapsed card at 272-350px
 * with three compact factual cells. The card had drifted to 449px, and the
 * extra height had been bought by dropping a cell — so it was failing the
 * measurement twice over. The rhythm below holds the whole anatomy the owner
 * has asked for (venue strip, starter faces, three cells) inside the band.
 * ======================================================================== */
.ca-matchup-card {
  /* No max-height. A clamp would squeeze the flex children rather than fail
     loudly, so a longer team name would quietly compress the card instead of
     showing that the rhythm no longer fits. The rhythm does the work, and
     public_site_runtime_diag holds the 272-350px band.

     The target is the middle of that band, not its ceiling. Sitting exactly on
     350 meant CI's font stack rounded one pixel higher than this machine's and
     failed the gate on a rendering difference rather than a design one. */
  gap: 5px;
}

.ca-matchup-card__venue {
  padding: 4px var(--space-3);
  margin: calc(-1 * var(--space-3)) calc(-1 * var(--space-3)) 0;
  flex-wrap: nowrap;
  overflow: hidden;
}

.ca-matchup-card__venue-name,
.ca-matchup-card__venue-city { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ca-matchup-card__venue-city { flex: 0 1 auto; }

/* One line, always. The broadcast has its own cell now, so nothing here wraps. */
.ca-matchup-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-height: 0;
  padding-left: 0;
  white-space: nowrap;
  overflow: hidden;
}

.ca-matchup-card__teams { min-height: 0; padding: 4px var(--space-1); }
.ca-matchup-card__club { padding: var(--space-1) var(--space-2); }

.ca-matchup-card__arm { padding: 3px var(--space-2); }
.ca-matchup-card__arm-era { padding: 1px 6px; min-width: 42px; }

.ca-matchup-card__summary { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.ca-matchup-card__fact {
  padding: 6px var(--space-2);
  min-width: 0;
}
.ca-matchup-card__fact strong {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ca-matchup-card__actions { padding-top: var(--space-1); }

@media (max-width: 720px) {
  /* Stacked, a fixed ceiling would clip; the anatomy is the same, the height
     is whatever one column of it needs. */
  .ca-matchup-card { max-height: none; }
  .ca-matchup-card__summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------------------
 * Violet is reserved.
 *
 * The style lock is explicit: #9A6BFF is for active navigation, the 3px card
 * edge, links and focus - "not data grading". Every bar that describes a
 * number now takes the metric ramp instead, which is also the honest signal:
 * a bar that says how good a rate is should not be the same colour as a link.
 * ------------------------------------------------------------------------ */
.ca-pct-bar__fill,
.ca-arsenal-bar__fill,
.ca-mirror__fill,
.ca-rate-bar > span { background: var(--metric-neutral); }

.ca-mirror__row.is-away .ca-mirror__track--away .ca-mirror__fill,
.ca-mirror__row.is-home .ca-mirror__track--home .ca-mirror__fill {
  background: var(--metric-elite);
}

/* The analysis hero carries the crests at the size the rendering draws them -
   roughly 100px at the outer edges, so identity lands before anything else. */
.ca-detail-team__logo { width: 96px; height: 96px; object-fit: contain; }

@media (max-width: 720px) {
  .ca-detail-team__logo { width: 56px; height: 56px; }
}

/* ===========================================================================
 * STATS WITHOUT BOXES
 *
 * Border, fill and radius each say "separate object". Stamped on every stat
 * cell they said it about forty times on one page, so nothing read as more
 * important than anything else and the numbers themselves fought their own
 * frames for attention.
 *
 * The grouping is carried by a single hairline between cells instead. The
 * panel around the group is still a panel; the cells inside it are just
 * columns of type.
 * ======================================================================== */
.ca-stat,
.ca-form-cell,
.ca-ctx-cell,
.ca-matchup-card__fact {
  background: none;
  border: 0;
  border-radius: 0;
  padding: var(--space-2) var(--space-3);
}

/* One hairline between cells, none on the outside - so the row reads as one
   object divided, not as a strip of separate ones. */
.ca-stat-row,
.ca-form-grid,
.ca-ctx-strip,
.ca-matchup-card__summary {
  gap: 0;
}

.ca-stat + .ca-stat,
.ca-form-cell + .ca-form-cell,
.ca-ctx-cell + .ca-ctx-cell,
.ca-matchup-card__fact + .ca-matchup-card__fact {
  border-left: 1px solid var(--border-subtle);
}

/* When the grid wraps, the cell that starts a new row must not carry a divider
   on its left edge - it is the first of its row, not a continuation. */
.ca-form-grid { row-gap: var(--space-3); }
.ca-stat-row { row-gap: var(--space-2); }

.ca-stat { text-align: left; }
.ca-stat__value { line-height: 1.1; }

/* The ERA chip on a card keeps its frame: it is a badge on a person's row, not
   a cell in a group, and without an edge it would read as loose text beside a
   headshot. */
.ca-matchup-card__arm-era { border: 1px solid var(--border-default); }

/* ===========================================================================
 * DISCLOSURE
 *
 * The legacy Team Rankings board lives here now: inside the matchup, behind a
 * summary, rather than as a public destination of its own. A reader who wants
 * the league gets the league; everyone else gets the two clubs in front of
 * them.
 * ======================================================================== */
.ca-disclosure {
  margin-top: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  background: var(--surface-field);
}

.ca-disclosure > summary {
  cursor: pointer;
  padding: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-accent);
  list-style: none;
}

.ca-disclosure > summary::-webkit-details-marker { display: none; }

.ca-disclosure > summary::after {
  content: " +";
  font-weight: 800;
}
.ca-disclosure[open] > summary::after { content: " \2212"; }

.ca-disclosure > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.ca-disclosure__body {
  padding: 0 var(--space-3) var(--space-3);
  border-top: 1px solid var(--border-subtle);
}
.ca-disclosure__body > .ca-lineup-context { padding-top: var(--space-3); }

/* The rank rides with its value rather than taking a column of its own, so
   thirty rows of seven metrics stay one screen wide. */
.ca-league-table td.num i {
  font-style: normal;
  font-size: var(--type-12);
  font-weight: 600;
  color: var(--text-muted);
  margin-left: 5px;
}

/* The two clubs in this game are marked so they can be found without hunting
   down thirty rows - by weight and a label, not by colour alone. */
.ca-league-table tbody tr.is-here { background: var(--surface-raised); }
.ca-league-table tbody tr.is-here .ca-lineup-name { color: var(--text-primary); font-weight: 800; }

/* ===========================================================================
 * CLUB COLOUR, WHERE IT ANSWERS "WHOSE SIDE IS THIS"
 *
 * The style lock reserves brand violet from data grading, and that rule holds:
 * nothing below encodes how good a number is. What these hues encode is
 * identity - a club's own published colour, on that club's own side of a
 * two-sided chart - so the reader stops counting columns to work out which bar
 * belongs to whom. Length still carries the value and the rank still sits
 * beside it, so the chart survives with the colour removed.
 * ======================================================================== */
.ca-mirror__track--away .ca-mirror__fill[data-club] { background: var(--club-away, var(--metric-neutral)); }
.ca-mirror__track--home .ca-mirror__fill[data-club] { background: var(--club-home, var(--metric-neutral)); }

/* The winning side still takes the emphasis colour: that IS a statement about
   the number, so it overrides identity where the two would compete. */
.ca-mirror__row.is-away .ca-mirror__track--away .ca-mirror__fill,
.ca-mirror__row.is-home .ca-mirror__track--home .ca-mirror__fill {
  background: var(--metric-elite);
}

/* The crest plates in the mirror head carry a hairline of the club's colour,
   so the header states the same identity the bars below it use. */
.ca-mirror__head { border-bottom-width: 1px; }

/* --- Pitch families ------------------------------------------------------
 * An arsenal reads by shape before it reads by number. These are categories -
 * a slider is not "better" than a fastball - so they take the series palette,
 * never the metric ramp. */
.ca-arsenal-row[data-pitch="heat"] .ca-arsenal-bar__fill { background: var(--series-7); }
.ca-arsenal-row[data-pitch="break"] .ca-arsenal-bar__fill { background: var(--series-3); }
.ca-arsenal-row[data-pitch="offspeed"] .ca-arsenal-bar__fill { background: var(--series-4); }
.ca-arsenal-row[data-pitch="other"] .ca-arsenal-bar__fill { background: var(--series-6); }

/* The family is named as well as coloured, so the grouping is never carried by
   hue alone. */
.ca-arsenal-row[data-pitch]::after {
  grid-area: meta;
  justify-self: end;
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.ca-arsenal-row[data-pitch="heat"]::after { content: "Fastball"; }
.ca-arsenal-row[data-pitch="break"]::after { content: "Breaking"; }
.ca-arsenal-row[data-pitch="offspeed"]::after { content: "Offspeed"; }
.ca-arsenal-row[data-pitch="other"]::after { content: "Other"; }

.ca-arsenal-row { grid-template-areas: "name bar pct" "meta meta after"; }
.ca-arsenal-row { grid-template-columns: minmax(88px, 1fr) minmax(60px, 2fr) auto; }

/* ===========================================================================
 * THE OPPONENT'S HISTORY AGAINST THE PITCH
 *
 * A usage share only means something beside what the other lineup has done
 * with that pitch. The rank is a chip so it can be scanned down the column;
 * the number is always printed, so the colour is a second reading of a fact
 * that is already legible without it.
 * ======================================================================== */
.ca-arsenal-opp {
  grid-area: opp;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 3px var(--space-2);
  padding-top: 3px;
  font-size: var(--type-12);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.ca-arsenal-opp__label {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-arsenal-opp strong {
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  color: var(--text-primary);
}

.ca-arsenal-opp__whiff,
.ca-arsenal-opp__n { color: var(--text-muted); }

.ca-arsenal-row {
  grid-template-areas: "name bar pct" "meta meta after" "opp opp opp";
  row-gap: 2px;
}

/* One rank chip, one meaning, everywhere it appears. */
.ca-rank {
  display: inline-block;
  margin-left: 3px;
  padding: 0 5px;
  border-radius: var(--radius-xs);
  border: 1px solid currentColor;
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ===========================================================================
 * LAST TEN GAMES
 *
 * The quickest read of form there is: ten squares, oldest to newest, each one
 * a game with its own score. Won and lost are carried by the letter as well as
 * the colour, so the strip survives being printed in grey.
 * ======================================================================== */
.ca-recent-stack { display: grid; gap: var(--space-3); }

.ca-recent {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}

.ca-recent__team {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  color: var(--text-primary);
}

.ca-recent__crest { width: 24px; height: 24px; object-fit: contain; flex: 0 0 auto; }

.ca-recent__record {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-size: var(--type-18);
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}
.ca-recent__record i {
  font-style: normal;
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-recent__games { display: flex; flex-wrap: wrap; gap: 4px; margin-left: auto; }

.ca-recent__game {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 0;
  min-width: 40px;
  padding: 3px 4px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xs);
  font-variant-numeric: tabular-nums;
}

.ca-recent__game abbr {
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  text-decoration: none;
  border: 0;
}

.ca-recent__game i { font-style: normal; font-size: var(--type-12); color: var(--text-muted); }

.ca-recent__game.is-win { color: var(--metric-elite); border-color: var(--metric-elite); }
.ca-recent__game.is-loss { color: var(--metric-poor); border-color: var(--metric-poor); }

.ca-recent__pending { font-size: var(--type-14); color: var(--text-muted); }

/* ===========================================================================
 * CONDITIONS AS A READING, NOT A SENTENCE
 * ======================================================================== */
.ca-wx-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
}

.ca-wx-tile {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
}

.ca-wx-tile__mark { display: flex; color: var(--text-accent); }
.ca-wx-glyph { display: block; }

.ca-wx-tile__read { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px var(--space-3); }

.ca-wx-tile__read strong {
  font-family: var(--font-display);
  font-size: var(--type-24);
  font-weight: 800;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.ca-wx-tile__cond { font-size: var(--type-14); color: var(--text-secondary); }

.ca-wx-tile__wind {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--type-12);
  color: var(--text-muted);
}

.ca-wx-arrow { flex: 0 0 auto; color: var(--text-accent); }

.ca-wx-note { margin: 0; font-size: var(--type-12); color: var(--text-muted); max-width: 42ch; }

/* ===========================================================================
 * PITCH MIX AS A TABLE
 *
 * Five parallel readings of the same shape, read down a column rather than
 * across a stack of rows. Usage carries a bar and a grade for how heavily the
 * pitch is leaned on; the percentage is printed beside it, so the colour is a
 * second reading of something already legible.
 * ======================================================================== */
.ca-usage {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  justify-content: flex-end;
  min-width: 118px;
}

.ca-usage__bar {
  display: block;
  flex: 1 1 auto;
  min-width: 44px;
  height: 8px;
  background: var(--surface-field);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-xs);
  overflow: hidden;
}

.ca-usage__bar > span { display: block; height: 100%; background: currentColor; }

.ca-usage b {
  font-family: var(--font-display);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  min-width: 46px;
  text-align: right;
}

/* How heavily the pitch is leaned on - not how good it is. */
.u-primary   { color: var(--series-1); }
.u-secondary { color: var(--series-2); }
.u-tertiary  { color: var(--series-3); }
.u-rare      { color: var(--text-muted); }

.ca-arsenal-table td.num { white-space: nowrap; }
.ca-arsenal-table tbody tr:nth-child(even) { background: var(--surface-field); }

/* The most recent outing, and what the arm does to each side of the plate -
   both named in the architecture as starter content and neither previously
   fetched. */
.ca-last-start {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--space-2);
  margin: 0 0 var(--space-3);
  font-size: var(--type-12);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.ca-last-start > span {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-split-block { margin: 0 0 var(--space-3); }

.ca-split-block h4 {
  margin: 0 0 var(--space-2);
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-split-table { min-width: 0; }

/* Ten squares, one per ten per cent. A grid is read at a glance the way a bar
   is not - four filled is "about forty per cent" before the eye reaches the
   number, and the number is printed beside it regardless. */
.ca-usage__grid {
  display: inline-grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 2px;
  flex: 0 0 auto;
}

.ca-usage__grid > i {
  display: block;
  width: 7px;
  height: 12px;
  border-radius: 1px;
  background: var(--surface-raised);
  border: 1px solid var(--border-subtle);
}

.ca-usage__grid > i.is-on { background: currentColor; border-color: currentColor; }

.ca-usage { min-width: 150px; }
.ca-usage__bar { display: none; }

@media (max-width: 720px) {
  .ca-usage__grid > i { width: 5px; height: 10px; }
  .ca-usage { min-width: 120px; }
}

/* ===========================================================================
 * THE TREND LINE
 *
 * The graphic the earlier card carried, rebuilt on what the data holds. Every
 * point's value and its league rank are printed underneath: a chart nobody can
 * read the numbers off is decoration.
 * ======================================================================== */
.ca-spark {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  min-width: 0;
}

.ca-spark__chart {
  display: block;
  flex: 0 0 auto;
  overflow: visible;
}

.ca-spark__chart polyline {
  fill: none;
  stroke: var(--club, var(--metric-neutral));
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.ca-spark__chart circle {
  fill: var(--club, var(--metric-neutral));
}

/* The most recent window is the one being read, so it carries the weight. */
.ca-spark__chart circle.is-now {
  fill: var(--text-primary);
  stroke: var(--club, var(--metric-neutral));
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

.ca-spark__read { display: flex; gap: var(--space-3); flex-wrap: wrap; }

.ca-spark__step {
  display: grid;
  justify-items: center;
  gap: 1px;
  font-variant-numeric: tabular-nums;
}

.ca-spark__step i {
  font-style: normal;
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  color: var(--text-muted);
}

.ca-spark__step b {
  font-family: var(--font-display);
  font-size: var(--type-14);
  font-weight: 800;
  color: var(--text-primary);
}

.ca-spark__step .ca-rank { margin-left: 0; }

@media (max-width: 720px) {
  .ca-spark__chart { width: 120px; }
}

/* ===========================================================================
 * THE MIRROR IS RED AND GREEN
 *
 * Club colour answered "whose bar is this" and left the reader working out
 * which side was better. Two colours with one meaning instead: green leads the
 * row, red trails it. The rank under every value says the same thing, so the
 * chart survives with the colour removed.
 * ======================================================================== */
.ca-mirror__fill,
.ca-mirror__fill[data-club] { background: var(--metric-poor); }

.ca-mirror__row.is-away .ca-mirror__track--away .ca-mirror__fill,
.ca-mirror__row.is-home .ca-mirror__track--home .ca-mirror__fill {
  background: var(--metric-elite);
}

/* The figure and its rank grade themselves against the thirty-club pool, the
   same ramp every other number on this page uses.
 *
 * They used to take the row's winner: the losing side went red whatever it had
 * done, so a club ranked 16th of 30 was painted the colour of failure because
 * the other club was 15th - while three sections up red meant "poor". Two
 * different meanings for the same colour on the same page is worse than no
 * colour at all.
 *
 * Which side leads is still shown, and shown better: the winning bar fills
 * green and the losing bar red, so the comparison is read off the bars - where
 * length already carries it - and the grade is read off the numbers. */
.ca-mirror__row .ca-mirror__value { color: var(--grade, var(--text-primary)); }
.ca-mirror__value i { color: inherit; opacity: 0.78; }

/* ===========================================================================
 * TEAM PROFILE RADAR
 *
 * Two webs, both clubs on each. Every axis is a percentile, which is the only
 * honest way to put OSI, wRC+ and xwOBA on one shape. Away and home take the
 * same two colours as the mirror, so a reader who has learned one has learned
 * the other.
 * ======================================================================== */
/* Two webs, side by side and close enough to be read as a pair. An auto-fit
   grid across the full panel width left a third of the section empty between
   them, which made two shapes look like two unrelated charts. */
.ca-radar-duo {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-4) var(--space-6);
  margin-bottom: var(--space-3);
}

.ca-radar-duo > .ca-radar { flex: 0 1 360px; max-width: 100%; }
.ca-radar svg { width: 100%; height: auto; max-width: 360px; }

.ca-radar { margin: 0; display: grid; justify-items: center; gap: var(--space-2); }

.ca-radar figcaption {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}

.ca-radar svg { overflow: visible; }

.ca-radar__ring { fill: none; stroke: var(--border-subtle); stroke-width: 1; }
.ca-radar__spoke { stroke: var(--border-subtle); stroke-width: 1; }

.ca-radar__area { stroke-width: 2; fill-opacity: 0.18; vector-effect: non-scaling-stroke; }
.ca-radar__area.is-away { stroke: var(--series-1); fill: var(--series-1); }
.ca-radar__area.is-home { stroke: var(--series-4); fill: var(--series-4); }

.ca-radar__label {
  font-family: var(--font-display);
  font-size: var(--type-12);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  fill: var(--text-secondary);
}

.ca-radar-key {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px var(--space-3);
  margin: 0 0 var(--space-3);
  font-size: var(--type-12);
  color: var(--text-secondary);
}

.ca-radar-key__swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: 5px;
}
.ca-radar-key__swatch.is-away { background: var(--series-1); }
.ca-radar-key__swatch.is-home { background: var(--series-4); }

/* --- pitch count by day ------------------------------------------------- */
.ca-pc-table td.num, .ca-pc-table th.num { min-width: 44px; text-align: center; }
.ca-pc { font-family: var(--font-display); font-weight: 800;
         font-variant-numeric: tabular-nums; color: var(--text-muted); }
/* A workload ramp, dim to hot - deliberately NOT the green-to-red grade scale
   the stat columns use. Fifteen pitches is a light day, not a good one, and
   painting it the green that means "elite" elsewhere on the page would assert
   something nobody measured. Only the top two steps take a hue, because only
   the top two steps are what a reader is scanning the grid for. */
.ca-pc, .ca-pc-total { transition: none; }
.ca-pc.p-zero  { color: var(--text-disabled); font-weight: 600; }
.ca-pc.p-touch { background: var(--surface-raised); color: var(--text-secondary); }
.ca-pc.p-light { background: var(--surface-elevated); color: var(--text-primary); }
.ca-pc.p-full  { background: var(--tint-caution); color: var(--metric-watch); }
.ca-pc.p-heavy { background: var(--tint-negative); color: var(--metric-poor); }

/* The two summary columns take the same ramp on thresholds scaled to the days
   they cover, and keep their heavier frame so the eye still reads them as
   totals rather than as two more days. */
.ca-pc-total.p-zero  { color: var(--text-disabled); }
.ca-pc-total.p-full  { color: var(--metric-watch); }
.ca-pc-total.p-heavy { color: var(--metric-poor); }
.ca-pc-total { font-family: var(--font-display); font-weight: 800;
               color: var(--text-primary); background: var(--surface-field);
               font-variant-numeric: tabular-nums; }
.ca-bullpen__crest { width: 22px; height: 22px; object-fit: contain; margin-right: 6px; }
.ca-bullpen-panel > h3 { display: flex; align-items: center; }

/* --- conditions in the banner ------------------------------------------- */
.ca-wx-fact { display: inline-flex; align-items: center; gap: 6px; }
.ca-wx-glyph--sm { width: 18px; height: 18px; color: var(--text-accent); }

/* ---------------------------------------------------------------------------
 * CARD HEIGHT: ONE LONG NAME MUST NOT RAISE THE WHOLE ROW
 *
 * Grid rows stretch to their tallest member, so "Los Angeles Dodgers" wrapping
 * to a second line, or a two-line pitcher name, pushed every card in the row
 * past the 350px ceiling the style lock fixes - and the extra height was blank
 * space on the other eleven cards. Both names clamp to two lines and then
 * ellipsis, which holds the card inside its band without hiding a club: the
 * crest is beside the name and the full text stays in the title attribute.
 * ------------------------------------------------------------------------ */
.ca-matchup-card__name,
.ca-matchup-card__arm-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  min-width: 0;
}

/* A pitcher's name is short enough to sit on one line at this size; when one
   does not, ellipsis costs a surname and saves seventeen points of height on
   every card in the row. The club name keeps its two lines - truncating
   "Los Angeles Do..." is not a trade worth making. */
.ca-matchup-card__arm-name {
  -webkit-line-clamp: 1;
  line-clamp: 1;
}

/* ---------------------------------------------------------------------------
 * CARD HEIGHT BUDGET
 *
 * The style lock caps the collapsed card at 350px and the card had reached
 * 348 - inside the band, but with no room for the font-metric difference
 * between this machine and CI, which is the exact one-pixel gap that failed a
 * deploy once already. The two points below are whitespace, not content: the
 * stack gap comes down a point, and the collapsed detail drawer stops
 * reserving a gap while it is empty. That is about fourteen points of
 * headroom, and the card reads no tighter for it.
 * ------------------------------------------------------------------------ */
.ca-matchup-card { gap: 4px; }

/* The drawer carries the `hidden` attribute when collapsed, but a display rule
   on the class overrode the UA's `display:none`, so a hidden element was still
   a flex item claiming a gap. It is now actually hidden when it says it is. */
.ca-matchup-card__expand[hidden] { display: none; }

/* The venue strip runs one line of 14px display type but inherited the page's
   body line-height, so it reserved 36 points for an 18-point line. Setting the
   leading it actually needs returns the last of the headroom. */
.ca-matchup-card__venue { line-height: 1.3; }
.ca-matchup-card__venue .ca-status-chip { line-height: 1.2; }

/* ---------------------------------------------------------------------------
 * TABLE COLUMN WIDTHS
 *
 * `width: 100%` on a table with one long text column and several short numeric
 * ones gives every spare pixel to the text column, so a nine-row batting order
 * sat with its name column 700px wide and its four rate columns crowded into
 * the right margin - four numbers a reader is asked to compare down the page,
 * placed as far from each other as the panel allows.
 *
 * The numeric columns take a fixed share and the name column absorbs what is
 * left, which is the arrangement the eye needs: the figures line up in narrow
 * tracks close enough to scan across as well as down.
 * ------------------------------------------------------------------------ */
.ca-lineup-table th.num,
.ca-lineup-table td.num { width: 4.5rem; }

.ca-lineup-table thead th:first-child,
.ca-lineup-table tbody td:first-child { width: 2.5rem; }

/* The batter's name is the one column that should take the slack. */
.ca-lineup-table .ca-lineup-name { width: auto; }

/* The pitch-count matrix is the exception: it is all numbers, so its day
   columns stay on the narrower track they set for themselves. */
.ca-pc-table th.num,
.ca-pc-table td.num { width: 3.25rem; }

/* Splits carry ten columns in a panel half the page wide; each needs less. */
.ca-split-table th.num,
.ca-split-table td.num { width: 3.5rem; }

/* The split label is shorthand and must stay on its line; if a longer label
   ever lands here the table scrolls rather than growing three rows tall. */
.ca-split-table tbody td:first-child,
.ca-split-table thead th:first-child { white-space: nowrap; width: 5rem; }
