/*
 * Research machine (hero object). The drawing comes from build-research-machine.mjs; its class names (iso-*, tb-*)
 * are the Anatomy kit's, and every fill and stroke reads a token, so a part recedes or lights up by a token swap.
 *
 * Which assembly runs: data-live="<slug>" on the <svg class="robj"> or on any element around it (the research pages
 * put it on .robj-host). Slugs: core, protocol, proofs, economy, rwa, eip, updates. Any other value ("main", "all",
 * "") runs the whole machine: the rotations turn at their own slow rates and the events (a coin paid out, the valve
 * switching, the proof lamps, the stamp, the meter, the beacon) take turns inside one cycle, --robj-cycle.
 *
 * Contexts: .robj alone is drawn for a light ground; inside .rs-night, [data-theme="dark"] or .robj-dark it is drawn
 * for a dark ground. data-paused (set by ORZ_MACHINE.mount while the drawing is off screen) holds every motion.
 */

/* ---------- tokens: light ground ---------- */
.robj {
  --anatomy-paper: #ffffff;
  --anatomy-face: #ffffff;
  --anatomy-top: #ffffff;
  --anatomy-shade-0: #cbd4e2;
  --anatomy-shade-1: #d9e0eb;
  --anatomy-shade-2: #e5eaf2;
  --anatomy-shade-3: #f0f3f8;
  --anatomy-lit-top: #ffffff;
  --anatomy-lit-shade: #eef2f8;
  --anatomy-hi: #22324a;
  --anatomy-mid: #72829a;
  --anatomy-lo: #a8b4c5;
  --anatomy-faint: #d0d8e3;
  --anatomy-lit: #2473ff;
  --anatomy-halo: #5d6e8a;
  --anatomy-halo-opacity: 0.26;
  --anatomy-dot: #34435b;
  --anatomy-weight: 0.7px;
  --robj-glow: #2fd0f5;
  --robj-glow-edge: #0b5cf0;
  --robj-flow: #2473ff;
  --robj-seal: #8a97ab;
  --robj-cycle: 14s;
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* ---------- tokens: dark ground (hero night section, dark theme) ---------- */
:is(.rs-night, [data-theme="dark"], .robj-dark) .robj {
  --anatomy-paper: #0f1a33;
  --anatomy-face: #14234a;
  --anatomy-top: #1d3366;
  --anatomy-shade-0: #0d1730;
  --anatomy-shade-1: #111d3c;
  --anatomy-shade-2: #152448;
  --anatomy-shade-3: #1a2b55;
  --anatomy-lit-top: #243f7a;
  --anatomy-lit-shade: #1b3163;
  --anatomy-hi: #b4cdff;
  --anatomy-mid: #6896f4;
  --anatomy-lo: #4370cc;
  --anatomy-faint: #2c4f97;
  --anatomy-lit: #5bdcf3;
  --anatomy-halo: #000000;
  --anatomy-halo-opacity: 0.8;
  --anatomy-dot: #b4cdff;
  --robj-glow: #5bdcf3;
  --robj-glow-edge: #dff8ff;
  --robj-flow: #69ddff;
  --robj-seal: #6896f4;
}

/* the bench sits one step behind the machine on it */
.robj [data-part="bench"] {
  --anatomy-top: #f6f8fc;
  --anatomy-hi: #7a889e;
}
:is(.rs-night, [data-theme="dark"], .robj-dark) .robj [data-part="bench"] {
  --anatomy-paper: #0d1730;
  --anatomy-top: #14254d;
  --anatomy-shade-0: #0a1229;
  --anatomy-shade-1: #0c1630;
  --anatomy-shade-2: #0f1a37;
  --anatomy-shade-3: #121f40;
  --anatomy-hi: #5d8ae6;
  --anatomy-mid: #3e66b8;
  --anatomy-lo: #2e529a;
  --anatomy-faint: #22417c;
}

/* ---------- recede: every assembly but the live one (token swap, never transparency) ---------- */
:is(.robj:is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]), :is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]) .robj) [data-part] {
  --anatomy-shade-0: #e1e6ee;
  --anatomy-shade-1: #e8ecf2;
  --anatomy-shade-2: #eef1f6;
  --anatomy-shade-3: #f4f6f9;
  --anatomy-hi: #9eabbe;
  --anatomy-mid: #bac4d2;
  --anatomy-lo: #d0d7e1;
  --anatomy-faint: #e0e5ec;
  --anatomy-dot: #b2bdcc;
  --robj-seal: #d0d7e1;
}

:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj:is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]), :is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]) .robj) [data-part] {
  --anatomy-paper: #0c1428;
  --anatomy-face: #0f1931;
  --anatomy-top: #13203e;
  --anatomy-shade-0: #0a1123;
  --anatomy-shade-1: #0c152a;
  --anatomy-shade-2: #0f1932;
  --anatomy-shade-3: #121e3a;
  --anatomy-hi: #4a68a6;
  --anatomy-mid: #344f86;
  --anatomy-lo: #283f6e;
  --anatomy-faint: #1e315a;
  --anatomy-dot: #4a68a6;
  --robj-seal: #283f6e;
}

/* ---------- accent: the live assembly, in the company blue and cyan ---------- */
:is(.robj[data-live="core"], [data-live="core"] .robj) [data-part="core"],
:is(.robj[data-live="protocol"], [data-live="protocol"] .robj) [data-part="protocol"],
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) [data-part="proofs"],
:is(.robj[data-live="economy"], [data-live="economy"] .robj) [data-part="economy"],
:is(.robj[data-live="rwa"], [data-live="rwa"] .robj) [data-part="rwa"],
:is(.robj[data-live="eip"], [data-live="eip"] .robj) [data-part="eip"],
:is(.robj[data-live="updates"], [data-live="updates"] .robj) [data-part="updates"] {
  --anatomy-paper: #ffffff;
  --anatomy-face: #f4f8ff;
  --anatomy-top: #eaf2ff;
  --anatomy-shade-0: #a8c4fb;
  --anatomy-shade-1: #bad1fc;
  --anatomy-shade-2: #cddefd;
  --anatomy-shade-3: #dfeafe;
  --anatomy-hi: #0b5cf0;
  --anatomy-mid: #4b84f7;
  --anatomy-lo: #8cb0fa;
  --anatomy-faint: #c1d5fc;
  --anatomy-dot: #2473ff;
  --robj-seal: #2473ff;
}

:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="core"], [data-live="core"] .robj) [data-part="core"],
:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="protocol"], [data-live="protocol"] .robj) [data-part="protocol"],
:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="proofs"], [data-live="proofs"] .robj) [data-part="proofs"],
:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="economy"], [data-live="economy"] .robj) [data-part="economy"],
:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="rwa"], [data-live="rwa"] .robj) [data-part="rwa"],
:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="eip"], [data-live="eip"] .robj) [data-part="eip"],
:is(.rs-night, [data-theme="dark"], .robj-dark) :is(.robj[data-live="updates"], [data-live="updates"] .robj) [data-part="updates"] {
  --anatomy-paper: #0c2a45;
  --anatomy-face: #10375a;
  --anatomy-top: #17507f;
  --anatomy-shade-0: #0d2c4b;
  --anatomy-shade-1: #113558;
  --anatomy-shade-2: #153f66;
  --anatomy-shade-3: #1a4a75;
  --anatomy-hi: #a6f3ff;
  --anatomy-mid: #4fd3f2;
  --anatomy-lo: #2f97c4;
  --anatomy-faint: #22668f;
  --anatomy-dot: #a6f3ff;
  --robj-seal: #5bdcf3;
}

/* ---------- the kit's drawing rules, scoped ---------- */
.robj path,
.robj circle,
.robj rect {
  vector-effect: non-scaling-stroke;
}
.robj .iso-fill {
  fill: var(--anatomy-paper);
  stroke: none;
}
.robj .iso-solid[data-lit] > .iso-fill {
  fill: var(--anatomy-face);
}
.robj .iso-shade,
.robj .iso-top {
  stroke: none;
}
.robj .iso-shade[data-shade="0"] {
  fill: var(--anatomy-shade-0);
}
.robj .iso-shade[data-shade="1"] {
  fill: var(--anatomy-shade-1);
}
.robj .iso-shade[data-shade="2"] {
  fill: var(--anatomy-shade-2);
}
.robj .iso-shade[data-shade="3"] {
  fill: var(--anatomy-shade-3);
}
.robj .iso-top {
  fill: var(--anatomy-top);
}
.robj .iso-solid[data-seamless] > .iso-shade,
.robj .iso-solid[data-seamless] > .iso-top {
  stroke-linejoin: round;
  stroke-width: 0.4px;
}
.robj .iso-solid[data-seamless] > .iso-shade[data-shade="0"] {
  stroke: var(--anatomy-shade-0);
}
.robj .iso-solid[data-seamless] > .iso-shade[data-shade="1"] {
  stroke: var(--anatomy-shade-1);
}
.robj .iso-solid[data-seamless] > .iso-shade[data-shade="2"] {
  stroke: var(--anatomy-shade-2);
}
.robj .iso-solid[data-seamless] > .iso-shade[data-shade="3"] {
  stroke: var(--anatomy-shade-3);
}
.robj .iso-solid[data-seamless] > .iso-top {
  stroke: var(--anatomy-top);
}
.robj .iso-halo {
  fill: var(--anatomy-halo);
  filter: blur(9px);
  opacity: var(--anatomy-halo-opacity);
  stroke: none;
  transform: translateY(3px);
}
.robj .iso-line {
  fill: none;
  stroke: var(--anatomy-lo);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: var(--anatomy-weight);
}
.robj .iso-line[data-tone="hi"] {
  stroke: var(--anatomy-hi);
}
.robj .iso-line[data-tone="mid"] {
  stroke: var(--anatomy-mid);
}
.robj .iso-line[data-tone="faint"] {
  stroke: var(--anatomy-faint);
}
.robj .iso-line[data-tone="lit"] {
  stroke: var(--anatomy-lit);
}
.robj .iso-dots circle {
  fill: var(--anatomy-dot);
  opacity: 0.32;
  stroke: none;
}
.robj .iso-dots[data-tone="hi"] circle {
  opacity: 0.85;
}
.robj .iso-dots[data-tone="mid"] circle {
  opacity: 0.45;
}
.robj .iso-dots[data-tone="lo"] circle {
  opacity: 0.22;
}
.robj .tb-body {
  fill: var(--anatomy-shade-2);
  stroke: none;
}
.robj .tb-shine {
  fill: var(--anatomy-top);
  stroke: none;
}
.robj .tb-shade {
  fill: var(--anatomy-shade-0);
  stroke: none;
}

/* ---------- flat features drawn in the plane of a face ---------- */
.robj .robj-index {
  fill: var(--anatomy-hi);
}
.robj .robj-hub,
.robj .robj-knob {
  fill: var(--anatomy-top);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-boss,
.robj .robj-hub-ring {
  fill: var(--anatomy-shade-2);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-rod {
  fill: var(--anatomy-top);
  stroke: var(--anatomy-hi);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-rod-side {
  fill: var(--anatomy-shade-1);
  stroke: var(--anatomy-hi);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-pin {
  fill: var(--anatomy-shade-0);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-teeth {
  fill: var(--anatomy-top);
  stroke: var(--anatomy-hi);
  stroke-linejoin: round;
  stroke-width: var(--anatomy-weight);
}
.robj .robj-hole {
  fill: var(--anatomy-shade-0);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-weight {
  fill: var(--anatomy-mid);
}
.robj .robj-dial {
  fill: var(--anatomy-paper);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-needle {
  transform: rotate(-40deg);
}
.robj .robj-needle-line {
  fill: none;
  stroke: var(--anatomy-hi);
  stroke-linecap: round;
  stroke-width: 1.1px;
}
.robj .robj-lamp {
  fill: var(--anatomy-shade-0);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-beacon-glow {
  fill: var(--robj-glow);
  opacity: 0;
  stroke: var(--robj-glow-edge);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-spoke {
  fill: none;
  stroke: var(--anatomy-hi);
  stroke-linecap: round;
  stroke-width: 1.1px;
}
.robj .robj-vault-wheel .robj-spoke {
  stroke-width: 1.5px;
}
/* the vault: bolt heads on the door, hinge straps, the payout slot */
.robj .robj-bolt {
  fill: var(--anatomy-mid);
}
.robj .robj-strap {
  fill: var(--anatomy-shade-1);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-slot {
  fill: var(--anatomy-shade-0);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
/* the standards: binder labels numbered by bars, the title block of the specification, the approval seal */
.robj .robj-label {
  fill: var(--anatomy-top);
  stroke: var(--anatomy-mid);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-label-bars {
  fill: none;
  stroke: var(--anatomy-hi);
  stroke-linecap: round;
  stroke-width: 1px;
}
.robj .robj-doc-head {
  fill: var(--anatomy-shade-1);
  stroke: var(--anatomy-lo);
  stroke-width: var(--anatomy-weight);
}
.robj .robj-seal-disc {
  fill: var(--robj-seal);
}
.robj .robj-seal-ring {
  fill: none;
  stroke: var(--anatomy-paper);
  stroke-width: 0.7px;
}
.robj .robj-seal-check {
  fill: none;
  stroke: var(--anatomy-paper);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.3px;
}

/* pulses in the pipes and rings from the beacon; drawn over the machine */
.robj .robj-flow {
  fill: none;
  opacity: 0;
  stroke: var(--robj-flow);
  stroke-dasharray: 0.1 7;
  stroke-linecap: round;
  stroke-width: 2.2px;
  vector-effect: none;
}
.robj .robj-ring {
  fill: none;
  opacity: 0;
  stroke: var(--robj-glow);
  stroke-width: 1px;
}

/* every moving group turns or slides about its own local origin */
.robj :is(.robj-drum, .robj-drum-back, .robj-gear, .robj-fly, .robj-valve, .robj-needle, .robj-ring, .robj-vault-wheel, .robj-vault-dial, .robj-coin, .robj-stamp) {
  transform-box: view-box;
  transform-origin: 0 0;
}

/* ---------- motion: the whole machine running (main page) ----------
 * Rotations turn at their own slow rates (drums 9 s, gears 1.75 times their area speed, flywheel 5.6 s, pulses
 * 1.6 s). The events share one cycle and never start together: the vault pays a coin (0 to 33 %), the valve sends
 * the pulses to the other outlet (34 %), the proof lamps light in turn (41 to 57 %), the stamp seals the
 * specification (60 to 68 %), the meter climbs (69 to 80 %), the beacon flashes (82 %), the valve switches back
 * (90 %). */
.robj .robj-drum {
  animation: robj-cw 9s linear infinite;
}
.robj .robj-drum-back {
  animation: robj-ccw 9s linear infinite;
}
.robj .robj-gear[data-way="cw"] {
  animation: robj-cw calc(var(--t) * 1.75) linear infinite;
}
.robj .robj-gear[data-way="ccw"] {
  animation: robj-ccw calc(var(--t) * 1.75) linear infinite;
}
.robj .robj-fly {
  animation: robj-cw 5.6s linear infinite;
}
.robj .robj-flow {
  animation: robj-flow 1.6s linear infinite;
  opacity: 0.85;
}
.robj .robj-flow[data-flow="a"] {
  animation: robj-flow 1.6s linear infinite, robj-m-route-a var(--robj-cycle) linear infinite;
}
.robj .robj-flow[data-flow="b"] {
  animation: robj-flow 1.6s linear infinite, robj-m-route-b var(--robj-cycle) linear infinite;
}
.robj .robj-valve {
  animation: robj-m-valve var(--robj-cycle) ease-in-out infinite;
}
.robj .robj-vault-dial {
  animation: robj-m-dial var(--robj-cycle) ease-in-out infinite;
}
.robj .robj-vault-wheel {
  animation: robj-m-wheel var(--robj-cycle) ease-in-out infinite;
}
.robj .robj-coin {
  animation: robj-m-coin var(--robj-cycle) linear infinite;
}
.robj .robj-lamp {
  animation: var(--robj-cycle) linear infinite;
}
.robj .robj-lamp[data-lamp="0"] {
  animation-name: robj-m-lamp-0;
}
.robj .robj-lamp[data-lamp="1"] {
  animation-name: robj-m-lamp-1;
}
.robj .robj-lamp[data-lamp="2"] {
  animation-name: robj-m-lamp-2;
}
.robj .robj-lamp[data-lamp="3"] {
  animation-name: robj-m-lamp-3;
}
.robj .robj-lamp[data-lamp="accept"] {
  animation-name: robj-m-lamp-accept;
}
.robj .robj-stamp {
  animation: robj-m-stamp var(--robj-cycle) linear infinite;
}
.robj .robj-seal {
  animation: robj-m-seal var(--robj-cycle) linear infinite;
}
.robj .robj-needle {
  animation: robj-m-needle var(--robj-cycle) ease-in-out infinite;
}
.robj .robj-beacon-glow {
  animation: robj-m-flash var(--robj-cycle) linear infinite;
}
.robj .robj-ring {
  animation: robj-m-ring var(--robj-cycle) ease-out infinite;
  animation-delay: calc(var(--n) * 0.35s);
}

/* ---------- an area page: one assembly live, everything else stands still ---------- */
:is(.robj:is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]), :is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]) .robj) :is(.robj-drum, .robj-drum-back, .robj-gear, .robj-fly, .robj-flow, .robj-valve, .robj-vault-dial, .robj-vault-wheel, .robj-coin, .robj-lamp, .robj-stamp, .robj-seal, .robj-needle, .robj-beacon-glow, .robj-ring) {
  animation: none;
}
:is(.robj:is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]), :is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]) .robj) .robj-flow {
  opacity: 0;
}

/* core: both drums turn as one; the coupling rod circles without turning */
:is(.robj[data-live="core"], [data-live="core"] .robj) .robj-drum {
  animation: robj-cw 5s linear infinite;
}
:is(.robj[data-live="core"], [data-live="core"] .robj) .robj-drum-back {
  animation: robj-ccw 5s linear infinite;
}

/* protocol: pulses run from the core into the valve; the valve turns and sends them out one way, then the other */
:is(.robj[data-live="protocol"], [data-live="protocol"] .robj) .robj-valve {
  animation: robj-valve 5s ease-in-out infinite;
}
:is(.robj[data-live="protocol"], [data-live="protocol"] .robj) .robj-flow {
  animation: robj-flow 1.1s linear infinite;
  opacity: 1;
}
:is(.robj[data-live="protocol"], [data-live="protocol"] .robj) .robj-flow[data-flow="a"] {
  animation: robj-flow 1.1s linear infinite, robj-route-a 5s linear infinite;
}
:is(.robj[data-live="protocol"], [data-live="protocol"] .robj) .robj-flow[data-flow="b"] {
  animation: robj-flow 1.1s linear infinite, robj-route-b 5s linear infinite;
}

/* proofs: the gears turn in mesh (equal rim speed), the lamps light one by one, then the accept lamp */
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-gear[data-way="cw"] {
  animation: robj-cw var(--t) linear infinite;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-gear[data-way="ccw"] {
  animation: robj-ccw var(--t) linear infinite;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp {
  animation: 6.4s linear infinite;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp[data-lamp="0"] {
  animation-name: robj-lamp-0;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp[data-lamp="1"] {
  animation-name: robj-lamp-1;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp[data-lamp="2"] {
  animation-name: robj-lamp-2;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp[data-lamp="3"] {
  animation-name: robj-lamp-3;
}
:is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp[data-lamp="accept"] {
  animation-name: robj-lamp-accept;
}

/* economy: the flywheel spins and the meter needle climbs, settles and resets */
:is(.robj[data-live="economy"], [data-live="economy"] .robj) .robj-fly {
  animation: robj-cw 3.2s linear infinite;
}
:is(.robj[data-live="economy"], [data-live="economy"] .robj) .robj-needle {
  animation: robj-needle 6.4s ease-in-out infinite;
}

/* rwa: the dial turns the combination, the handle unlocks, the vault pays a coin out of its slot onto the stack */
:is(.robj[data-live="rwa"], [data-live="rwa"] .robj) .robj-vault-dial {
  animation: robj-dial 6s ease-in-out infinite;
}
:is(.robj[data-live="rwa"], [data-live="rwa"] .robj) .robj-vault-wheel {
  animation: robj-wheel 6s ease-in-out infinite;
}
:is(.robj[data-live="rwa"], [data-live="rwa"] .robj) .robj-coin {
  animation: robj-coin 6s linear infinite;
}

/* eip: the stamp comes down on the specification and lifts away from a fresh approval seal */
:is(.robj[data-live="eip"], [data-live="eip"] .robj) .robj-stamp {
  animation: robj-stamp 3.2s linear infinite;
}
:is(.robj[data-live="eip"], [data-live="eip"] .robj) .robj-seal {
  animation: robj-seal 3.2s linear infinite;
}

/* updates: the beacon flashes and sends out rings */
:is(.robj[data-live="updates"], [data-live="updates"] .robj) .robj-beacon-glow {
  animation: robj-flash 2.4s linear infinite;
}
:is(.robj[data-live="updates"], [data-live="updates"] .robj) .robj-ring {
  animation: robj-ring 2.4s ease-out infinite;
  animation-delay: calc(var(--n) * -0.8s);
}

/* off screen: hold every motion where it is */
.robj[data-paused] * {
  animation-play-state: paused !important;
}

/* ---------- keyframes shared by both modes ---------- */
@keyframes robj-cw {
  to {
    transform: rotate(360deg);
  }
}
@keyframes robj-ccw {
  to {
    transform: rotate(-360deg);
  }
}
@keyframes robj-flow {
  to {
    stroke-dashoffset: -14.2;
  }
}

/* ---------- keyframes: area pages ---------- */
@keyframes robj-valve {
  0%,
  8% {
    transform: rotate(0deg);
  }
  18%,
  58% {
    transform: rotate(90deg);
  }
  68%,
  100% {
    transform: rotate(0deg);
  }
}
@keyframes robj-route-a {
  0%,
  8% {
    opacity: 1;
  }
  13%,
  63% {
    opacity: 0;
  }
  68%,
  100% {
    opacity: 1;
  }
}
@keyframes robj-route-b {
  0%,
  13% {
    opacity: 0;
  }
  18%,
  58% {
    opacity: 1;
  }
  63%,
  100% {
    opacity: 0;
  }
}
@keyframes robj-lamp-0 {
  0%,
  10% {
    fill: var(--anatomy-shade-0);
  }
  11%,
  90% {
    fill: var(--robj-glow);
  }
  91%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-lamp-1 {
  0%,
  24% {
    fill: var(--anatomy-shade-0);
  }
  25%,
  90% {
    fill: var(--robj-glow);
  }
  91%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-lamp-2 {
  0%,
  38% {
    fill: var(--anatomy-shade-0);
  }
  39%,
  90% {
    fill: var(--robj-glow);
  }
  91%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-lamp-3 {
  0%,
  52% {
    fill: var(--anatomy-shade-0);
  }
  53%,
  90% {
    fill: var(--robj-glow);
  }
  91%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-lamp-accept {
  0%,
  66% {
    fill: var(--anatomy-shade-0);
    stroke: var(--anatomy-mid);
  }
  68%,
  90% {
    fill: var(--robj-glow);
    stroke: var(--robj-glow-edge);
  }
  91%,
  100% {
    fill: var(--anatomy-shade-0);
    stroke: var(--anatomy-mid);
  }
}
@keyframes robj-needle {
  0% {
    transform: rotate(-110deg);
  }
  45% {
    transform: rotate(52deg);
  }
  55% {
    transform: rotate(40deg);
  }
  70%,
  86% {
    transform: rotate(46deg);
  }
  100% {
    transform: rotate(-110deg);
  }
}
/* the combination: right past 200, back to 80, right again to 160; the handle turns an eighth (X to +) to unlock */
@keyframes robj-dial {
  0% {
    transform: rotate(0deg);
  }
  12% {
    transform: rotate(200deg);
  }
  21% {
    transform: rotate(80deg);
  }
  30%,
  60% {
    transform: rotate(160deg);
  }
  72%,
  100% {
    transform: rotate(0deg);
  }
}
@keyframes robj-wheel {
  0%,
  31% {
    transform: rotate(0deg);
  }
  40%,
  60% {
    transform: rotate(45deg);
  }
  69%,
  100% {
    transform: rotate(0deg);
  }
}
/* the coin on the stack is taken away, then a new one slides out of the slot (it starts inside, clipped) */
@keyframes robj-coin {
  0%,
  28% {
    opacity: 1;
    transform: translate(0px, 0px);
  }
  33% {
    opacity: 0;
    transform: translate(0px, 0px);
  }
  33.5% {
    opacity: 0;
    transform: translate(var(--in-x), var(--in-y));
  }
  36%,
  41% {
    opacity: 1;
    transform: translate(var(--in-x), var(--in-y));
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  54%,
  100% {
    opacity: 1;
    transform: translate(0px, 0px);
  }
}
@keyframes robj-stamp {
  0%,
  14% {
    transform: translate(0px, 0px);
    animation-timing-function: cubic-bezier(0.55, 0, 0.9, 0.4);
  }
  36%,
  46% {
    transform: translate(var(--drop-x), var(--drop-y));
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  72%,
  100% {
    transform: translate(0px, 0px);
  }
}
/* the old seal lifts away as the stamp starts down; the new one is there when the stamp touches */
@keyframes robj-seal {
  0%,
  14% {
    opacity: 1;
  }
  24%,
  35.9% {
    opacity: 0;
  }
  36%,
  100% {
    opacity: 1;
  }
}
@keyframes robj-flash {
  0%,
  100% {
    opacity: 0;
  }
  4%,
  30% {
    opacity: 1;
  }
  40% {
    opacity: 0;
  }
}
@keyframes robj-ring {
  0% {
    opacity: 0.95;
    transform: scale(1);
  }
  100% {
    opacity: 0;
    transform: scale(3.6);
  }
}

/* ---------- keyframes: the main page, one shared cycle ---------- */
@keyframes robj-m-dial {
  0% {
    transform: rotate(0deg);
  }
  5% {
    transform: rotate(200deg);
  }
  9% {
    transform: rotate(80deg);
  }
  13%,
  27% {
    transform: rotate(160deg);
  }
  33%,
  100% {
    transform: rotate(0deg);
  }
}
@keyframes robj-m-wheel {
  0%,
  13% {
    transform: rotate(0deg);
  }
  17%,
  27% {
    transform: rotate(45deg);
  }
  31%,
  100% {
    transform: rotate(0deg);
  }
}
@keyframes robj-m-coin {
  0%,
  9% {
    opacity: 1;
    transform: translate(0px, 0px);
  }
  12% {
    opacity: 0;
    transform: translate(0px, 0px);
  }
  12.5% {
    opacity: 0;
    transform: translate(var(--in-x), var(--in-y));
  }
  14%,
  17.5% {
    opacity: 1;
    transform: translate(var(--in-x), var(--in-y));
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  24%,
  100% {
    opacity: 1;
    transform: translate(0px, 0px);
  }
}
@keyframes robj-m-valve {
  0%,
  34% {
    transform: rotate(0deg);
  }
  39%,
  90% {
    transform: rotate(90deg);
  }
  95%,
  100% {
    transform: rotate(0deg);
  }
}
@keyframes robj-m-route-a {
  0%,
  35% {
    opacity: 0.85;
  }
  38%,
  91% {
    opacity: 0;
  }
  94%,
  100% {
    opacity: 0.85;
  }
}
@keyframes robj-m-route-b {
  0%,
  35% {
    opacity: 0;
  }
  38%,
  91% {
    opacity: 0.85;
  }
  94%,
  100% {
    opacity: 0;
  }
}
@keyframes robj-m-lamp-0 {
  0%,
  40.9% {
    fill: var(--anatomy-shade-0);
  }
  41%,
  80% {
    fill: var(--robj-glow);
  }
  80.1%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-m-lamp-1 {
  0%,
  44.9% {
    fill: var(--anatomy-shade-0);
  }
  45%,
  80% {
    fill: var(--robj-glow);
  }
  80.1%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-m-lamp-2 {
  0%,
  48.9% {
    fill: var(--anatomy-shade-0);
  }
  49%,
  80% {
    fill: var(--robj-glow);
  }
  80.1%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-m-lamp-3 {
  0%,
  52.9% {
    fill: var(--anatomy-shade-0);
  }
  53%,
  80% {
    fill: var(--robj-glow);
  }
  80.1%,
  100% {
    fill: var(--anatomy-shade-0);
  }
}
@keyframes robj-m-lamp-accept {
  0%,
  56.9% {
    fill: var(--anatomy-shade-0);
    stroke: var(--anatomy-mid);
  }
  57%,
  80% {
    fill: var(--robj-glow);
    stroke: var(--robj-glow-edge);
  }
  80.1%,
  100% {
    fill: var(--anatomy-shade-0);
    stroke: var(--anatomy-mid);
  }
}
@keyframes robj-m-stamp {
  0%,
  60% {
    transform: translate(0px, 0px);
    animation-timing-function: cubic-bezier(0.55, 0, 0.9, 0.4);
  }
  63.5%,
  64.5% {
    transform: translate(var(--drop-x), var(--drop-y));
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
  }
  68.5%,
  100% {
    transform: translate(0px, 0px);
  }
}
@keyframes robj-m-seal {
  0%,
  59% {
    opacity: 1;
  }
  61.5%,
  63.4% {
    opacity: 0;
  }
  63.5%,
  100% {
    opacity: 1;
  }
}
@keyframes robj-m-needle {
  0%,
  69% {
    transform: rotate(-40deg);
  }
  75% {
    transform: rotate(52deg);
  }
  77.5% {
    transform: rotate(40deg);
  }
  80%,
  92% {
    transform: rotate(46deg);
  }
  99%,
  100% {
    transform: rotate(-40deg);
  }
}
@keyframes robj-m-flash {
  0%,
  81.9% {
    opacity: 0;
  }
  82.5%,
  85% {
    opacity: 1;
  }
  88%,
  100% {
    opacity: 0;
  }
}
@keyframes robj-m-ring {
  0%,
  81.9% {
    opacity: 0;
    transform: scale(1);
  }
  82% {
    opacity: 0.95;
    transform: scale(1);
  }
  95%,
  100% {
    opacity: 0;
    transform: scale(3.6);
  }
}

/* ---------- reduced motion: a still picture that still says what each assembly does ---------- */
@media (prefers-reduced-motion: reduce) {
  .robj * {
    animation: none !important;
  }
  /* main: the machine stands with its signals on */
  .robj .robj-flow {
    opacity: 0.6;
  }
  .robj .robj-lamp {
    fill: var(--robj-glow);
  }
  .robj .robj-beacon-glow {
    opacity: 0.85;
  }
  /* an area page: only the live assembly keeps its signal */
  :is(.robj:is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]), :is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]) .robj) .robj-lamp {
    fill: var(--anatomy-shade-0);
  }
  :is(.robj:is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]), :is([data-live="core"], [data-live="protocol"], [data-live="proofs"], [data-live="economy"], [data-live="rwa"], [data-live="eip"], [data-live="updates"]) .robj) .robj-beacon-glow {
    opacity: 0;
  }
  :is(.robj[data-live="protocol"], [data-live="protocol"] .robj) .robj-flow {
    opacity: 1;
  }
  :is(.robj[data-live="proofs"], [data-live="proofs"] .robj) .robj-lamp {
    fill: var(--robj-glow);
  }
  :is(.robj[data-live="updates"], [data-live="updates"] .robj) .robj-beacon-glow {
    opacity: 1;
  }
  :is(.robj[data-live="updates"], [data-live="updates"] .robj) .robj-ring {
    opacity: 0.55;
    transform: scale(calc(1.5 + var(--n) * 0.8));
  }
}
