/* Figure: the octopus grabbing marbles — interpolation weights.
   Behaviour lives in static/js/octopus-interpolation.js;
   markup is <d-figure id="octopus-figure"> in src/index.html.

   Sizes inside the SVG are in the artwork's user units (~2900 across), so the
   font sizes here look ~3× larger than they render. */

/* Colours come from the shared theme (static/js/theme.js); the literals here are
   only fallbacks for if it fails to load. The marble colours themselves are the
   theme's categorical palette, applied to the artwork in the JS. */
.oct {
  /* inside the SVG: fixed, because the panel stays on a white surface */
  --oct-ink: var(--vx-panel-ink, #16160f);
  --oct-ink-muted: var(--vx-panel-muted, #6b6a63);
  --oct-rule: var(--vx-panel-rule, #cfcec6);
  --oct-grid: var(--vx-panel-grid, #e6e5dd);
  --oct-accent: var(--vx-accent, #eb6834); /* the highlighted marble and its spoke */
  /* outside the SVG: follows the page theme */
  --oct-chrome-muted: var(--vx-muted, #6b6a63);
  --oct-chrome-rule: var(--vx-rule, #d8d7cf);
  margin: 2rem 0 2.5rem;
}

/* The artwork is pencil-on-white line art, so the panel keeps its light
   surface in dark mode; only the chrome around it follows the theme. */
.oct-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 marbles and the base point z ---- */
.oct-mover {
  cursor: grab;
}
.oct-mover:focus {
  outline: none;
}
.oct-mover.is-dragging {
  cursor: grabbing;
}
.oct-hit {
  fill: transparent; /* transparent, not none: it still takes the pointer */
}
.oct-mark {
  transition: stroke-opacity 120ms ease-out;
  stroke: var(--oct-ink);
  stroke-width: 6;
  stroke-opacity: 0;
}
.oct-mover.is-active .oct-mark,
.oct-mover:focus-visible .oct-mark {
  stroke-opacity: 0.45;
}
/* `z` carries the mixed colour of the marbles, which can come out pale, so it
   keeps a faint ring at rest to stay legible against the white panel. */
.oct-hub .oct-mark {
  stroke: var(--oct-ink);
  stroke-width: 6;
  stroke-opacity: 0.4;
}
.oct-hub.is-active .oct-mark,
.oct-hub:focus-visible .oct-mark {
  stroke: var(--oct-accent);
  stroke-width: 9;
  stroke-opacity: 1;
}

/* ---- spokes ---- */
.oct-spoke.is-active {
  stroke: var(--oct-accent);
  stroke-width: 12;
}

/* ---- names on the circles ---- */
.oct-marble-label,
.oct-hub-label {
  font-size: 54px;
  fill: var(--oct-ink);
  text-anchor: middle;
  pointer-events: none; /* the circle underneath keeps the drag */
}
/* `z`'s label flips with the brightness of the mixed fill underneath it. */
.oct-hub-label {
  font-size: 50px;
  fill: #fff;
}
.oct-hub-label.is-dark {
  fill: var(--oct-ink);
}

/* ---- read-outs ---- */
.oct-chart-title {
  font-size: 44px;
  font-weight: 700;
  fill: var(--oct-ink);
}
.oct-math {
  font-family: Georgia, "Times New Roman", serif;
  font-style: italic;
  font-weight: 400;
}
.oct-sub {
  font-size: 0.7em;
}
.oct-row-label {
  font-size: 42px;
  fill: var(--oct-ink-muted);
  text-anchor: end;
}
.oct-bar.is-active .oct-row-label {
  fill: var(--oct-ink);
}

/* ---- d_i → w_i ---- */
.oct-arrow {
  stroke: var(--oct-ink-muted);
  stroke-width: 7;
}
.oct-arrow-head {
  fill: var(--oct-ink-muted);
}
.oct-map {
  font-size: 44px;
  fill: var(--oct-ink);
}
.oct-formula {
  font-size: 40px;
  fill: var(--oct-ink);
  text-anchor: middle;
}
.oct-formula-lhs {
  text-anchor: end; /* the "w_i =" that sits left of the fraction */
}
.oct-frac-bar {
  stroke: var(--oct-ink);
  stroke-width: 4;
}
.oct-ref {
  stroke: var(--oct-ink-muted);
  stroke-width: 4;
  stroke-dasharray: 14 12;
}
.oct-chart-note,
.oct-tick {
  font-size: 36px;
  fill: var(--oct-ink-muted);
}
.oct-tick {
  text-anchor: middle;
}
.oct-grid line {
  stroke: var(--oct-grid);
  stroke-width: 3;
}
.oct-baseline {
  stroke: var(--oct-rule);
  stroke-width: 5;
}

.oct-bar-hit {
  fill: transparent;
}
.oct-bar {
  cursor: default;
}
.oct-bar-fill {
  stroke: var(--oct-rule);
  stroke-width: 2;
}
.oct-bar.is-active .oct-bar-fill {
  stroke: var(--oct-accent);
  stroke-width: 6;
}
/* Values stay on screen — weight bars are short, and reading them should not
   require hovering. The active row just gets darker. */
.oct-bar-value {
  font-size: 36px;
  fill: var(--oct-ink-muted);
  text-anchor: start;
  transition: fill 120ms ease-out;
}
.oct-bar.is-active .oct-bar-value {
  fill: var(--oct-ink);
  font-weight: 700;
}

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

.oct-field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.oct-field-label {
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--oct-chrome-muted);
}
.oct-field-value {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 12px;
  min-width: 2.2em;
}
.oct-slider input[type="range"] {
  width: 112px;
  accent-color: var(--oct-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 .oct-field alone. */
.oct-field.is-hidden {
  display: none;
}

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

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

.oct-hint {
  font-size: 12px;
  color: var(--oct-chrome-muted);
}
.oct-hint i {
  font-family: Georgia, "Times New Roman", serif;
}


/* The cutoff of whichever kernel has one, as a ring around z: marbles outside it
   earn nothing.
   Sizes are in the artwork's units, so the dashes look ordinary on screen. */
.oct-cutoff {
  fill: none;
  stroke: var(--oct-ink);
  stroke-opacity: 0.4;
  stroke-width: 5;
  stroke-dasharray: 24 18;
  pointer-events: none;
}
.oct-cutoff.is-hidden {
  display: none;
}
