/* Reusable pieces. Anything used by both views lives here.
 *
 * The rule for adding to this file: if a second view would want it, it is a
 * component; if only one view will ever use it, keep it out.
 */

/* ── Form controls ────────────────────────────────────────────── */
select, button {
  font-family: inherit; font-size: 12px;
  background: #23262e; color: var(--appbar-ink);
  border: 1px solid #383c46; border-radius: 5px; padding: 4px 7px; cursor: pointer;
}
select:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
button:hover:not(:disabled) { background: #2d313b; }
button:disabled { opacity: .4; cursor: default; }

.ctrl { display: flex; align-items: center; gap: 7px; }
.ctrl label { font-size: 11px; color: var(--appbar-muted); white-space: nowrap; }
.navgroup { display: flex; gap: 4px; }
.navgroup button { padding: 4px 9px; font-variant-numeric: tabular-nums; }
#recording-select { min-width: 300px; max-width: 460px; }

/* ── Context bar (the strip under the controls) ───────────────── */
.contextbar {
  background: var(--surface); border-bottom: 1px solid var(--hairline);
  padding: 9px var(--pad); display: flex; gap: 10px 22px; flex-wrap: wrap; align-items: baseline;
}
.contextbar .field { display: flex; gap: 6px; align-items: baseline; white-space: nowrap; }
.contextbar .k {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
}
.contextbar .v { font-size: 13px; color: var(--ink); font-variant-numeric: tabular-nums; }
.contextbar .v.big { font-size: 17px; font-weight: 650; }

.pill {
  font-size: 10px; padding: 2px 7px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline); color: var(--ink-2); background: var(--plane);
}
.badge {
  font-size: 11px; padding: 2px 9px; border-radius: var(--radius-pill);
  border: 1px solid var(--hairline); background: var(--surface); color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* ── Notes disclosure ─────────────────────────────────────────── */
.notes { background: var(--surface); border-bottom: 1px solid var(--hairline); padding: 0 var(--pad); }
.notes summary {
  cursor: pointer; padding: 7px 0; font-size: 12px; color: var(--ink-2);
  list-style: none; display: flex; align-items: center; gap: 7px;
}
.notes summary::-webkit-details-marker { display: none; }
.notes summary::before { content: "▸"; color: var(--muted); font-size: 10px; }
.notes[open] summary::before { content: "▾"; }
.notes ul { padding: 0 0 10px 26px; margin: 0; }
.notes li { font-size: 12px; color: var(--ink-2); margin-bottom: 3px; }

/* ── Cards ────────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius);
  overflow: hidden; min-width: 0;
}
.card.empty {
  display: flex; align-items: center; justify-content: center;
  min-height: 90px; color: var(--muted); font-size: 12px; padding: var(--pad); text-align: center;
}
/* Stacks two plots so both share the axis the eye reads down the column. */
.stack-card { display: flex; flex-direction: column; }

.placeholder {
  background: var(--surface); border: 1px dashed var(--baseline); border-radius: var(--radius);
  padding: 14px var(--pad); color: var(--ink-2);
}
.placeholder .title { font-size: 12.5px; font-weight: 600; margin-bottom: 3px; }
.placeholder .body { font-size: 12px; color: var(--muted); max-width: 78ch; }

/* ── Stat tiles ───────────────────────────────────────────────── */
.tile {
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius);
  padding: 10px 12px 4px; display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.tile .t-label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile .t-value { display: flex; align-items: baseline; gap: 4px; }
/* Proportional figures on the hero number; nothing here aligns in a column. */
.tile .t-num { font-size: 25px; font-weight: 650; color: var(--ink); line-height: 1.15; }
.tile .t-num.t-word { font-size: 22px; letter-spacing: -.01em; }
.tile .t-unit { font-size: 11px; color: var(--muted); }
.tile .t-sub {
  font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile .t-caption {
  font-size: 10.5px; color: var(--ink-2); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tile .t-spark { height: 34px; margin: 4px -4px 0; }
/* A tile with nothing behind it is dimmed and dashed, so it cannot be mistaken
   for one carrying a measurement. */
.tile.placeholder .t-num { color: var(--muted); font-weight: 500; }
.tile.placeholder { border-style: dashed; }
.t-flag {
  font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase;
  padding: 1px 6px; border-radius: var(--radius-pill); align-self: flex-start;
  border: 1px solid currentColor; color: var(--muted);
}

/* ── Trace toggles ────────────────────────────────────────────── */
.toggles { display: flex; gap: 5px; align-items: center; }
.toggle {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--baseline); border-radius: var(--radius-pill);
  padding: 2px 10px 2px 8px; font-size: 11px; line-height: 1.6; cursor: pointer;
}
.toggle:hover { border-color: var(--muted); }
.toggle[aria-pressed="false"] { color: var(--muted); background: var(--plane); border-style: dashed; }
.toggle[aria-pressed="false"] .swatch { opacity: .35; }
/* Line glyphs, drawn the way the trace is drawn. */
.swatch { display: inline-block; width: 15px; height: 0; }
.swatch.raw { border-top: 1px solid var(--baseline); }
.swatch.dc  { border-top: 2.5px solid var(--ink-2); }
.swatch.ac  { border-top: 1.5px solid var(--ink-2); opacity: .55; }
.toggle[aria-pressed="false"] .swatch.ac { opacity: .2; }

/* A labelled group of small-multiple panels, one per sub-model. */
.sub-block { margin-bottom: var(--gap); }
.sub-block-head {
  font-size: 11px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-2); padding: 2px 0 5px;
}

/* ── Data tables ──────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; }
table.data {
  width: 100%; border-collapse: collapse;
  font-size: 11.5px; font-variant-numeric: tabular-nums;
}
table.data th, table.data td {
  padding: 5px 10px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--hairline);
}
table.data th {
  position: sticky; top: 0; background: var(--surface);
  font-size: 10px; font-weight: 650; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); text-align: right;
}
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data tbody tr:hover { background: var(--plane); }
/* Tick / cross. Sized up and centred so the column scans as a pattern rather
   than as characters to be read one by one. */
table.data td.glyph {
  text-align: center;
  font-size: 14px;
  line-height: 1;
  font-variant-numeric: normal;
}
table.data td.glyph.yes { color: var(--included); font-weight: 700; }
table.data td.glyph.no { color: var(--excluded); }

/* Rows the ensemble kept, tinted just enough to group them. The tick already
   carries the meaning; the tint is what makes the set readable as a block
   without reading each glyph. Excluded rows get nothing — highlighting both
   would leave the eye no default to scan past. */
table.data tr.included td { background: var(--included-wash); }
table.data tr.included:hover td { background: var(--included-wash-hover); }

table.data td.empty {
  text-align: center; color: var(--muted); padding: 22px; font-variant-numeric: normal;
}

/* --- Refresh control -----------------------------------------------------
   The button pulls new recordings from S3 and scores them, which takes tens
   of seconds. The status line beside it is not decoration: without it a user
   cannot tell a working refresh from a hung page, and the failure mode is
   reloading mid-download. */
.refreshgroup { gap: 8px; }

.refresh-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--muted);
  max-width: 46ch;
  /* One line, always. A failed refresh reports an AWS error long enough to
     wrap to four lines, which pushes the app bar over the page and moves
     every control under the cursor. The full text is on the title attribute. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.refresh-status.is-running { color: var(--accent); }
.refresh-status.is-failed  { color: var(--critical); }
.refresh-status.is-done    { color: var(--muted); }

/* The last line the running command printed. Truncated rather than wrapped:
   the app bar is one row and a long S3 key must not reflow the controls. */
.refresh-detail {
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 28ch;
}

.spinner {
  width: 11px;
  height: 11px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: apollo-spin 0.7s linear infinite;
  flex: 0 0 auto;
}

@keyframes apollo-spin { to { transform: rotate(360deg); } }

/* Respect a user who has asked for less motion: keep the affordance, drop the
   rotation. */
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-right-color: currentColor; opacity: 0.5; }
}

#refresh-btn[disabled] { opacity: 0.6; cursor: progress; }
