/* Playgrounds (/playground/...): one hierarchy on every page. The stage, a full-width dark plate
   that carries the figure; the rail, a column of controls beside it with hairlines between groups;
   a row of secondary charts separated by hairlines; then the notes in the reading width.
   Scoped to .pg-page; colours, type and radii come only from the site tokens. */

.pg-page { max-inline-size: var(--page-max); margin-inline: auto; padding-block-end: 8px; }
.pg-nb { white-space: nowrap; }
.pg-intro {
  margin: 0 0 clamp(20px, 2.5vw, 32px);
  max-inline-size: 70ch;
  font-size: 1.08rem;
  line-height: 1.6;
  color: var(--ink-2);
}

.pg { container: pg / inline-size; display: grid; gap: 0; }

/* ---------------------------------------------------------------- stage and rail */
.pg-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; align-items: start; }
@container pg (min-width: 900px) {
  .pg-top { grid-template-columns: 300px minmax(0, 1fr); gap: clamp(24px, 3vw, 40px); }
}

/* the plate is always dark, like the photographs on the home page: color-scheme flips every
   light-dark() token inside it, and the canvases read their colours from inside the plate */
.pg-plate {
  --bg: #100f0e; --surface: #100f0e; --surface-2: #1d1b18;
  color-scheme: dark;
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 0;
  block-size: 560px;
  border-radius: var(--radius);
  overflow: hidden;
  color: var(--ink);
  background:
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / 24px 24px, #100f0e;
  box-shadow: 0 0 0 1px color-mix(in oklab, #bbb7b1 45%, #4a4744);
}
/* the legend sits inside the plate's top edge and the foot inside its bottom one; the canvas
   takes everything between, so nothing can overlap at any width */
.pg-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 20px;
  padding: 14px 18px 8px;
}
.pg-plate .pg-stage { position: relative; flex: 1 1 auto; min-block-size: 0; }
.pg-plate .pg-foot {
  margin: 0;
  padding: 8px 18px 12px;
  font: 0.8125rem/1.4 var(--mono);
  color: var(--muted);
}
/* on phones the plate grows with its legend and foot rather than squeezing the canvas */
@media (max-width: 640px) {
  .pg-plate { block-size: auto; min-block-size: 420px; }
  .pg-plate .pg-stage { min-block-size: 280px; }
}

/* the rail: groups parted by hairlines, no box */
.pg-rail { display: grid; align-content: start; gap: 0; min-inline-size: 0; }
.pg-group {
  display: grid;
  align-content: start;
  gap: 12px;
  margin: 0;
  padding-block: 18px;
  border-block-start: 1px solid var(--line);
}
.pg-rail > .pg-group:first-child { padding-block-start: 0; border-block-start: 0; }
.pg-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.pg-buttons .btn:first-child { flex: 1 1 auto; }
.pg-buttons .btn:disabled { color: var(--muted); background: transparent; border-color: var(--line); cursor: not-allowed; transform: none; box-shadow: none; }
.pg-live { display: grid; gap: 10px; }
.pg-readout { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; margin: 0; }
.pg-readout > div { min-inline-size: 0; }
.pg-readout dt { font: 500 0.8125rem/1.4 var(--mono); color: var(--muted); }
.pg-readout dd {
  margin: 2px 0 0;
  font: 300 1.75rem/1.1 var(--serif);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.pg-readout dd small { font: 500 0.8125rem/1 var(--mono); color: var(--muted); }
.pg-readout .minor dd { font: 500 1rem/1.3 var(--sans); letter-spacing: 0; }
.pg-state { margin: 0; font: 0.8125rem/1.5 var(--mono); color: var(--muted); }
.pg-state.is-alert { color: var(--ink-2); padding-inline-start: 10px; border-inline-start: 2px solid var(--flow); }

/* settings */
.pg-settings { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px; }
.pg-field { display: grid; gap: 5px; min-inline-size: 0; }
.pg-field--wide { grid-column: 1 / -1; }
.pg-label { font: 500 0.8125rem/1.4 var(--mono); color: var(--muted); }
.pg-hint { grid-column: 1 / -1; margin: 0; font-size: 0.875rem; line-height: 1.5; color: var(--muted); }
.pg-select { position: relative; display: block; }
.pg-select::after {
  content: "";
  position: absolute;
  inset-inline-end: 12px;
  inset-block-start: 50%;
  inline-size: 6px;
  block-size: 6px;
  margin-block-start: -5px;
  border-inline-end: 1.5px solid var(--muted);
  border-block-end: 1.5px solid var(--muted);
  transform: rotate(45deg);
  pointer-events: none;
}
.pg-select select {
  appearance: none;
  inline-size: 100%;
  min-block-size: 36px;
  padding: 0 28px 0 11px;
  font: 500 0.9rem/1 var(--sans);
  color: var(--ink);
  background: var(--raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  text-overflow: ellipsis;
  transition: border-color 0.25s;
}
.pg-select select:hover { border-color: var(--ink-2); }
.pg-select select:disabled { cursor: progress; opacity: 0.7; }
.pg-select--sm select { min-block-size: 30px; font-size: 0.8125rem; padding-inline: 9px 24px; }
.pg-select--sm::after { inset-inline-end: 10px; }
.pg-inline { display: inline-flex; align-items: center; gap: 8px; }
.pg-range input[type="range"] { inline-size: 100%; margin: 2px 0 0; accent-color: var(--mark); cursor: pointer; }

/* ---------------------------------------------------------------- the secondary charts */
.pg-row {
  display: flex;
  flex-wrap: wrap;
  margin-block-start: clamp(24px, 3vw, 36px);
  border-block: 1px solid var(--line);
  overflow: hidden;
}
.pg-chart {
  flex: 1 1 280px;
  min-inline-size: 0;
  display: grid;
  align-content: start;
  gap: 10px;
  margin: 0;
  padding: 18px 20px 20px;
  border-inline-start: 1px solid var(--line);
  border-block-start: 1px solid var(--line);
  margin-inline-start: -1px;
  margin-block-start: -1px;
}
.pg-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
}
.pg-title { font: 500 0.8125rem/1.4 var(--mono); color: var(--ink); }
.pg-key { display: flex; flex-wrap: wrap; gap: 4px 14px; font: 500 0.8125rem/1.4 var(--mono); color: var(--muted); }
.pg-key > span { display: inline-flex; align-items: center; gap: 6px; }
.pg-key i { display: inline-block; inline-size: 14px; block-size: 3px; border-radius: 2px; background: var(--muted); }
.pg-key .k-pos, .pg-key .k-val { background: var(--mark); }
.pg-key .k-neg { background: var(--flow); }
.pg-key .k-train { block-size: 2px; background: var(--ink-2); }
.pg-key .sym { font-variant-caps: normal; }
.pg-chart .pg-stage { block-size: 240px; }
.pg-caption { margin: 0; font-size: 0.875rem; line-height: 1.5; color: var(--muted); }
.pg-facts { margin: 0; font: 0.8125rem/1.5 var(--mono); color: var(--muted); overflow-wrap: anywhere; }
.pg-facts b { font-weight: 500; color: var(--ink-2); }

/* canvases fill a sized stage and draw at device resolution (the scripts re-measure on resize) */
.pg-stage { position: relative; min-inline-size: 0; }
.pg-stage canvas { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; }
.pg-parity canvas { touch-action: manipulation; }

.pg-tip {
  position: absolute;
  z-index: 3;
  display: grid;
  gap: 2px;
  padding: 8px 10px;
  pointer-events: none;
  white-space: nowrap;
  font: 0.8125rem/1.45 var(--mono);
  color: var(--ink-2);
  background: var(--raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
}
.pg-tip b { font-weight: 600; color: var(--ink); }

/* before the data arrive, keep the frame quiet */
.pg:not(.is-ready) .pg-top, .pg:not(.is-ready) .pg-row { opacity: 0.6; }
@media (prefers-reduced-motion: no-preference) {
  .pg-top, .pg-row { transition: opacity 0.24s var(--ease); }
}

/* ---------------------------------------------------------------- notes, in the reading width */
.pg-details { display: grid; gap: 14px; margin: clamp(24px, 3vw, 36px) 0 0; }
.pg-details h2 { margin: 0; font: 500 0.8125rem/1.4 var(--mono); color: var(--ink); }
.pg-details .pg-caption { max-inline-size: 70ch; }
.pg-details .table-wrap { border: 0; border-radius: 0; background: transparent; }
.pg-details table { border-collapse: collapse; inline-size: 100%; font: 0.8125rem/1.5 var(--mono); color: var(--ink-2); }
.pg-details th, .pg-details td { padding: 6px 12px 6px 0; text-align: left; vertical-align: top; border-block-end: 1px solid var(--line); white-space: nowrap; background: transparent; }
.pg-details th { font-weight: 500; color: var(--muted); }
.pg-details td.num, .pg-details th.num { text-align: right; font-variant-numeric: tabular-nums; }
.pg-details td b { font-weight: 600; color: var(--ink); }

.pg-more { margin-block-start: clamp(28px, 3vw, 40px); padding-block-start: 18px; border-block-start: 1px solid var(--line); max-inline-size: 960px; }
.pg-more > summary {
  display: flex;
  align-items: center;
  gap: 12px;
  inline-size: fit-content;
  list-style: none;
  cursor: pointer;
  font: 300 clamp(1.4rem, 1.2rem + 0.6vw, 1.7rem)/1.3 var(--serif);
  letter-spacing: -0.01em;
  color: var(--ink);
}
.pg-more > summary::-webkit-details-marker { display: none; }
.pg-more > summary::before {
  content: "";
  inline-size: 8px;
  block-size: 8px;
  border-inline-end: 1.5px solid var(--muted);
  border-block-end: 1.5px solid var(--muted);
  transform: rotate(-45deg);
}
.pg-more[open] > summary::before { transform: rotate(45deg); }
@media (prefers-reduced-motion: no-preference) {
  .pg-more > summary::before { transition: transform 0.2s var(--ease); }
}
.pg-more > .prose { margin-block-start: 16px; max-inline-size: 70ch; }
.pg-notes { display: grid; gap: 28px; max-inline-size: 960px; margin-block-start: clamp(28px, 3vw, 40px); padding-block-start: 18px; border-block-start: 1px solid var(--line); }
.pg-notes .pg-credits { margin: 0; max-inline-size: 70ch; align-content: start; }
.pg-notes .pg-credits h2 { margin: 0; font-size: 1.25rem; }

/* ---------------------------------------------------------------- the app shell
   On a screen wide and tall enough, the playground fills the first screen: one bar with the crumb and the
   title, the controls in a narrow rail on the left, the stage taking the rest, the secondary charts in one
   strip under it. The notes, the tables and the credits follow below the fold. Elsewhere the same markup
   stacks in reading order. */
.pg-wrap { --rail: 264px; }
.pg-bar { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; padding-block: 14px 12px; }
.pg-bar .crumbs { margin: 0; font: 500 0.8125rem/1.3 var(--mono); }
.pg-bar .crumbs a { color: var(--muted); text-decoration: none; }
.pg-bar .crumbs a:hover { color: var(--ink); }
.pg-bar h1 { margin: 0; font: 400 clamp(1.35rem, 1.1rem + 0.6vw, 1.7rem)/1.15 var(--serif); letter-spacing: -0.01em; }
.pg-bar .pg-about-link { margin-inline-start: auto; font: 500 0.8125rem/1.3 var(--mono); color: var(--muted); text-decoration: none; }
.pg-bar .pg-about-link:hover { color: var(--ink); }
.pg-bar .pg-buttons .btn:first-child { flex: 0 0 auto; }
.pg-about { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; padding-block: clamp(32px, 4vw, 56px) 8px; border-block-start: 1px solid var(--line); margin-block-start: clamp(24px, 3vw, 40px); }
.pg-about > .pg-intro { margin-block-end: 0; }
.pg-row .pg-caption, .pg-row .pg-hint { display: none; }
.pg-rail .pg-hint { display: none; }
.pg-app { grid-template-columns: minmax(0, 1fr); }
.pg-details .table-wrap { overflow-x: auto; }
.pg-about .prose { grid-template-columns: minmax(0, 1fr); }
.pg-about .prose p { overflow-x: auto; overflow-y: hidden; }
.pg-about .tex-display { position: relative; display: block; overflow-x: auto; }
/* on a phone the picture comes first and the controls follow it */
@media not ((min-width: 1000px) and (min-height: 620px)) {
  .pg-app .pg-top { display: flex; flex-direction: column; gap: 20px; }
  .pg-app .pg-plate, .pg-app .pg-stage2 { order: -1; }
}

@media (min-width: 1000px) and (min-height: 620px) {
  .pg-app {
    --strip: clamp(236px, 27dvh, 260px); --main-min: 320px;
    display: grid;
    grid-template-columns: var(--rail) minmax(0, 1fr);
    grid-template-rows: 56px max(var(--main-min), calc(100dvh - var(--head-h) - 56px - var(--strip) - 40px)) var(--strip);
    grid-auto-rows: auto;
    column-gap: 24px;
    row-gap: 12px;
  }
  /* what follows the first screen (tables, formulae, notices) runs the full width below it */
  .pg-app > :not(.pg-bar, .pg-top, .gp-dash, .pg-row) { grid-column: 1 / -1; }
  .pg-app > .pg-details:first-of-type, .pg-app > .gp-details { margin-block-start: clamp(24px, 3vw, 40px); }
  .pg-app > .pg-bar { grid-column: 1 / -1; grid-row: 1; align-self: end; padding-block: 0 4px; }
  .pg-app .pg-top, .pg-app .gp-dash:not([hidden]) { display: contents; }
  .pg-app .gp-dash[hidden] { display: none; }
  .pg-app .pg-rail {
    grid-column: 1; grid-row: 2 / 4;
    overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
    padding-inline-end: 6px; margin-inline-end: -6px;
  }
  .pg-app .pg-plate, .pg-app .pg-stage2 { grid-column: 2; grid-row: 2; block-size: auto; min-block-size: 0; }
  .pg-app .pg-row {
    grid-column: 2; grid-row: 3;
    margin: 0; min-block-size: 0;
    flex-wrap: nowrap;
    border-block: 0;
    gap: 0;
  }
  .pg-app .pg-chart {
    flex: 1 1 0; display: flex; flex-direction: column; gap: 6px;
    padding: 2px 16px 0; margin: 0;
    border-block-start: 0;
  }
  .pg-app .pg-chart:first-child { border-inline-start: 0; padding-inline-start: 0; }
  .pg-app .pg-chart .pg-stage { flex: 1 1 auto; block-size: auto; min-block-size: 0; }
  .pg-app .pg-chart.pg-chart--wide { flex-grow: 2; }
  /* the rail tightens: smaller readouts, controls closer together */
  .pg-app .pg-group { gap: 10px; padding-block: 12px; }
  .pg-app .pg-readout { gap: 8px 14px; }
  .pg-app .pg-readout dd { font-size: 1.3rem; }
  .pg-app .pg-settings { gap: 9px 12px; }
  .pg-app .pg-select select { min-block-size: 32px; }
  .pg-app .pg-legend { padding: 10px 14px 4px; }
}

/* below the app, the notes take the reading column and the data and credits sit beside them */
@media (min-width: 1100px) {
  .pg-about { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); column-gap: clamp(32px, 4vw, 64px); align-items: start; }
  .pg-about > .pg-intro, .pg-about > .pg-more { grid-column: 1; }
  .pg-about > .pg-notes { grid-column: 2; grid-row: 1 / span 3; margin-block-start: 0; padding-block-start: 0; border-block-start: 0; }
  .pg-about > .pg-more { margin-block-start: 24px; }
  .pg-about > .pg-intro + .pg-more { padding-block-start: 0; border-block-start: 0; }
  .pg-about .pg-notes .pg-credits { font-size: 0.9375rem; }
}

/* the network: one clean diverging pair for the sign of a weight, sky and coral, on a cooler black; the same pair runs
   from cool to hot stars in the scatter, which is the way stars themselves are coloured */
.nn {
  --accent: light-dark(#0a78b8, #7ccfff); --accent-2: light-dark(#d4452f, #ff7f6b);
  --mark: var(--accent); --flow: var(--accent-2);
}
/* the scatter needs a real square: a taller strip, and more of its width than the loss curve */
@media (min-width: 1000px) and (min-height: 620px) {
  .pg-app.nn { --strip: clamp(276px, 31dvh, 300px); }
  .pg-app.nn .pg-chart.pg-parity { flex-grow: 1.5; }
}
.nn .pg-plate {
  --bg: #0b0d12; --surface: #0b0d12; --surface-2: #171a22;
  background: linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / 24px 24px, linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / 24px 24px, #0b0d12;
}
