/* Interactions (js/interactions/): the live figures a teacher drives on the
   projected tablet. Styled like the book's printed figures (template.typ):
   brand-green curves on a pale grid, green axes with arrowheads, italic
   axis names, labels in mint pills. `ix-board` is for a projector (text at
   least 18px, controls at least 44px); `ix-inline` for a laptop screen.
   Tokens only. */

.ix {
  /* series: template.typ's `series` (brand green, a darkened amber, a
     darkened highlight green, muted), so a curve is the colour it prints */
  --ix-s0: var(--primary);
  --ix-s1: color-mix(in srgb, var(--amber) 70%, black);
  --ix-s2: color-mix(in srgb, var(--green-400) 78%, black);
  --ix-s3: var(--muted);
  --ix-accent: var(--answer-ink);        /* tangents: the teacher's blue */
  --ix-normal: var(--amber);
  --ix-up: var(--green-600);             /* gradient > 0 */
  --ix-down: var(--amber);               /* gradient < 0 */
  --ix-cup: var(--answer-ink);           /* concave up */
  --ix-cdown: var(--amber);              /* concave down */
  --ix-neg: var(--error);
  --ix-hit: var(--green-400);

  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(260px, 28%, 380px);
  grid-template-rows: minmax(0, 1fr);
  width: 100%; height: 100%;
  min-height: 360px;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--font-ui);
  -webkit-user-select: none; user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.ix-board {
  --ix-font: 22px; --ix-small: 18px; --ix-tick: 18px; --ix-label: 18px; --ix-name: 22px;
  --ix-curve: 4.5px; --ix-thin: 2.5px; --ix-axis: 2px; --ix-control: 52px; --ix-gap: 16px;
}
.ix-inline {
  --ix-font: 16px; --ix-small: 13px; --ix-tick: 13px; --ix-label: 13px; --ix-name: 16px;
  --ix-curve: 3px; --ix-thin: 1.8px; --ix-axis: 1.5px; --ix-control: 44px; --ix-gap: 12px;
}
.ix-narrow, .ix-toolbar { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto; }

/* ---- stage ------------------------------------------------------------------ */
.ix-stage { position: relative; min-width: 0; min-height: 0; overflow: hidden; touch-action: none; }
.ix-stage.is-draggable { cursor: crosshair; }
.ix-stage.is-tappable { cursor: pointer; }
.ix-svg { position: absolute; inset: 0; display: block; overflow: visible; touch-action: none; }
.ix-svg:focus-visible { box-shadow: none !important; outline: 3px solid var(--green-400); outline-offset: -3px; }

.ix-gridline { stroke: var(--green-200); stroke-width: 1; }
.ix-axis { stroke: var(--primary); stroke-width: var(--ix-axis); stroke-linecap: round; }
.ix-arrow { fill: var(--primary); }
.ix-tick { fill: var(--primary); font-size: var(--ix-tick); font-variant-numeric: tabular-nums; paint-order: stroke; stroke: var(--surface); stroke-width: 5px; stroke-linejoin: round; }
.ix-tick.is-zero { font-weight: var(--w-semibold); }
.ix-axname { fill: var(--primary); font-size: var(--ix-name); font-style: italic; paint-order: stroke; stroke: var(--surface); stroke-width: 5px; stroke-linejoin: round; }
.ix-sup { font-size: 72%; }
.ix-inset-title { fill: var(--muted); font-size: var(--ix-small); font-weight: var(--w-semibold); }
.ix-note { fill: var(--primary); font-size: var(--ix-label); }
.ix-note.s1, .ix-pill.s1 text { fill: var(--ix-s1); }
.ix-note.s2, .ix-pill.s2 text { fill: var(--ix-s2); }
.ix-note.s3, .ix-pill.s3 text { fill: var(--ix-s3); }

.ix-curve { fill: none; stroke: var(--ix-s0); stroke-width: var(--ix-curve); stroke-linejoin: round; stroke-linecap: round; }
.ix-curve.s1 { stroke: var(--ix-s1); }
.ix-curve.s2 { stroke: var(--ix-s2); }
.ix-curve.s3 { stroke: var(--ix-s3); }
.ix-curve.is-dash { stroke-dasharray: calc(var(--ix-curve) * 3) calc(var(--ix-curve) * 2.2); }
.ix-curve.is-faint { opacity: .4; }
.ix-curve.is-thin { stroke-width: var(--ix-thin); }
.ix-curve.is-ghost { opacity: .45; stroke-width: var(--ix-thin); stroke-dasharray: calc(var(--ix-thin) * 4) calc(var(--ix-thin) * 3); }
.ix-curve.is-under { opacity: .22; }
.ix-curve.is-solid { stroke-dasharray: none; opacity: 1; }
.ix-curve.is-hit { stroke-width: calc(var(--ix-curve) * 1.25); }
.ix-col-a { stroke: var(--ix-up); }
.ix-col-b { stroke: var(--ix-down); }
.ix-kind-tangent-trace .ix-col-a, .ix-key-a i { --ix-up: var(--green-600); }
.ix-trail { stroke-width: calc(var(--ix-curve) * .9); }
.ix-shade { fill: var(--green-200); opacity: .75; }

.ix-guide { stroke: var(--green-600); stroke-width: var(--ix-thin); opacity: .8; }
.ix-guide.is-dash { stroke-dasharray: 10 8; }
.ix-guide.s1 { stroke: var(--ix-s1); }
.ix-guide.s2 { stroke: var(--ix-s2); }
.ix-seg-line { stroke: var(--ix-accent); stroke-width: var(--ix-thin); stroke-linecap: round; }
.ix-seg-line.is-dash { stroke-dasharray: 8 7; opacity: .6; }
.ix-seg-line.is-arrow { fill: var(--ix-accent); stroke-linejoin: round; opacity: .55; }
.ix-tangent { stroke: var(--ix-accent); stroke-width: calc(var(--ix-thin) * 1.1); stroke-linecap: round; }
.ix-tangent.is-flat { stroke: var(--green-600); stroke-width: calc(var(--ix-thin) * 1.6); }
.ix-tangent.is-second { opacity: .9; }
.ix-normal { stroke: var(--ix-normal); stroke-width: calc(var(--ix-thin) * 1.1); stroke-dasharray: 12 7; stroke-linecap: round; }
.ix-link { stroke: var(--green-300); stroke-width: 1.5; stroke-dasharray: 3 5; }
.ix-hold { stroke: var(--ix-s2); stroke-width: var(--ix-thin); stroke-dasharray: 12 7; }
.ix-hold-dot { fill: var(--amber); stroke: var(--surface); stroke-width: 2; }
.ix-triangle { fill: none; stroke: var(--green-600); stroke-width: var(--ix-thin); stroke-dasharray: 7 6; }
.ix-fixed-dot { fill: var(--primary); stroke: var(--surface); stroke-width: 2; }

/* points: hollow like the book's; a draggable one is a big filled handle */
.ix-point circle { fill: var(--surface); stroke: var(--primary); stroke-width: calc(var(--ix-thin) * .9); }
.ix-point.is-drag circle:not(.ix-halo) { fill: var(--primary); stroke: var(--surface); stroke-width: 3; }
.ix-point .ix-halo { fill: var(--green-400); stroke: none; opacity: .28; }
.ix-stage.is-draggable .ix-halo { transition: opacity var(--dur-2) var(--ease); }
.ix-stage.is-draggable:active .ix-halo { opacity: .45; }
.ix-trail-dot { fill: var(--primary); stroke: var(--surface); stroke-width: 2; }

/* labels on the figure: mint pills, as the book labels its curves */
.ix-pill rect { fill: var(--green-50); stroke: var(--green-200); stroke-width: 1; opacity: .96; }
.ix-pill text { fill: var(--primary); font-size: var(--ix-label); font-weight: var(--w-medium); font-variant-numeric: tabular-nums; }
.ix-pill.s1 text { fill: var(--ix-s1); }
.ix-pill.s2 text { fill: var(--ix-s2); }
.ix-pill.is-tangent text { fill: var(--ix-accent); }
.ix-pill.is-normal text { fill: var(--amber-text); }
.ix-pill.is-flat rect, .ix-pill.is-pick rect { fill: var(--green-400); stroke: var(--green-600); }
.ix-pill.is-flat text, .ix-pill.is-pick text { fill: var(--green-950); }
.ix-pill.is-hold text { fill: var(--amber-text); }
.ix-pill.is-mean text { fill: var(--primary); }
.ix-pill.is-state text { fill: var(--green-600); font-weight: var(--w-semibold); }
.ix-pill.is-state.is-slow rect { fill: var(--amber-bg); stroke: var(--amber); }
.ix-pill.is-state.is-slow text { fill: var(--amber-text); }

/* ---- panel ------------------------------------------------------------------ */
.ix-panel {
  display: flex; flex-direction: column; gap: var(--ix-gap);
  padding: var(--ix-gap); min-width: 0;
  /* a slider's thumb carrier reaches past the track: no sideways scroll */
  overflow-x: hidden; overflow-y: auto;
  border-left: 1px solid var(--line);
  background: var(--surface-quiet);
}
.ix-tight { --ix-gap: 8px; }
.ix-tight .ix-slider-ends { display: none; }
.ix-narrow .ix-panel, .ix-toolbar .ix-panel {
  border-left: 0; border-top: 1px solid var(--line);
  flex-direction: row; flex-wrap: wrap; align-items: flex-end;
}
.ix-title { text-wrap: balance; font-size: var(--ix-font); line-height: 1.25; font-weight: var(--w-semibold); color: var(--primary); }
.ix-narrow .ix-title, .ix-toolbar .ix-title { width: 100%; }
.ix-controls { display: flex; flex-direction: column; gap: var(--ix-gap); }
.ix-controls > .ix-btn { align-self: flex-start; }
.ix-narrow .ix-controls, .ix-toolbar .ix-controls { flex-direction: row; flex-wrap: wrap; flex: 1 1 320px; }
.ix-narrow .ix-slider { flex: 1 1 260px; }
.ix-readouts { display: flex; flex-direction: column; gap: 8px; }
.ix-narrow .ix-readouts, .ix-toolbar .ix-readouts { flex-direction: row; flex-wrap: wrap; }
.ix-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: auto; }
.ix-narrow .ix-actions, .ix-toolbar .ix-actions { margin-top: 0; }

/* the slider: a 44px+ track with a big thumb; pointer events, no scrolling */
.ix-slider { display: flex; flex-direction: column; gap: 2px; min-width: 200px; }
.ix-slider-head { display: flex; align-items: baseline; gap: 8px; font-size: var(--ix-font); }
.ix-slider-label { font-style: italic; color: var(--primary); }
.ix-eq { color: var(--muted); }
.ix-slider-value { font-weight: var(--w-semibold); color: var(--ink); font-variant-numeric: tabular-nums; }
.ix-track {
  --t: 0; --thumb: calc(var(--ix-control) * .62);
  position: relative; height: var(--ix-control); touch-action: none; cursor: pointer; border-radius: var(--r-full);
}
.ix-rail {
  position: absolute; left: calc(var(--thumb) / 2); right: calc(var(--thumb) / 2); top: 50%;
  height: 8px; margin-top: -4px; border-radius: var(--r-full); background: var(--track);
  box-shadow: inset 0 0 0 1px var(--line-strong); overflow: hidden;
}
.ix-rail-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 100%; background: var(--primary); transform-origin: left; transform: scaleX(var(--t)); }
.ix-thumb {
  /* a full-width carrier moved by a transform (no layout per frame); the
     knob is its ::before */
  position: absolute; top: 50%; left: 0; width: calc(100% - var(--thumb)); height: var(--thumb);
  margin-top: calc(var(--thumb) / -2);
  transform: translateX(calc(var(--t) * 100%));
  pointer-events: none; will-change: transform;
}
.ix-thumb::before {
  content: ''; position: absolute; left: 0; top: 0; width: var(--thumb); height: var(--thumb);
  border-radius: 50%; background: var(--surface); border: 3px solid var(--primary);
  box-sizing: border-box; box-shadow: var(--e2); transition: box-shadow var(--dur-1) var(--ease);
}
/* hover only where there is a mouse: on the tablet a tapped button kept its hover tint */
@media (hover: hover) { .ix-track:hover .ix-thumb::before { box-shadow: var(--e3); } }
.ix-track.is-active .ix-thumb::before { box-shadow: 0 0 0 10px color-mix(in srgb, var(--green-400) 35%, transparent), var(--e3); }
.ix-track:focus-visible { box-shadow: var(--focus-ring) !important; }
.ix-slider-ends { display: flex; justify-content: space-between; font-size: var(--ix-small); color: var(--muted); padding: 0 4px; font-variant-numeric: tabular-nums; }

/* readouts */
.ix-readout {
  display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 10px;
  padding: 8px 12px; border-radius: var(--r-md); background: var(--surface);
  border: 1px solid var(--line-strong);
  font-size: var(--ix-font); line-height: 1.3;
  transition: background var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
.ix-readout-label { color: var(--muted); font-size: var(--ix-small); }
.ix-readout-label sup { font-size: 72%; }
.ix-readout-value { font-weight: var(--w-semibold); color: var(--ink); margin-left: auto; font-variant-numeric: tabular-nums; }
.ix-readout-say { width: 100%; font-size: var(--ix-small); font-weight: var(--w-semibold); color: var(--green-800); }
.ix-readout-say:empty { display: none; }
.ix-readout.is-hit { background: var(--green-400); border-color: var(--green-600); }
.ix-readout.is-hit .ix-readout-label, .ix-readout.is-hit .ix-readout-value { color: var(--green-950); }
.ix-pick {
  padding: 10px 14px; border-radius: var(--r-md); background: var(--green-400); color: var(--green-950);
  font-size: var(--ix-font); line-height: 1.45; font-variant-numeric: tabular-nums; font-weight: var(--w-medium);
}
.ix-pick[hidden] { display: none; }
.ix-note-line { font-size: var(--ix-small); color: var(--muted); }
.ix-note-line:empty { display: none; }
.ix-note-line.is-warn { color: var(--error-text); background: var(--error-bg); padding: 8px 12px; border-radius: var(--r-md); }
.ix-legend { display: flex; flex-direction: column; gap: 6px; font-size: var(--ix-small); color: var(--ink); }
.ix-legend:empty { display: none; }
.ix-key { display: inline-flex; align-items: center; gap: 10px; }
.ix-key i { width: 28px; height: 6px; border-radius: 3px; background: var(--ix-up); }
.ix-key-b i { background: var(--ix-down); }

/* buttons: the app's buttons at board size */
.ix-btn {
  min-height: var(--ix-control); padding: 0 calc(var(--ix-control) * .4);
  font-size: var(--ix-small); font-weight: var(--w-semibold); color: var(--primary);
  background: var(--surface); border: 1.5px solid var(--primary); border-radius: var(--r-md);
  touch-action: manipulation; cursor: pointer;
  transition: background var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
@media (hover: hover) { .ix-btn:hover:not(:disabled) { background: var(--surface-mint); } }
.ix-btn:active:not(:disabled) { transform: translateY(1px); }
.ix-btn:disabled { color: var(--disabled-text); background: var(--disabled-bg); border-color: var(--disabled-bg); cursor: default; }
.ix-btn-primary { background: var(--primary); color: var(--on-primary); }
@media (hover: hover) { .ix-btn-primary:hover:not(:disabled) { background: var(--primary-hover); } }
.ix-toggle[aria-pressed="true"] { background: var(--surface-mint); box-shadow: inset 0 0 0 2px var(--primary); }
.ix-seg { display: flex; flex-wrap: wrap; gap: 0; border: 1.5px solid var(--primary); border-radius: var(--r-md); overflow: hidden; align-self: flex-start; }
.ix-seg-btn {
  min-height: var(--ix-control); padding: 0 calc(var(--ix-control) * .36);
  font-size: var(--ix-small); font-weight: var(--w-medium); color: var(--primary);
  background: var(--surface); border: 0; border-left: 1.5px solid var(--primary); cursor: pointer; touch-action: manipulation;
}
.ix-seg-btn:first-child { border-left: 0; }
.ix-seg-btn[aria-pressed="true"] { background: var(--primary); color: var(--on-primary); }
/* a param's choices (slider-plot): a row of tabs in place of a slider */
.ix-choice { display: flex; flex-wrap: wrap; gap: 8px; }
.ix-choice .ix-chip { min-width: calc(var(--ix-control) * 1.3); text-align: center; font-size: var(--ix-font); font-weight: var(--w-medium); }

/* ---- table-fill ---------------------------------------------------------------- */
.ix-table { font-size: var(--tf-fs); }
.tf-head { fill: var(--surface-mint); stroke: var(--green-300); stroke-width: 1.5; }
.tf-head-t { fill: var(--primary); font-weight: var(--w-semibold); }
.tf-cell { fill: var(--surface); stroke: var(--green-300); stroke-width: 1.5; }
.tf-given { fill: var(--surface-quiet); }
.tf-t { fill: var(--ink); pointer-events: none; }
.tf-fill { cursor: pointer; }
@media (hover: hover) { .tf-fill:hover { fill: var(--green-50); } }
.tf-fill:focus-visible { outline: none; stroke: var(--primary); stroke-width: 3; }
.tf-fill.is-shown { fill: var(--surface); }
.tf-fill.is-choice { fill: var(--surface); }
.tf-fill.is-right { fill: var(--green-100); }
.tf-fill.is-wrong { fill: var(--error-bg); }
.tf-ans { fill: var(--answer-ink); font-weight: var(--w-medium); pointer-events: none; }
.tf-pick { fill: var(--ink); font-weight: var(--w-medium); pointer-events: none; }
.tf-sub { fill: var(--error-text); font-size: 78%; pointer-events: none; }
.ix-pair { display: flex; gap: 0; }
.ix-pair > .ix { flex: 0 0 44%; width: 44%; border-right: 1px solid var(--line); }
.ix-pair > .ix-link-slot { flex: 1 1 0; min-width: 0; position: relative; }
.ix-pair.ix-pair-stack { flex-direction: column; }
.ix-pair.ix-pair-stack > .ix { flex: 0 0 auto; width: 100%; height: 44%; border-right: 0; border-bottom: 1px solid var(--line); }
.ix-pair.ix-pair-stack > .ix-link-slot { flex: 1 1 0; min-height: 0; }

/* ---- the crate (slider-plot side: net-box) --------------------------------------------- */
.nb-sheet { fill: var(--green-50); stroke: var(--primary); stroke-width: var(--ix-thin); stroke-linejoin: round; }
.nb-cut { fill: none; stroke: var(--error); stroke-width: 1.5; stroke-dasharray: 6 5; }
.nb-fold { fill: none; stroke: var(--green-600); stroke-width: 1.5; stroke-dasharray: 8 6; }
.nb-face { fill: var(--green-100); stroke: var(--primary); stroke-width: var(--ix-thin); stroke-linejoin: round; }
.nb-face-r { fill: var(--green-200); }
.nb-open { fill: var(--green-300); }
.nb-inner { fill: var(--green-50); stroke: var(--green-600); stroke-width: 1.2; stroke-linejoin: round; }
.nb-rim { fill: none; stroke: var(--primary); stroke-width: var(--ix-thin); stroke-linejoin: round; }
.nb-lab { fill: var(--primary); font-size: var(--ix-small); font-variant-numeric: tabular-nums; }
.nb-h { fill: var(--error-text); font-weight: var(--w-semibold); }
.nb-title { fill: var(--muted); font-size: var(--ix-small); font-weight: var(--w-semibold); }

/* ---- motion-line -------------------------------------------------------------------- */
.ml-trail { fill: none; stroke: var(--green-300); stroke-width: var(--ix-thin); stroke-linejoin: round; stroke-linecap: round; }
.ml-turn { fill: var(--surface); stroke: var(--primary); stroke-width: 2; }
.ml-turn.is-start { fill: var(--primary); }
.ml-turn-lab { fill: var(--muted); font-size: var(--ix-small); font-variant-numeric: tabular-nums; }
.ml-particle { fill: var(--primary); stroke: var(--surface); stroke-width: 3; filter: drop-shadow(0 2px 3px color-mix(in srgb, var(--green-900) 30%, transparent)); }
.ml-arrow { stroke-width: calc(var(--ix-thin) * 1.5); stroke-linecap: round; stroke-linejoin: round; }
.ml-v { stroke: var(--ix-accent); fill: var(--ix-accent); }
.ml-a { stroke: var(--amber); fill: var(--amber); }
.ml-arrow-lab { font-size: var(--ix-label); font-style: italic; font-weight: var(--w-semibold); }
.ml-v-lab { fill: var(--ix-accent); }
.ml-a-lab { fill: var(--amber-text); }

/* ---- prob-bars ------------------------------------------------------------------------ */
.pb-true { fill: var(--green-200); stroke: var(--primary); stroke-width: var(--ix-thin); }
.pb-bar.is-outline .pb-true { fill: none; stroke-dasharray: 9 6; }
.pb-sim { fill: var(--primary); opacity: .85; transition: y var(--dur-1) linear, height var(--dur-1) linear; }
.pb-bar.is-neg .pb-true { fill: var(--error-bg); stroke: var(--ix-neg); }
.pb-bar.is-picked .pb-true { fill: var(--green-400); stroke: var(--green-800); }
.pb-val { fill: var(--primary); font-size: var(--ix-small); font-variant-numeric: tabular-nums; font-weight: var(--w-medium); }
.pb-val.is-neg { fill: var(--error-text); }
.pb-mean { stroke: var(--amber-text); stroke-width: var(--ix-thin); stroke-dasharray: 10 7; }
.pb-bracket { fill: none; stroke: var(--amber-text); stroke-width: var(--ix-thin); stroke-linejoin: round; }
.pb-bracket-lab { fill: var(--amber-text); font-size: var(--ix-small); font-weight: var(--w-medium); }
.pb-rm { stroke-width: var(--ix-thin); }

/* ---- errors ----------------------------------------------------------------------------- */
.ix-error { padding: var(--s-6); border: 1.5px solid var(--error); border-radius: var(--r-md); background: var(--error-bg); color: var(--error-text); }
.ix-error pre { white-space: pre-wrap; font-size: 14px; margin: 4px 0; }
.ix-missing { padding: var(--s-6); color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .pb-sim { transition: none; }
}

/* ---- the gallery (#/interactions) ---------------------------------------------------------- */
.ixg { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: var(--s-6); align-items: start; }
.ixg-list { position: sticky; top: calc(var(--topbar-h) + var(--s-4)); max-height: calc(100vh - var(--topbar-h) - var(--s-8)); overflow: auto; }
.ixg-group { padding: var(--s-3) 0; }
.ixg-group + .ixg-group { border-top: 1px solid var(--line); }
.ixg-group h2 { padding: var(--s-2) var(--s-4); }
.ixg-item { display: flex; flex-direction: column; gap: 2px; padding: var(--s-2) var(--s-4); text-decoration: none; color: var(--ink); border-left: 3px solid transparent; }
.ixg-item:hover { background: var(--surface-quiet); }
.ixg-item.is-current { background: var(--surface-mint); border-left-color: var(--primary); }
.ixg-name { font: var(--t-body); font-weight: var(--w-medium); }
.ixg-meta { font: var(--t-caption); color: var(--muted); }
.ixg-view { display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; overflow-x: auto; }
.ixg-bar { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }
.ixg-frame { position: relative; border: 1px solid var(--line-strong); border-radius: var(--r-md); overflow: hidden; box-shadow: var(--e2); background: var(--surface); flex: 0 0 auto; }
.ixg-live { position: absolute; inset: 0; }
.ixg-prompts ol { margin: var(--s-2) 0 0; padding-left: var(--s-6); }
body.ixg-bare-body { min-width: 0; overflow: hidden; }
.ixg-bare { position: fixed; inset: 0; background: var(--surface); }
.ixg-bare-body .stale-banner { display: none; }
.tf-hint { fill: var(--green-300); font-style: italic; pointer-events: none; }
/* motion-line: what the particle is doing */
.ix-state { align-self: flex-start; padding: 6px 14px; border-radius: var(--r-full); font-size: var(--ix-font); font-weight: var(--w-semibold); background: var(--green-100); color: var(--green-800); border: 1.5px solid var(--green-300); }
.ix-state.is-slow { background: var(--amber-bg); color: var(--amber-text); border-color: var(--amber); }

/* ---- a value on a number line (slider-plot side: number-line; teaching manual) ---- */
.nl-title { fill: var(--primary); font-size: var(--ix-font); font-weight: var(--w-semibold); }
.nl-axis { stroke: var(--ink); stroke-width: var(--ix-thin); }
.nl-ticks { stroke: var(--muted); stroke-width: 1; }
.nl-zero { stroke: var(--primary); stroke-width: 2.5; }
.nl-lab { fill: var(--muted); font-size: var(--ix-small); font-variant-numeric: tabular-nums; }
.nl-side { fill: var(--muted); font-size: var(--ix-small); }
.nl-mark { fill: var(--amber); stroke: var(--ink); stroke-width: 1; }
.nl-mark.is-hit { fill: var(--green-400); }
.nl-val { fill: var(--ink); font-size: var(--ix-font); font-weight: var(--w-semibold); font-variant-numeric: tabular-nums; }

/* ---- values on demand (teaching manual, Mitch 2026-10-14) ---- */
/* a point with a tip: a soft halo says it can be touched; its value shows on hover or tap */
.ix-point.has-tip .ix-halo { fill: var(--green-400); opacity: .22; }
.ix-point.has-tip circle:not(.ix-halo) { fill: var(--primary); stroke: var(--surface); stroke-width: 2; }
.ix-pill.is-tip rect { fill: var(--primary); stroke: none; opacity: 1; }
.ix-pill.is-tip text { fill: var(--surface); }
/* toggles in a group: rule chips, set in the maths face */
.ix-chip { font-variant-numeric: tabular-nums; text-align: left; }

/* ---- sample-proportion and interval-catcher (teaching manual, Unit 4 skills 23 to 29) ---- */
.sp-member { fill: var(--surface); stroke: var(--green-300); stroke-width: 1.2; }
.sp-member.is-trait { fill: var(--primary); stroke: var(--primary); }
.sp-member.is-picked { stroke: var(--amber); stroke-width: 2.4; }
.sp-dot { fill: var(--primary); }
.sp-dot.is-tail { fill: var(--amber); }
.sp-dot.is-new { fill: var(--amber-text); stroke: var(--surface); stroke-width: 1; }
.sp-tail-shade { fill: var(--amber-bg); opacity: .7; }
.sp-handle { fill: var(--amber); stroke: var(--amber-text); stroke-width: 2; cursor: ew-resize; }
.sp-p, .ic-p { stroke: var(--primary); stroke-width: var(--ix-thin); stroke-dasharray: 10 7; }
.sp-mean { stroke: var(--amber-text); stroke-width: var(--ix-thin); }
.sp-line-lab { fill: var(--primary); font-size: var(--ix-label); font-style: italic; font-weight: var(--w-medium); paint-order: stroke; stroke: var(--surface); stroke-width: 5px; stroke-linejoin: round; }
.sp-line-lab.is-mean, .sp-line-lab.is-sd { fill: var(--amber-text); font-style: normal; }
.sp-col { fill: var(--green-200); stroke: var(--primary); stroke-width: 1; }
.sp-normal { stroke: var(--ix-accent); stroke-width: var(--ix-thin); }
.sp-normal.is-out { stroke: var(--ix-neg); stroke-dasharray: 8 6; }
.sp-sd { fill: none; stroke: var(--amber-text); stroke-width: var(--ix-thin); stroke-linecap: round; }
.ic-row .ic-bar { fill: none; stroke: var(--primary); stroke-width: var(--ix-thin); stroke-linecap: round; }
.ic-row .ic-dot { fill: var(--primary); }
.ic-row.is-miss .ic-bar { stroke: var(--ix-neg); }
.ic-row.is-miss .ic-dot { fill: var(--ix-neg); }
.ic-row.is-live .ic-bar { stroke-width: var(--ix-curve); }
.ic-row.is-live.is-fit .ic-bar { stroke: var(--green-600); }
.ic-row.is-kept .ic-bar { stroke: var(--muted); }
.ic-band { fill: var(--green-100); opacity: .8; }
.ic-name { fill: var(--muted); font-size: var(--ix-label); font-variant-numeric: tabular-nums; }
.ic-name.is-live { fill: var(--primary); font-weight: var(--w-semibold); }
/* p̂ in the maths face (the UI face sets the combining hat beside the p) */
.ix-m { font-family: var(--font-math); font-style: italic; }
.sp-cut { stroke: var(--amber-text); stroke-width: var(--ix-thin); }
/* ---- dice-sim: relative frequencies settling (teaching manual) ---- */
.ds-col { fill: var(--green-200); stroke: var(--primary); stroke-width: var(--ix-thin); }
.ds-col.is-last { fill: var(--green-400); }
.ds-true { fill: none; stroke: var(--amber-text); stroke-width: var(--ix-thin); stroke-dasharray: 10 7; }
.ds-true-lab { fill: var(--amber-text); font-size: var(--ix-small); font-weight: var(--w-medium); }
.ds-rolls { fill: var(--muted); font-size: var(--ix-font); font-variant-numeric: tabular-nums; }

/* ---- balancer: a distribution on a beam, the fulcrum at the mean (teaching manual) ---- */
.bl-bar { fill: var(--green-200); stroke: var(--primary); stroke-width: var(--ix-thin); }
.bl-bar.is-thin { stroke-width: 1; }
.bl-bar.is-on { fill: var(--green-400); }
.bl-curve { fill: none; }
.bl-beamline { stroke: var(--primary); stroke-width: calc(var(--ix-axis) * 2.5); stroke-linecap: round; }
.bl-fulcrum { fill: var(--amber); stroke: var(--amber-text); stroke-width: 1.5; stroke-linejoin: round; cursor: grab; }
.bl-fulcrum.is-held { fill: var(--amber-bg); }
.bl-bracket { fill: none; stroke: var(--amber-text); stroke-width: var(--ix-thin); stroke-linejoin: round; }
.bl-mu, .bl-mode { stroke: var(--amber-text); stroke-width: var(--ix-thin); stroke-dasharray: 10 7; }
.bl-arrow { stroke: var(--ix-accent); stroke-width: var(--ix-thin); fill: var(--ix-accent); stroke-linejoin: round; }
.bl-bar.is-fine { stroke: none; }
/* shading in a series colour (a shade's `colour: n`), and an open point
   (a hole at a removable gap) that stays hollow when it carries a tip */
.ix-shade.s0 { fill: var(--ix-s0); opacity: .55; }
.ix-shade.s1 { fill: var(--ix-s1); opacity: .45; }
.ix-shade.s2 { fill: var(--ix-s2); opacity: .45; }
.ix-shade.s3 { fill: var(--ix-s3); opacity: .35; }
.ix-point.is-open.has-tip circle:not(.ix-halo) { fill: var(--surface); stroke: var(--primary); stroke-width: calc(var(--ix-thin) * 1.1); }
/* ---- triangle (teaching manual: Triangle explorer, Unit 4 skills 10 to 13) ---- */
.tx-fill { fill: var(--green-100); opacity: .8; }
.tx-lit { fill: var(--green-300); opacity: .5; }
.tx-lit.is-s1 { fill: var(--amber); opacity: .3; }
.tx-iso { fill: var(--ix-accent); opacity: .16; }
.tx-side { stroke: var(--primary); stroke-width: calc(var(--ix-thin) * 1.25); stroke-linecap: round; }
.tx-side.is-mark { stroke: var(--ix-accent); stroke-width: calc(var(--ix-thin) * 1.7); }
.tx-side.is-grey { opacity: .28; }
.tx-ext { stroke: var(--muted); stroke-width: var(--ix-thin); stroke-dasharray: 3 7; stroke-linecap: round; }
.tx-perp { stroke: var(--green-600); stroke-width: var(--ix-thin); stroke-dasharray: 10 7; }
.tx-perp.is-mark { stroke: var(--ix-accent); stroke-dasharray: none; stroke-width: calc(var(--ix-thin) * 1.5); }
.tx-right { fill: none; stroke: var(--green-600); stroke-width: 1.5; }
.tx-arc { fill: none; stroke: var(--primary); stroke-width: var(--ix-thin); }
.tx-arc.is-mark { stroke: var(--ix-accent); stroke-width: calc(var(--ix-thin) * 1.4); }
.tx-arc.is-lit { stroke: var(--ix-s2); stroke-width: calc(var(--ix-thin) * 1.4); }
.tx-circle { fill: none; stroke: var(--muted); stroke-width: 1.5; stroke-dasharray: 4 6; opacity: .7; }
.tx-rod { stroke: var(--ix-s0); stroke-width: calc(var(--ix-thin) * 1.5); stroke-linecap: round; }
.tx-rod.is-s1 { stroke: var(--ix-s1); }
.tx-rod.is-grey { stroke: var(--muted); opacity: .4; stroke-dasharray: 8 6; }
.tx-tick { stroke: var(--ix-accent); stroke-width: var(--ix-thin); }
.tx-halo { fill: var(--green-400); opacity: .18; }
.tx-lab { fill: var(--primary); font-size: var(--ix-font); font-weight: var(--w-medium); paint-order: stroke; stroke: var(--surface); stroke-width: 5px; stroke-linejoin: round; pointer-events: none; }
.tx-lab.is-side { font-style: italic; }
.tx-lab.is-small { font-size: var(--ix-small); font-style: normal; }
.tx-lab.is-mark { fill: var(--ix-accent); }
.tx-lab.is-grey { opacity: .4; }
.tx-lab.is-s1 { fill: var(--ix-s1); }
.tx-lab.is-bar { font-style: normal; }
.tx-lab.is-gap { font-size: var(--ix-small); fill: var(--amber-text); }
.tx-lab.is-gap.is-hit { fill: var(--green-600); font-weight: var(--w-semibold); }
.ix-point.is-grey { opacity: .35; }
.tx-bar { fill: var(--green-200); stroke: var(--primary); stroke-width: 1.5; }
.tx-bar.is-c { fill: var(--green-300); }
.tx-bar.is-hit { fill: var(--green-400); }
.tx-gap { fill: var(--amber); opacity: .45; }
.tx-gap.is-minus { fill: var(--surface); opacity: .85; stroke: var(--amber); stroke-width: 2; stroke-dasharray: 6 4; }

/* ---- frame-3d (teaching manual: 3D frame, Unit 4 skill 15) ---- */
.f3-edge { stroke: var(--primary); stroke-width: calc(var(--ix-thin) * 1.1); stroke-linecap: round; }
.f3-edge.is-hidden { stroke: var(--muted); stroke-width: var(--ix-thin); stroke-dasharray: 7 7; opacity: .75; }
.f3-edge.is-ghost { stroke: var(--muted); opacity: .55; }
.f3-edge.is-lit { stroke: var(--ix-accent); stroke-width: calc(var(--ix-thin) * 1.6); stroke-dasharray: none; opacity: 1; }
.f3-lit { fill: var(--green-300); opacity: .45; }
.f3-lit.is-left { opacity: .2; }
.f3-lit.is-flat { opacity: .55; }
.f3-north { fill: var(--muted); stroke: var(--muted); stroke-width: 1.5; }
.f3-dot { fill: var(--primary); }
/* ---- stack-plot (teaching manual): shades in a series colour, the legs of a path ---- */
.ix-shade.s1 { fill: color-mix(in srgb, var(--amber) 40%, transparent); opacity: 1; }
.ix-shade.s2 { fill: color-mix(in srgb, var(--answer-ink) 22%, transparent); opacity: 1; }
.ix-shade.s3 { fill: var(--track); }
.stk-leg { stroke: var(--primary); stroke-width: var(--ix-thin); stroke-linecap: round; }
.stk-leg-lab { fill: var(--primary); font-size: var(--ix-small); font-weight: var(--w-semibold); font-variant-numeric: tabular-nums; }
.ix-kind-stack-plot .ix-note { font-size: calc(var(--ix-font) * 1.4); font-weight: var(--w-semibold); }
/* ---- areas (areas.js): regions under and between curves, and strip sums ---- */
.ix-fill { fill: var(--green-200); opacity: .75; stroke: none; }
.ix-fill.t-dense { fill: var(--green-300); opacity: .8; }
.ix-fill.t-light { fill: var(--green-100); opacity: .9; }
.ix-fill.t-strong { fill: var(--ix-accent); opacity: .45; }
.ix-fill.is-pos { fill: var(--green-300); opacity: .7; }
.ix-fill.is-neg { fill: var(--amber); opacity: .4; }
.ix-strips { fill: var(--green-100); opacity: .55; stroke: none; }
.ix-strip-edge { fill: none; stroke: var(--green-700); stroke-width: var(--ix-thin); stroke-linejoin: round; opacity: .85; }
.ix-strip-edge.is-dense { stroke-width: 1; opacity: .55; }
.ix-tint.is-over { fill: var(--amber); opacity: .45; }
.ix-tint.is-under { fill: var(--ix-accent); opacity: .28; }
.ix-region.is-faint .ix-strips { opacity: 0; }
.ix-region.is-faint .ix-strip-edge { stroke: var(--muted); stroke-dasharray: 6 5; opacity: .6; }
.ix-fill.is-back { fill: var(--amber); opacity: .4; }
/* ---- histogram (teaching manual, Unit 4 skill 16) ---- */
.hd-row { align-items: center; }
.hd-row-label { flex-basis: 100%; font-size: var(--ix-small); color: var(--muted); }
.hd-bar { fill: var(--green-200); stroke: var(--primary); stroke-width: calc(var(--ix-thin) * .6); }
.hd-bars.is-faint .hd-bar { opacity: .35; }
.hd-over-arrow { fill: none; stroke: var(--primary); stroke-width: var(--ix-thin); stroke-linecap: round; stroke-linejoin: round; }
.hd-shade { fill: var(--amber); opacity: .45; }
.hd-row .ix-chip { min-width: calc(var(--ix-control) * 1.1); padding: 0 calc(var(--ix-control) * .26); }
/* ---- the circle kinds: radian-wrap, unit-circle, ferris-wheel (teaching manual) ---- */
.uc-lab, .rw-lab, .rw-num { fill: var(--primary); font-size: var(--ix-label); font-style: italic; paint-order: stroke; stroke: var(--surface); stroke-width: 4px; stroke-linejoin: round; }
.rw-num { font-style: normal; font-weight: var(--w-semibold); font-variant-numeric: tabular-nums; }
.uc-arc-lab { font-style: normal; font-weight: var(--w-medium); }
.uc-p-lab { font-weight: var(--w-semibold); }
.uc-cos-lab { fill: var(--ix-s1); }
.uc-sin-lab { fill: var(--ix-s0); }
.uc-mirror-lab { fill: var(--ix-accent); font-style: normal; }
.uc-radius { stroke: var(--ink); stroke-width: var(--ix-thin); stroke-linecap: round; }
.uc-cos { stroke: var(--ix-s1); stroke-width: calc(var(--ix-curve) * 1.1); stroke-linecap: round; }
.uc-sin { stroke: var(--ix-s0); stroke-width: calc(var(--ix-curve) * 1.1); stroke-linecap: round; }
.uc-arc { fill: none; stroke: var(--ink); stroke-width: calc(var(--ix-thin) * .8); }
.uc-arc-head { fill: var(--ink); }
.uc-ref { fill: var(--green-200); opacity: .8; }
.uc-ghost { fill: none; stroke: var(--muted); stroke-width: var(--ix-thin); stroke-dasharray: 7 6; opacity: .7; }
.uc-mirror { stroke: var(--ix-accent); stroke-width: var(--ix-thin); stroke-linecap: round; }
.uc-mirror-tri { fill: none; stroke: var(--ix-accent); stroke-width: 1.5; stroke-dasharray: 6 6; opacity: .6; }
.ix-point.has-tip.uc-mirror-dot circle:not(.ix-halo) { fill: var(--ix-accent); }
.uc-quad { fill: var(--surface-mint); }
.uc-sign { fill: var(--muted); font-size: var(--ix-label); }
.uc-sign.is-here { fill: var(--primary); font-weight: var(--w-semibold); }
.rw-circle { fill: none; stroke: var(--primary); stroke-width: var(--ix-thin); opacity: .55; }
.rw-wedge { fill: var(--green-100); }
.rw-wedge.is-alt { fill: var(--amber-bg); }
.rw-wedge.is-last { fill: var(--green-300); }
.rw-sector { fill: var(--green-200); opacity: .8; }
.rw-spoke { stroke: var(--green-300); stroke-width: 1.5; }
.rw-radius { stroke: var(--primary); stroke-width: calc(var(--ix-curve) * .8); stroke-linecap: round; }
.rw-strip { fill: none; stroke: var(--ix-s0); stroke-width: calc(var(--ix-curve) * 2); stroke-linecap: butt; }
.rw-strip.is-alt { stroke: var(--ix-s1); }
.rw-strip.is-moving, .rw-strip.is-last { stroke: var(--ix-s2); }
.rw-strip.is-over { stroke: var(--ix-s3); stroke-width: var(--ix-curve); stroke-dasharray: 8 6; opacity: .7; }
.rw-arc { fill: none; stroke: var(--ix-s1); stroke-width: calc(var(--ix-curve) * 1.6); stroke-linecap: round; }
.rw-lab.is-arc { fill: var(--ix-s1); }
.rw-centre, .fw-hub { fill: var(--primary); }
.fw-ground { stroke: var(--primary); stroke-width: var(--ix-axis); }
.fw-leg { stroke: var(--muted); stroke-width: var(--ix-thin); stroke-linecap: round; }
.fw-rim { fill: none; stroke: var(--primary); stroke-width: var(--ix-thin); }
.fw-spoke { stroke: var(--green-300); stroke-width: 1.2; }
.fw-arm { stroke: var(--primary); stroke-width: var(--ix-thin); }
.fw-car { fill: var(--amber); stroke: var(--ink); stroke-width: 1.5; }
.fw-ext { stroke: var(--muted); stroke-width: 1.2; stroke-dasharray: 3 5; }
.fw-bracket { fill: none; stroke: var(--muted); stroke-width: 1.5; }
.fw-bracket-lab { fill: var(--muted); font-size: var(--ix-small); font-variant-numeric: tabular-nums; }
.ix-point.has-tip.fw-turn circle:not(.ix-halo) { fill: var(--surface); stroke: var(--primary); stroke-width: 2; }
