.rating-card {
  border: 1px solid var(--border);
  padding: var(--s5);
  background: var(--surface-1);
  border-radius: var(--r-2);
  box-shadow: var(--shadow-1);
}
.rating-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s4);
}
.rating-card__context {
  margin-inline-start: auto;
  color: var(--ink-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
}
/* Every score starts on the same left rule. Standing is carried by the tier
   color, never by how far across the card the number floats: one card in the
   middle band read as a layout bug beside seven flush-left siblings. */
.rating-score {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: start;
  gap: var(--s2);
  padding: var(--s3) 0 var(--s4);
  border-bottom: 1px solid var(--border);
}
.rating-score__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-h2);
}
.rating-card[data-tier="directive"] .rating-score__value { color: var(--tier-directive); }
.rating-card[data-tier="suggestive"] .rating-score__value { color: var(--tier-suggestive); }
.rating-card[data-tier="descriptive"] .rating-score__value,
.rating-card[data-tier="empty"] .rating-score__value { color: var(--tier-descriptive); }
.rating-card__support,
.rating-score__baseline,
.rating-score__trend,
.rating-score__placement {
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  text-align: start;
}
.rating-card__support { margin: 0 0 var(--s4); }
.rating-card__face {
  display: grid;
  gap: var(--s3);
  padding: var(--s4) 0;
}
.rating-card__measure-face {
  border-inline-start: var(--s1) solid var(--tier-descriptive);
  padding-inline-start: var(--s3);
}
.rating-card__measure-face[data-tier="scored"] { border-inline-start-color: var(--tier-suggestive); }
.rating-face {
  display: grid;
  grid-template-columns: minmax(12ch, 1fr) auto minmax(14ch, auto);
  align-items: baseline;
  gap: var(--s2) var(--s4);
  margin: 0;
}
.rating-face__name { font-weight: var(--fw-semi); }
.rating-face__you,
.rating-face__vs {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.rating-face__you { font-weight: var(--fw-semi); }
.rating-face__vs { color: var(--ink-muted); }
.rating-face__action,
.rating-face__reason {
  margin: var(--s2) 0 0;
  font-size: var(--fs-sm);
}
.rating-face__reason { color: var(--ink-muted); }
/* A summary set to `display:flex` is no longer a list item, so the browser
   draws no ::marker and the control reads as a bold label — which is how every
   denominator, evidence round and method note ended up behind something a
   reader had no reason to open. Each rating expander draws the same triangle
   itself and keeps a 40px target. One rule for all three, so they cannot drift
   apart again. */
.rating-card summary,
.rating-method summary,
.rating-graph__values summary {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: calc(var(--s5) + var(--s4));
  padding-block: var(--s3);
  cursor: pointer;
  font-weight: var(--fw-semi);
  list-style: none;
}
.rating-card summary::-webkit-details-marker,
.rating-method summary::-webkit-details-marker,
.rating-graph__values summary::-webkit-details-marker { display: none; }
.rating-card summary::before,
.rating-method summary::before,
.rating-graph__values summary::before {
  content: "▶";
  flex: none;
  /* The 11px floor (nit 27) counts a drawn pseudo-element too, and this one is
     drawn type. It sits at the floor rather than under it. */
  font-size: var(--fs-xs);
  line-height: 1;
  color: var(--ink-muted);
  transition: transform 120ms ease;
}
.rating-card details[open] > summary::before,
.rating-method[open] > summary::before,
.rating-graph__values[open] > summary::before { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) {
  .rating-card summary::before,
  .rating-method summary::before,
  .rating-graph__values summary::before { transition: none; }
}
.rating-card a:focus-visible,
.rating-card button:focus-visible,
.rating-card summary:focus-visible,
.rating-method summary:focus-visible { outline: var(--focus-ring); }
/* An auto grid track grows to its widest child's min-content width, so at
   390px the rows pushed this box 27px past its own edge with no scroller to
   reach it. The track is bounded and every row may shrink inside it. */
.rating-measures {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s4);
}
.rating-measure {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s3);
  min-width: 0;
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-1);
  background: var(--surface-2);
}
.rating-measure > * { min-width: 0; }
/* The chip is one nowrap flex line, so at 390px its value, whisker and meta
   ran past the row with nothing to scroll. It wraps inside a rating card, the
   way it already does inside a stat tile. */
.rating-measure .ratechip,
.rating-measure .ratechip__meta { flex-wrap: wrap; max-width: 100%; }
.rating-measure__facts {
  display: grid;
  gap: var(--s1);
  color: var(--ink-muted);
  font-size: var(--fs-sm);
}
.rating-measure__facts p,
.rating-review { margin: 0; }
.rating-review { color: var(--ink-muted); }
.rating-evidence {
  display: grid;
  gap: var(--s3);
  padding-inline-start: var(--s5);
  margin: var(--s5) 0;
}
.rating-evidence__item { padding-inline-start: var(--s2); }
.rating-evidence__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s3);
}
.rating-evidence__outcome {
  color: var(--ink-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  text-transform: uppercase;
}
.rating-evidence__item p { margin: var(--s2) 0; }
.rating-rep {
  border-inline-start: var(--s1) solid var(--ink);
  padding-inline-start: var(--s4);
  margin-block: var(--s4);
}
.rating-rep p { margin-block: var(--s2); }
.rating-rep__source { color: var(--ink-muted); font-size: var(--fs-xs); }
.rating-rep-details {
  display: grid;
  gap: var(--s2);
  margin-block: var(--s4);
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-1);
  background: var(--surface-2);
}
.rating-rep-details > * { margin: 0; }
.rating-headline {
  display: grid;
  justify-items: start;
  gap: var(--s2);
  min-width: 0;
}
.rating-headline > * { margin: 0; }
/* A sentence, not a label token: no uppercasing, which would also change what
   the page reads back to the numeric-context guard. */
.rating-headline__label {
  font-size: var(--fs-sm);
  color: var(--ink-muted);
}
.rating-headline__score {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-h1);
  line-height: 1;
}
.rating-headline__support,
.rating-headline__tracks {
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  max-width: 42ch;
}
.rating-method {
  margin-top: var(--s5);
  border-block: 1px solid var(--border);
}
.rating-method ul { display: grid; gap: var(--s3); padding: 0 0 var(--s5) var(--s5); }

.progress-track-select {
  display: flex;
  align-items: center;
  gap: var(--s3);
}
.progress-track-select__label {
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
}
/* The player row is the page's title as well as its switcher, so the page
   carries one player control instead of a heading that repeats it. */
.hub-progress .c-player-tabs { align-items: baseline; }
.hub-progress .c-player-tabs__current { margin: 0; }
.hub-progress .c-player-tabs__current a {
  min-height: 0;
  padding-inline: var(--s2);
  font: inherit;
  color: var(--ink);
}
/* An auto grid track takes its content's max-content width, so the expanded
   values table would otherwise push the card and the plot past the screen. */
.progress-track {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s5);
  min-width: 0;
  margin-block: var(--s5);
}
.progress-others { margin-block: var(--s5); }
.progress-others__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s1);
  margin: var(--s3) 0 0;
  padding: 0;
  list-style: none;
}
.progress-other {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 16ch);
  align-items: baseline;
  gap: var(--s2) var(--s4);
  padding-block: var(--s3);
  border-top: 1px solid var(--border);
}
.progress-other__score {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.progress-other__why {
  color: var(--ink-muted);
  font-size: var(--fs-sm);
}
.rating-graph {
  min-width: 0;
  max-width: 688px;
  margin: 0;
  padding: var(--s5);
  border: 1px solid var(--border);
  border-radius: var(--r-2);
  background: var(--surface-1);
  box-shadow: var(--shadow-1);
}
/* The viewBox is sized from this box, so the plot is never scaled and its type
   renders at the size it is set in. Cap the width so two points do not stretch
   across a 1440px card. */
.rating-graph__chart { max-width: 640px; }
.rating-graph__plot { display: block; width: 100%; height: 200px; }
.rating-graph__grid { stroke: var(--grid); stroke-width: 1; }
.rating-graph__label {
  fill: var(--ink-muted);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
}
.rating-graph__line {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rating-graph__dot { fill: var(--ink-muted); }
.rating-graph__dot--reconstructed {
  fill: var(--surface-1);
  stroke: var(--ink-muted);
  stroke-width: 1.5;
}
.rating-graph--empty {
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  color: var(--ink-muted);
}
.rating-graph--empty p { margin: 0; }
.rating-graph__recon-tag {
  margin-inline-start: var(--s2);
  color: var(--ink-muted);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
}
.rating-graph__boundary {
  stroke: var(--border-strong);
  stroke-width: 1;
  stroke-dasharray: 4 4;
}
.rating-graph__boundary-label {
  fill: var(--ink-muted);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
}
.rating-graph figcaption,
.rating-graph__gap-note,
.rating-graph__boundaries { color: var(--ink-muted); font-size: var(--fs-sm); }
.rating-graph__gap-note { margin-block: var(--s2); }
.rating-graph__boundaries { margin-block: var(--s2); padding-inline-start: 0; list-style: none; }
.rating-graph__values { min-width: 0; margin-top: var(--s4); }
.rating-graph__values summary:focus-visible { outline: var(--focus-ring); }
.rating-graph__table-wrap { min-width: 0; max-width: 100%; overflow-x: auto; }
.rating-graph__table-wrap:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rating-graph__table { min-width: max-content; }
.rating-graph__table th,
.rating-graph__table td {
  white-space: nowrap;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.progress-periods { margin-block: var(--s5); border-top: 1px solid var(--border); }
.progress-period {
  display: grid;
  grid-template-columns: minmax(0, 12ch) minmax(0, 1fr);
  align-items: baseline;
  gap: var(--s2) var(--s4);
  padding-block: var(--s3);
  border-bottom: 1px solid var(--border);
}
.progress-period h2 { margin: 0; font-size: var(--fs-h3); }
.progress-period p { margin: 0; color: var(--ink-muted); }

.practice-items,
.practice-card-grid,
.rating-shared-players,
.rating-shared-details {
  display: grid;
  gap: var(--s5);
}
.practice-items { margin-block: var(--s5); }
.practice-card-grid { grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr)); }
.practice-empty { display: grid; justify-items: start; gap: var(--s3); max-width: 44rem; }
.practice-empty p { margin: 0; max-width: 48ch; }
/* `C.select` wraps its control in a block `label.c-field`, which `flex: 1`
   then stretches to the page: the three-option period control measured
   1,183px at 1440. It needs no more room than its longest option. */
.hub-practice > .c-top-summary > .c-field { flex: 0 0 auto; min-width: 11rem; max-width: 16rem; }
.rating-card--shared-practice { grid-column: 1 / -1; }
.rating-shared-players { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.rating-shared-player {
  display: grid;
  gap: var(--s3);
  min-width: 0;
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r-1);
  background: var(--surface-2);
}
.rating-shared-player > * { margin: 0; }

/* The plot caps at 640px inside a 688px card, so on a wide band the open track
   used to sit alone with half the row empty and the other tracks below the
   fold. From 1200 up the list reads beside the graph instead; the page's own
   gap is the column gap, so the two sections drop their block margins. */
@media (min-width: 1200px) {
  /* `.c-page` sets the column flex in a later sheet, so the page's own class
     carries the grid. */
  .c-page.hub-progress {
    display: grid;
    grid-template-columns: minmax(0, 688px) minmax(0, 1fr);
    align-items: start;
  }
  .c-page.hub-progress > * { grid-column: 1 / -1; }
  .c-page.hub-progress > .progress-track { grid-column: 1; margin-block: 0; }
  .c-page.hub-progress > .progress-others { grid-column: 2; margin-block: 0; }
  .c-page.hub-progress > .progress-others > h2 { margin-top: 0; }
}

@media (max-width: 480px) {
  .rating-card { padding: var(--s4); }
  .rating-face { grid-template-columns: minmax(0, 1fr) auto; }
  .rating-face__vs { grid-column: 1 / -1; }
  .progress-track-select { align-items: flex-start; flex-direction: column; }
  .progress-other { grid-template-columns: minmax(0, 1fr) auto; }
  .progress-period { grid-template-columns: minmax(0, 1fr); }
  .progress-other__why { grid-column: 1 / -1; }
  .rating-card__head { align-items: flex-start; }
  .rating-card__context { width: 100%; margin-inline-start: 0; }
  .rating-shared-players { grid-template-columns: minmax(0, 1fr); }
  .rating-graph { padding: var(--s3); }
}

@media (prefers-reduced-motion: reduce) {
  .rating-card,
  .rating-card * { animation: none; transition: none; scroll-behavior: auto; }
}
