/* Figure: mixing paint on a palette — the same interpolation weights the
   octopus figure draws, with colour standing in for the latent code.
   Behaviour lives in static/js/palette-mixing.js;
   markup is <d-figure id="palette-mixing-figure"> in src/index.html.

   Sizes inside the SVG are in the artwork's user units. The read-out sits under
   the artwork rather than beside it, so the viewBox is the export's own 979
   across by 812 down; the figure sits in the *text* column, matching the caption
   beneath it, which is 704 px at full width. A unit is therefore about 0.72 px
   and the font sizes here read some 28% smaller than the numbers suggest. (The
   octopus's artwork is three times coarser, hence its very different numbers.) */

/* Colours come from the shared theme (static/js/theme.js); the literals here are
   only fallbacks for if it fails to load. The paint colours themselves are the
   illustration's own and are deliberately not themed — each marker sits on the
   dab of paint it names. */
.pm {
  /* inside the SVG: fixed, because the artwork is a light watercolour surface */
  --pm-ink: var(--vx-panel-ink, #16160f);
  --pm-ink-muted: var(--vx-panel-muted, #6b6a63);
  --pm-rule: var(--vx-panel-rule, #cfcec6);
  --pm-grid: var(--vx-panel-grid, #e6e5dd);
  --pm-accent: var(--vx-accent, #eb6834); /* the highlighted paint and its arm */
  /* outside the SVG: follows the page theme */
  --pm-chrome-muted: var(--vx-muted, #6b6a63);
  --pm-chrome-rule: var(--vx-rule, #d8d7cf);
  margin: 2rem 0 2.5rem;
}

/* The illustration is ink-and-watercolour on paper, so the figure keeps its
   light surface in dark mode; only the chrome around it follows the theme. */
.pm-svg {
  display: block;
  width: 100%;
  height: auto;
  background: var(--vx-panel, #fff);
  border-radius: 3px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
  touch-action: none;
}

/* ---- draggables: the z_i paints and the mixing point z ---- */
.pm-mover {
  cursor: grab;
}
.pm-mover:focus {
  outline: none;
}
.pm-mover.is-dragging {
  cursor: grabbing;
}
.pm-hit {
  fill: transparent; /* transparent, not none: it still takes the pointer */
}
/* A dab keeps a faint ring at rest: two of the paints are near-white, and a
   white disc on a cream palette has no edge of its own. */
.pm-mark {
  transition: stroke-opacity 120ms ease-out;
  stroke: var(--pm-ink);
  stroke-width: 2;
  stroke-opacity: 0.3;
}
.pm-mover.is-active .pm-mark,
.pm-mover:focus-visible .pm-mark {
  stroke: var(--pm-accent);
  stroke-width: 3.5;
  stroke-opacity: 1;
}
/* `z` carries the mixture, which is usually a muddy mid-tone, so it wears a
   heavier ring to stay separate from the wood underneath. */
.pm-hub .pm-mark {
  stroke-width: 3;
  stroke-opacity: 0.55;
}
.pm-hub.is-active .pm-mark,
.pm-hub:focus-visible .pm-mark {
  stroke: var(--pm-accent);
  stroke-width: 4;
  stroke-opacity: 1;
}

/* ---- arms ----
   Width is set per frame in the JS, because it *is* the weight: nothing here may
   set stroke-width, or a CSS rule would outrank the attribute and flatten the
   one encoding the arms carry. Highlighting changes colour only. */
.pm-spoke {
  stroke: #5d5a52;
  stroke-opacity: 0.7;
}
.pm-spoke.is-active {
  stroke: var(--pm-accent);
  stroke-opacity: 1;
}

/* ---- names on the circles ---- */
.pm-paint-label,
.pm-hub-label {
  font-size: 19px;
  fill: #fff;
  text-anchor: middle;
  pointer-events: none; /* the circle underneath keeps the drag */
}
/* Flipped by the JS from the brightness of the fill underneath — the paints
   run from near-black to near-white, and `z` changes colour as you drag it. */
.pm-paint-label.is-dark,
.pm-hub-label.is-dark {
  fill: var(--pm-ink);
}
.pm-hub-label {
  font-size: 17px;
}

/* ---- read-out ---- */
.pm-title {
  font-size: 18px;
  font-weight: 700;
  fill: var(--pm-ink);
}
.pm-math {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 400;
}
.pm-sub {
  font-size: 0.7em;
}
/* Each z_i label sits in a pill of its paint's own colour. The geometry — and
   the radius, half the pill's height — is set in the JS from the glyphs' box;
   only the paint is here. The faint ring is not decoration: two of the seven
   paints are near-white, and a white pill on the white panel has no edge. */
.pm-row-chip {
  stroke: var(--pm-ink);
  stroke-opacity: 0.25;
  stroke-width: 1;
}
.pm-bar.is-active .pm-row-chip {
  stroke: var(--pm-accent);
  stroke-opacity: 1;
  stroke-width: 2;
}
.pm-row-label {
  font-size: 16px;
  fill: #fff;
  text-anchor: middle;
  pointer-events: none; /* the chip and the hit rect keep the hover */
}
/* Flipped by the JS from the brightness of the paint underneath, the same way
   the labels on the dabs themselves are. The active row is marked on the chip's
   ring instead, since darkening the text would fight that flip. */
.pm-row-label.is-dark {
  fill: var(--pm-ink);
}
.pm-note {
  font-size: 14px;
  fill: var(--pm-ink-muted);
}
.pm-note-warn {
  fill: var(--pm-accent);
}
.pm-tick {
  font-size: 13px;
  fill: var(--pm-ink-muted);
  text-anchor: end; /* the scale runs up the left of the plot now */
}
.pm-grid line {
  stroke: var(--pm-grid);
  stroke-width: 1;
}
.pm-baseline {
  stroke: var(--pm-rule);
  stroke-width: 1.6;
}
.pm-bar-hit {
  fill: transparent;
}
.pm-bar {
  cursor: default;
}
.pm-bar-fill {
  stroke: var(--pm-rule);
  stroke-width: 0.8;
}
.pm-bar.is-active .pm-bar-fill {
  stroke: var(--pm-accent);
  stroke-width: 2;
}
/* Values stay on screen — the bars are short at an even mix, and reading them
   should not require hovering. The active row just gets darker. */
.pm-bar-value {
  font-size: 13px;
  fill: var(--pm-ink-muted);
  text-anchor: middle;
  transition: fill 120ms ease-out;
}
.pm-bar.is-active .pm-bar-value {
  fill: var(--pm-ink);
  font-weight: 700;
}

/* ---- the mixture: the recipe strip, then the colour it comes out as ---- */
.pm-strip-frame {
  fill: none;
  stroke: var(--pm-rule);
  stroke-width: 1;
}
/* Hairline separators so two neighbouring paints of a similar tone still read as
   two shares. Drawn in the panel white rather than in ink, so a thin segment
   loses width to the gap rather than turning into a dark line. */
.pm-strip-seg {
  stroke: var(--vx-panel, #fff);
  stroke-width: 0.8;
}
.pm-swatch {
  stroke: var(--pm-rule);
  stroke-width: 1;
}
.pm-swatch-value {
  font-size: 18px;
  font-family: Georgia, "Times New Roman", serif;
  fill: #fff;
  text-anchor: middle;
  pointer-events: none;
}
.pm-swatch-value.is-dark {
  fill: var(--pm-ink);
}

/* The artwork's <ellipse> is the drag domain. Normally a shape rather than a
   mark — drawn over the illustration it washes the whole palette pale — but
   "Rearrange the paints" shows it for the throw, since that is the one moment
   the region itself is what you want to see. Reset takes it away again.
   The opacity beats the element's own `opacity="0.67"` attribute, as any
   stylesheet rule beats a presentation attribute. */
.pm-domain {
  display: none;
}
.pm-domain.is-shown {
  display: inline;
  opacity: 0.887;
}

/* The cutoff of whichever kernel has one, as a ring around z: paints outside it
   earn nothing. */
.pm-cutoff {
  fill: none;
  stroke: var(--pm-ink);
  stroke-opacity: 0.45;
  stroke-width: 1.6;
  stroke-dasharray: 8 6;
  pointer-events: none;
}
.pm-cutoff.is-hidden {
  display: none;
}

/* ---- controls ---- */
.pm-controls {
  margin-top: 10px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
}
.pm-control-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
}
.pm-control-line + .pm-control-line {
  margin-top: 8px;
}

.pm-field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.pm-field-label {
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--pm-chrome-muted);
}
.pm-field-value {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12px;
  min-width: 2.2em;
}
.pm-slider input[type="range"] {
  width: 112px;
  accent-color: var(--pm-accent);
}
/* The cutoff means nothing to 1/d, so the whole field goes rather than being
   dimmed: a greyed control still asks to be read, and there is nothing to read.
   Two classes, so this beats the `display: inline-flex` on .pm-field alone. */
.pm-field.is-hidden {
  display: none;
}

/* the three kernels read as one segmented control */
.pm-modes {
  display: inline-flex;
}
.pm-btn-mode {
  border-radius: 0;
  margin-left: -1px;
}
.pm-btn-mode:first-child {
  border-radius: 4px 0 0 4px;
  margin-left: 0;
}
.pm-btn-mode:last-child {
  border-radius: 0 4px 4px 0;
}

.pm-btn {
  font: inherit;
  font-size: 12px;
  line-height: 1;
  padding: 6px 12px;
  color: inherit;
  background: transparent;
  border: 1px solid var(--pm-chrome-rule);
  border-radius: 4px;
  cursor: pointer;
}
.pm-btn:hover {
  border-color: var(--pm-chrome-muted);
}
.pm-btn i {
  font-family: Georgia, "Times New Roman", serif;
}
/* The wander toggles stay pressed while they run. */
.pm-btn.is-on {
  color: var(--vx-surface, #fcfcfb);
  background: var(--vx-ink, #16160f);
  border-color: var(--vx-ink, #16160f);
}

/* The hint is drawn inside the band now, so it is SVG and takes the panel's
   ink rather than the page chrome's. */
.pm-hint-svg {
  font-size: 14px;
  fill: var(--pm-ink-muted);
}
