.cards {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  margin: 0; padding: 0; list-style: none;
}
.card {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--surface); border: 1px solid var(--ring);
  border-radius: 10px; padding: 18px 18px 16px;
  text-decoration: none; color: inherit;
  transition: border-color .12s ease, transform .12s ease;
}
a.card:hover { border-color: var(--rule); transform: translateY(-1px); }
a.card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.card h2 {
  margin: 0; font-family: var(--sc-display); font-size: 22px; font-weight: 700;
  line-height: 1.05; letter-spacing: .01em;
}
.card p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.card .meta {
  margin-top: auto; padding-top: 10px;
  font-size: 11px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--ink-muted); font-variant-numeric: tabular-nums;
}
.card .row { display: flex; align-items: center; gap: 8px; }
.tag {
  font-size: 10px; font-weight: 650; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; white-space: nowrap;
}
.tag.live    { color: #006300; background: rgba(12,163,12,.12); }
.tag.planned { color: var(--ink-muted); background: var(--row-hover); }
:root[data-theme="dark"] .tag.live { color: #0ca30c; }
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .tag.live { color: #0ca30c; }
}
.card.planned { opacity: .72; }

/* ---- card thumbnails ------------------------------------------------
   Drawn from real data by build_thumbs.py. The field tokens are the page's
   own, copied value-for-value, so the card inherits the audit those colours
   already passed rather than inventing a second palette that has to be
   re-checked -- and so it keeps looking like the page it previews. */
:root {
  --t-grass:  #eef1f5;
  --t-stands: #e6e9ee;
  --t-fence:  #39424e;
  --t-chalk:  #58616d;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    --t-grass:#191e25; --t-stands:#151a20; --t-fence:#c2ccd8; --t-chalk:#99a3af;
  }
}
:root[data-theme="dark"] {
  --t-grass:#191e25; --t-stands:#151a20; --t-fence:#c2ccd8; --t-chalk:#99a3af;
}

.cards > li { display: flex; }
.card { gap: 0; flex: 1; }
.thumb {
  margin: -18px -18px 14px; border-bottom: 1px solid var(--ring);
  border-radius: 10px 10px 0 0; overflow: hidden;
  background: var(--row-hover); line-height: 0;
}
.thumb-svg { display: block; width: 100%; height: auto; }

/* A planned card has nothing to preview. Say that deliberately -- a faint
   hatch at the same aspect as a real thumbnail -- rather than leaving a flat
   panel that reads as a broken image. */
.thumb-empty {
  aspect-ratio: 300 / 190; background: var(--row-hover);
  background-image: repeating-linear-gradient(
    -45deg, transparent 0 7px, var(--ring) 7px 8px);
}
.card-body { display: flex; flex-direction: column; gap: 8px; flex: 1; }

/* leaderboard grid */
.t-name { fill: var(--ink); opacity: .16; }
/* the debut slash line, on the same outcome wheel the Finder's card uses */
.t-slash { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.th-avg { stroke: var(--ink-muted); stroke-dasharray: 5 3; }
.th-obp { stroke: var(--accent); }
.th-slg { stroke: var(--sc-hum); }

/* The duck pond's diamond. Each bag takes its own weight of the same ink, so
   the three read as one shape rather than three colours, and the league's
   outline is the one line meant to be compared against. */
/* The fill is the ramp class; the stroke is the card's own ground, so four
   quadrants meeting at home read as four rather than one blot. */
.t-bag { stroke: var(--surface); stroke-width: 1.5; }
/* Solid, the way the page draws them: base paths first, statistical frame
   second. Ink rather than the brand red -- on the page these lines take the
   ink of the quadrant they lie in, and a red that is not one of the ramp's
   reds would read as a fourth colour on a card that has three. */
.t-league { fill: none; stroke: var(--ink); stroke-width: 1.4; opacity: .55; }
.t-plate { fill: var(--ink); opacity: .55; }

/* a park on the map card: the page's ground with an ink ring, so a dot reads
   on a warm patch and on a cold one alike */
.t-dot { fill: var(--plane); stroke: var(--ink); stroke-width: 3; opacity: .75; }
.tc0{fill:var(--b0)}  .tc1{fill:var(--b1)}  .tc2{fill:var(--b2)}
.tc3{fill:var(--b3)}  .tc4{fill:var(--b4)}  .tc5{fill:var(--b5)}
.tc6{fill:var(--b6)}  .tc7{fill:var(--b7)}  .tc8{fill:var(--b8)}
.tc9{fill:var(--b9)}  .tc10{fill:var(--b10)}

/* batted-ball field: the page's spray overlay */
.t-stands { fill: var(--t-stands); }
.t-fair   { fill: var(--t-grass); }
.t-wall   { fill: none; stroke: var(--t-fence); stroke-width: 1.3; opacity: .9; }
.t-foul   { fill: none; stroke: var(--t-chalk); stroke-width: 1.1; opacity: .75; }

/* heartbreak hotel: club lines. Each line brings its own light and dark
   colour (--l / --d) from build_thumbs.py, solved against this ground. */
.t-season { stroke: var(--rule); stroke-width: .6; }
.t-line   { fill: none; stroke: var(--l); stroke-linejoin: round; stroke-linecap: round; }
.t-avg    { stroke-width: 1.1; }
.t-dim    { stroke-width: .7; }
.t-picked { stroke-width: 1.7; }
:root[data-theme="dark"] .t-line { stroke: var(--d); }
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .t-line { stroke: var(--d); }
}

@media (prefers-reduced-motion: reduce) { a.card:hover { transform: none; } }

/* a screenshot thumbnail, one image per theme */
.thumb-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.thumb-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .thumb-light { display: none; }
  :root:where(:not([data-theme="light"])) .thumb-dark { display: block; }
}
:root[data-theme="dark"] .thumb-light { display: none; }
:root[data-theme="dark"] .thumb-dark { display: block; }
