/* <contest-grid> — self-theming.
 *
 * The element appears on two surfaces with different palettes: the incumbent
 * site (global.css) and the logbook (/v2). Neutrals read a host variable first
 * and fall back to a literal, so the figure inherits whichever system it lands
 * in without either stylesheet knowing about it.
 *
 * Family colours default to the published matplotlib legend — blue foundation, gold naive — so
 * the element matches the rasters on whichever page it lands. A host that has a reason to
 * reassign them overrides the four variables below; /v2 does, in logbook.css, and explains why
 * there. Nothing in this file assumes either assignment. */

contest-grid {
  --cg-foundation: #3B82F6;
  --cg-naive: #D4A843;
  --cg-classical: #C084FC;
  --cg-ml: #8A99AF;

  --cg-void: color-mix(in srgb, currentColor 8%, transparent);
  --cg-rule: color-mix(in srgb, currentColor 16%, transparent);
  --cg-dim: color-mix(in srgb, currentColor 60%, transparent);
  --cg-accent: var(--foil, var(--gold, #D4A843));
  /* The ring on a read cell. Not currentColor: inside .cg-cell that is the near-black label
     ink, which is invisible against the cloth outside the cell. */
  --cg-ring: var(--ink, var(--text, #EDEAE3));
  /* Focus is not selection. Both states drew the same 2px ink ring, so after clicking one cell
     and tabbing to another two cells read as "the one being described" while the aria-live
     readout described only the focused one. Focus takes the host's documented focus colour
     where there is one — on /v2 that is --foil-lit, which is what DESIGN.md specifies for
     :focus-visible everywhere else. A host without it keeps the ink ring, unchanged. */
  --cg-focus: var(--foil-lit, var(--cg-ring));

  display: block;
  margin: 2.5rem 0;
  container-type: inline-size;
}

/* Fallback content (the published static figure) until the data arrives. */
contest-grid > img { max-width: 100%; height: auto; }

/* Inside a plate mount the surrounding frame owns the spacing. */
contest-grid[variant='strip'] { margin: 0; }

.cg-head { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.cg-count {
  font-size: clamp(1.8rem, 1.3rem + 1.9vw, 2.7rem);
  font-weight: 700; letter-spacing: -0.03em; line-height: 1;
  color: var(--cg-accent);
  font-variant-numeric: tabular-nums;
}
.cg-sub { color: var(--cg-dim); font-size: 0.95rem; }

/* Ten rows, four columns, a label column — the published chart's own shape. */
.cg-table { display: grid; gap: 4px; }
.cg-row {
  display: grid;
  grid-template-columns: minmax(6.5rem, 11rem) repeat(4, minmax(0, 1fr));
  gap: 4px;
  align-items: stretch;
}
.cg-row-head { margin-bottom: 2px; }

.cg-rowhead {
  display: flex; align-items: center; justify-content: flex-end;
  text-align: right;
  font-size: 0.8rem; line-height: 1.25; color: var(--cg-dim);
  padding-right: 0.5rem;
}
.cg-colhead {
  display: flex; align-items: flex-end; justify-content: center;
  font-size: 0.78rem; color: var(--cg-dim); letter-spacing: 0.02em;
}

.cg-cell {
  appearance: none; border: 0; margin: 0; font: inherit;
  padding: 0.62rem 0.4rem;
  border-radius: 4px;
  font-size: 0.82rem; font-weight: 700; line-height: 1.2;
  text-align: center;
  /* Every family fill is light enough to need dark type; the published figure
     does the same. */
  color: #06070A;
  background: var(--cg-void);
  /* Opacity and transform only — never a layout property. */
  opacity: 0; transform: translateY(5px);
  /* No per-cell transition-delay. A 38-cell stagger at 11ms took ~790ms to
     settle — three quarters of a second of arrival animation in front of a
     figure whose entire job is to be read, at the moment the reader is deciding
     whether to believe it. The count-up stays: it animates the headline number
     itself, which is meaning rather than arrival. */
  transition: opacity 0.35s ease-out, transform 0.35s ease-out, outline-color 0.15s;
  outline: 2px solid transparent; outline-offset: 2px;
}
.cg.is-live .cg-cell { opacity: 1; transform: none; }

button.cg-cell { cursor: pointer; }
.is-foundation { background: var(--cg-foundation); }
.is-naive { background: var(--cg-naive); }
.is-classical { background: var(--cg-classical); }
.is-ml { background: var(--cg-ml); }
.is-void {
  background: var(--cg-void); color: var(--cg-dim);
  font-weight: 400; font-style: italic; font-size: 0.76rem;
}

/* Reading one contest used to drop the other 37 to opacity 0.45, which put their winner labels
   at roughly 2:1 against the page — and on touch there is no hover to release it, so a phone
   reader who tapped one cell was left with a figure whose other 37 answers were unreadable
   until they tapped again. Every workable dim fails the floor for at least one family, so the
   read cell is raised instead of the rest being lowered: a ring in page ink, which is legible
   over every fill and over the cloth between them. */
button.cg-cell:hover,
.cg-cell.is-pinned { outline-color: var(--cg-ring); }
.cg-cell.is-pinned { outline-width: 2px; }
/* Last, so a focused cell reads as focused even when it is also the pinned one. */
button.cg-cell:focus-visible { outline-color: var(--cg-focus); }

.cg-legend {
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.15rem;
  margin-top: 1.25rem; font-size: 0.82rem; color: var(--cg-dim);
}
.cg-legend span { display: inline-flex; align-items: center; gap: 0.45rem; }
.cg-legend i { width: 11px; height: 11px; border-radius: 2px; display: inline-block; }
.cg-legend .k-foundation { background: var(--cg-foundation); }
.cg-legend .k-naive { background: var(--cg-naive); }
.cg-legend .k-classical { background: var(--cg-classical); }
.cg-legend .k-ml { background: var(--cg-ml); }

.cg-note {
  margin-top: 0.7rem; font-size: 0.8rem; line-height: 1.55;
  color: var(--cg-dim); max-width: 62ch;
}

/* Reserved height so the readout appearing never reflows the page around it. 3em was measured
   against a wide viewport: at 390px the longest generated sentences (the ties on BTC log returns
   and Bangkok PM2.5) wrap to four lines, so the figure grew 547 -> 559 -> 580 as a finger moved
   across the grid and everything below it — legend, footnote, the next caption — shifted with
   it. The reservation is now sized to the worst case at each width. */
.cg-read {
  margin-top: 0.8rem;
  /* Sized to the longest string the generator can emit — 138 characters, the Earthquake
     magnitudes 1-day tie — plus the 0.7rem padding and the rule, since box-sizing is
     border-box. Two lines wide, three narrow. */
  min-height: 4.2em;
  font-size: 0.88rem; line-height: 1.5;
  border-top: 1px solid var(--cg-rule); padding-top: 0.7rem;
  color: inherit;
}
@media (max-width: 700px) { .cg-read { min-height: 5.6em; } }
.cg-read-hint { color: var(--cg-dim); }

@container (max-width: 620px) {
  .cg-row { grid-template-columns: minmax(5rem, 7.5rem) repeat(4, minmax(0, 1fr)); }
  .cg-rowhead { font-size: 0.68rem; }
  .cg-cell { font-size: 0.66rem; padding: 0.5rem 0.15rem; }
  .cg-colhead { font-size: 0.68rem; }
}

/* A second step, because one was not enough: at 390px "AutoTheta" measured 53.0px inside a
   48.7px content box and rendered past the cell's rounded corner; at 360px "Chronos-2" cleared
   its box by 5.5px on several cells, and at 320px 25 of the 38 labels overflowed. The site's
   flagship evidence figure was visibly broken on common Android widths. The label column gives
   back width, the type steps down once more, and a name that still will not fit wraps instead
   of spilling. */
@container (max-width: 430px) {
  .cg-row { grid-template-columns: minmax(4.25rem, 6.5rem) repeat(4, minmax(0, 1fr)); }
  .cg-cell {
    font-size: 0.6rem; padding: 0.5rem 0.1rem;
    overflow-wrap: anywhere; hyphens: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cg-cell, .cg-chip { opacity: 1; transform: none; transition: none; }
}

/* ── variant="strip" ──────────────────────────────────────────────────────
   The same 38 contests inside the hero's plate mount: the count, the shape of
   the result, and the key. Nothing that needs width — no headers, no winner
   names, no readout. The full grid, with every contest named, is further down
   the page. */
.cg--strip { --chip-gap: 3px; }
.cg--strip .cg-head { margin-bottom: 0.7rem; gap: 0.5rem; }
.cg--strip .cg-count { font-size: clamp(1.5rem, 1.15rem + 1.3vw, 2.1rem); }
.cg--strip .cg-sub { font-size: 0.85rem; }

/* 38 = 19 x 2 exactly, so the band never ends ragged. */
.cg-strip {
  display: grid; grid-template-columns: repeat(19, minmax(0, 1fr));
  gap: var(--chip-gap);
}
.cg-chip {
  aspect-ratio: 1; border-radius: 2px;
  opacity: 0; transform: translateY(4px);
  transition: opacity 0.4s ease-out, transform 0.4s ease-out;
}
/* Zero-specificity default so the family fills below still win. Written as a
   plain `.cg-chip { background }` it tied with `.is-foundation` and, being later
   in the file, painted all 38 chips the empty colour. */
:where(.cg-chip) { background: var(--cg-void); }
.cg.is-live .cg-chip { opacity: 1; transform: none; }
.cg--strip .cg-legend { margin-top: 0.75rem; gap: 0.35rem 0.9rem; font-size: 0.76rem; }
.cg--strip .cg-legend i { width: 9px; height: 9px; }

@container (max-width: 420px) {
  .cg--strip { --chip-gap: 2px; }
}
