/* AURACLE — the figure runtime's styles.
 *
 * Shared by both books and the landing page. Every colour comes from the
 * phosphor tokens the surrounding page already defines (`--phos-a` on
 * `html.coal` / `html.light` in the books, on `:root` on the landing page), so a
 * figure re-themes with its page and no JavaScript has to know which theme is
 * on. That is also why the SVG uses `var(--…)` in its paint attributes rather
 * than resolved hex: a theme switch is a repaint, not a rebuild.
 *
 * The colour law the rest of the site keeps applies here too, and it is what
 * makes these readable at a glance: GREEN IS SOUND, AMBER IS THE MODEL'S MIND.
 * A figure about a waveform is green. A figure about a posterior is amber. A
 * figure about both says which is which by colour alone.
 */

.viz {
  margin: 2em 0;
}

.viz-stage {
  position: relative;
  background: var(--code-bg, rgba(255, 255, 255, 0.02));
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 14px 16px 12px;
}

.viz svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Text inside the plots. Mono, because every label in one is a value or an
   axis name — the tracking law says mono gets no letter-spacing. */
.viz text {
  font-family: var(--mono-font, ui-monospace, Menlo, monospace);
  font-size: 10px;
  letter-spacing: 0;
  fill: var(--silk-dim);
}

/* Axis names, units and the small print inside a box. `--silk-dim`, not
   `--silk-mute`: law 1 says mute is the stroke tier and never carries a glyph,
   and these are 9px glyphs on a dark panel — the tier below reads as unlit. */
.viz .v-axis {
  fill: var(--silk-dim);
  font-size: 9px;
}

.viz .v-grid {
  stroke: var(--hairline);
  stroke-width: 1;
}

.viz .v-rule {
  stroke: var(--silk-mute);
  stroke-width: 1;
}

/* A value the reader is meant to read off rather than eyeball.
   Every `--fg` here carries `var(--silk)` as its fallback. `fill` is inherited
   and its initial value is black, so on a page that defines the phosphors but
   not `--fg` an unqualified `var(--fg)` is invalid at computed-value time and
   resolves to *black text on a black panel* — and worse, it does it at a
   specificity that beats the `fill` presentation attribute the figure set, so a
   label the figure had deliberately painted green went black too. */
.viz .v-num {
  fill: var(--fg, var(--silk));
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.viz .v-num-a { fill: var(--phos-a); }
.viz .v-num-b { fill: var(--phos-b); }

/* ─── controls ──────────────────────────────────────────────────────────── */

.viz-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  align-items: center;
  margin-top: 12px;
  padding-top: 11px;
  border-top: 1px solid var(--hairline);
}

.viz-ctl {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--mono-font, ui-monospace, Menlo, monospace);
  font-size: 11px;
  color: var(--silk-dim);
}

.viz-ctl > span:first-child {
  white-space: nowrap;
}

.viz-ctl input[type="range"] {
  width: clamp(90px, 22vw, 168px);
  accent-color: var(--phos-b);
  cursor: pointer;
}

.viz-ctl output {
  min-width: 4.4em;
  color: var(--phos-b);
  font-variant-numeric: tabular-nums;
}

.viz-btn {
  font-family: var(--mono-font, ui-monospace, Menlo, monospace);
  font-size: 11px;
  color: var(--fg, var(--silk));
  background: var(--panel-hi, rgba(255, 255, 255, 0.05));
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 5px 11px;
  cursor: pointer;
}

.viz-btn:hover { border-color: var(--silk-mute); }
.viz-btn[aria-pressed="true"] { color: var(--phos-b); border-color: var(--phos-b-deep); }
.viz-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.viz-ctl input:focus-visible,
.viz-btn:focus-visible {
  outline: 2px solid var(--phos-b);
  outline-offset: 2px;
}

/* ─── draggable handles ─────────────────────────────────────────────────── */

/* Handles are real focusable elements with arrow-key support, not decoration —
   a figure whose only affordance is a mouse drag is a figure half the readers
   cannot use. */
.viz .v-handle {
  cursor: grab;
  touch-action: none;
}

.viz .v-handle:active { cursor: grabbing; }

.viz .v-handle:focus-visible {
  outline: none;
}

.viz .v-handle:focus-visible .v-handle-ring {
  stroke: var(--phos-b);
  stroke-width: 2.5;
}

/* ─── the readout strip ─────────────────────────────────────────────────── */

/* What the figure currently says, in words. This is the accessible equivalent
   of the picture and it is a `role="status"`, so a screen reader hears the
   figure change rather than only sighted readers seeing it. */
.viz-readout {
  margin-top: 10px;
  font-family: var(--mono-font, ui-monospace, Menlo, monospace);
  font-size: 11px;
  line-height: 1.55;
  color: var(--silk-dim);
  min-height: 1.55em;
}

.viz-readout b { color: var(--phos-b); font-weight: 400; }
.viz-readout i { color: var(--phos-a); font-style: normal; }

/* ─── captions ──────────────────────────────────────────────────────────── */

.viz figcaption {
  margin-top: 0.8em;
  font-size: 0.86em;
  line-height: 1.5;
  color: var(--silk-dim);
}

.viz figcaption strong { color: var(--fg, var(--silk)); font-weight: 500; }

/* ─── motion ────────────────────────────────────────────────────────────── */

/* Figures that animate check this in JS too and render a static end-state
   instead of a stopped animation — a paused diagram and a finished one are
   different pictures, and only one of them is informative. */
@media (prefers-reduced-motion: reduce) {
  .viz * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ─── narrow viewports ──────────────────────────────────────────────────── */

@media (max-width: 560px) {
  .viz-stage { padding: 10px 10px 8px; }
  .viz-controls { gap: 8px 14px; }
  .viz-ctl input[type="range"] { width: 100%; }
  .viz-ctl { flex: 1 1 100%; }
}

/* ─── print ─────────────────────────────────────────────────────────────── */

@media print {
  /* The controls do nothing on paper, and the readout carries what the figure
     was showing when it was printed. */
  .viz-controls { display: none; }
  .viz-stage { border-color: #999; }
}
