/* 30 · shape engine: chips, the radar stage, the caption and the plate.
   One light source per element: every radial inside shares the hexagon's center (--cx, --cy).
   The radar leans with the page camera at panel depth. */

@property --glow{syntax:"<percentage>";inherits:true;initial-value:16%}
.rw-engine{--gem-0:var(--hero-0);--gem-1:var(--hero-1);--gem-2:var(--hero-2);--gem-3:var(--hero-3);--gem-4:var(--hero-4);--pc:var(--rose);
  --cx:50%;--cy:38%;--glow:16%;
  position:relative;margin:0;overflow:hidden;min-width:0;display:flex;flex-direction:column;gap:12px;padding:18px;border-radius:18px;
  border:1px solid color-mix(in srgb,var(--pc) 45%,var(--rw-engine-edge));
  background:radial-gradient(560px circle at var(--cx) var(--cy),color-mix(in srgb,var(--pc) calc(var(--glow) + var(--rw-pulse) * 10%),transparent),transparent 75%),var(--rw-engine-fill,var(--rw-engine-bg));
  transition:border-color .3s,--glow var(--t2) var(--e)}
.rw-engine:hover{border-color:var(--pc);--glow:24%}

/* the row: always six choices on one line, the reroll pinned right; chips tighten first, the row scrolls before a choice is lost */
.rw-engine__row{display:flex;align-items:center;gap:6px;min-width:0}
.rw-chips{display:flex;gap:6px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none}
.rw-chips::-webkit-scrollbar{display:none}
.rw-chips.is-over{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent)}
/* chips are the Button type (06-button.css, --chip and --reroll); here only where the reroll sits and the letters'
   state. The edges never change; state lives in the letters */
.rw-chip--reroll{margin-left:auto}
.rw-chip__label{display:inline-block;transition:transform var(--t1) var(--e)}
.rw-chip:active .rw-chip__label{transform:scale(.94)}
.rw-chip[aria-pressed="true"]{color:var(--k3)}
.rw-chip[aria-pressed="true"] .rw-chip__label{background:linear-gradient(90deg,var(--k0),var(--k1),var(--k2),var(--k3),var(--k4),var(--k2),var(--k0));background-size:300% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;animation:rw-wheel calc(var(--rw-beat) * 2) linear infinite}
.rw-chip[data-gem="hero"]{--k0:var(--hero-0);--k1:var(--hero-1);--k2:var(--hero-2);--k3:var(--hero-3);--k4:var(--hero-4)}
.rw-chip[data-gem="teal"]{--k0:var(--g-teal-0);--k1:var(--g-teal-1);--k2:var(--g-teal-2);--k3:var(--g-teal-3);--k4:var(--g-teal-4)}
.rw-chip[data-gem="sage"]{--k0:var(--g-sage-0);--k1:var(--g-sage-1);--k2:var(--g-sage-2);--k3:var(--g-sage-3);--k4:var(--g-sage-4)}
.rw-chip[data-gem="amethyst"]{--k0:var(--g-amethyst-0);--k1:var(--g-amethyst-1);--k2:var(--g-amethyst-2);--k3:var(--g-amethyst-3);--k4:var(--g-amethyst-4)}
.rw-chip[data-gem="gold"]{--k0:var(--g-gold-0);--k1:var(--g-gold-1);--k2:var(--g-gold-2);--k3:var(--g-gold-3);--k4:var(--g-gold-4)}
.rw-chip[data-gem="peri"]{--k0:var(--g-peri-0);--k1:var(--g-peri-1);--k2:var(--g-peri-2);--k3:var(--g-peri-3);--k4:var(--g-peri-4)}
@keyframes rw-wheel{to{background-position:-150% 0}}

/* the radar: its frame leans with the page camera (a plain box, so a lean moves a layer and never re-lays the
   drawing), and the drawing breathes on the beat */
.rw-engine__tilt{align-self:center;width:100%;max-width:420px;cursor:crosshair;
  transform:perspective(900px) rotateX(calc(var(--rw-py) * -7deg)) rotateY(calc(var(--rw-px) * 9deg))}
.rw-radar{width:100%;height:auto;display:block;transform-origin:50% 50%;
  animation:rw-breathe var(--rw-beat) ease-in-out infinite}
@keyframes rw-breathe{0%,100%{scale:1}50%{scale:1.018}}
.rw-radar__ring{fill:none;stroke:var(--rw-grid);stroke-width:1}
.rw-radar__spoke{stroke:var(--rw-grid);stroke-width:1}
.rw-radar__axis{font-family:var(--f-body);font-size:13px;font-weight:600;fill:var(--rw-axis-ink);transition:fill .2s}
.rw-radar__axis.is-on{fill:var(--gem-3)}
.rw-gem-stop--0{stop-color:var(--gem-0)}
.rw-gem-stop--1{stop-color:var(--gem-1)}
.rw-gem-stop--2{stop-color:var(--gem-2)}
.rw-gem-stop--3{stop-color:var(--gem-3)}
.rw-gem-stop--4{stop-color:var(--gem-4)}
/* depth: pale thick mist at the heart, the gem's body between, its deep end dark at the near rim */
.rw-depth-stop--0{stop-color:var(--gem-1);stop-opacity:.34}
.rw-depth-stop--1{stop-color:var(--gem-3);stop-opacity:.22}
.rw-depth-stop--2{stop-color:color-mix(in oklab,var(--gem-4) 55%,var(--rw-engine-bg));stop-opacity:.7}
.rw-radar__ghost{fill:none;stroke:var(--rw-ghost-line);stroke-width:1.2;stroke-dasharray:3 4;opacity:0;transition:opacity var(--t2) var(--e)}
.rw-engine.is-show .rw-radar__ghost.is-on{opacity:.85}
.rw-radar__body{fill:url(#rw-depth-gradient)}
/* the lens (radar.js, Round 9: convex, not flat fogged glass): a rim shade where the surface turns away and one
   specular light up and left, its edge firm (stops close together) so it reads as a glint on a bulge, not a haze */
.rw-radar__lens{pointer-events:none}
.rw-rim-stop--0{stop-color:#000;stop-opacity:0}.rw-rim-stop--1{stop-color:#000;stop-opacity:0}.rw-rim-stop--2{stop-color:color-mix(in oklab,var(--gem-4) 40%,#000);stop-opacity:.55}
.rw-spec-stop--0{stop-color:#fff;stop-opacity:.55}.rw-spec-stop--1{stop-color:color-mix(in oklab,#fff 70%,var(--gem-1));stop-opacity:.32}.rw-spec-stop--2{stop-color:var(--gem-1);stop-opacity:.06}.rw-spec-stop--3{stop-color:var(--gem-1);stop-opacity:0}
:root[data-rw-theme="light"] .rw-rim-stop--2{stop-opacity:.3}
/* the fluid (field.js, Round 8): dozens of small crisp points in the gem's own stops, no glow, no blur; the hand
   drags them and streams them from its point. field.js sets each point's opacity as it lives and fades */
.rw-fluid{stroke:none;shape-rendering:geometricPrecision}
.rw-fluid--0{fill:var(--gem-0)}.rw-fluid--1{fill:var(--gem-1)}.rw-fluid--2{fill:var(--gem-2)}.rw-fluid--3{fill:var(--gem-3)}.rw-fluid--4{fill:var(--gem-4)}
.rw-radar__lights{opacity:.85}
.rw-lamp-stop--0{stop-color:var(--gem-0)}.rw-lamp-stop--1{stop-color:var(--gem-1)}.rw-lamp-stop--2{stop-color:var(--gem-2)}
.rw-lamp-stop--3{stop-color:var(--gem-3)}.rw-lamp-stop--4{stop-color:var(--gem-4)}
.rw-lamp-stop--a{stop-opacity:.3}.rw-lamp-stop--b{stop-opacity:.14}.rw-lamp-stop--c{stop-opacity:0}
/* the mist banks: wisps (textures painted in radar.js) in the color named here, drifting slowly, never still, never quick */
.rw-engine{--rw-radar-mist-ink:color-mix(in oklab,var(--gem-1) 72%,var(--rw-engine-bg))}
.rw-mist--far{opacity:.62;animation:rw-mist-far calc(var(--rw-beat) * 12) ease-in-out infinite alternate}
.rw-mist--near{opacity:.5;animation:rw-mist-near calc(var(--rw-beat) * 7) ease-in-out infinite alternate}
@keyframes rw-mist-far{from{translate:-34px 12px}to{translate:34px -14px}}
@keyframes rw-mist-near{from{translate:40px 18px}to{translate:-40px -16px}}
.rw-wave{stroke:var(--gem-1)}
.rw-radar__outline{fill:none;stroke:url(#rw-gem-gradient);stroke-width:2.5;stroke-linejoin:round;transition:stroke-width .35s var(--e)}
.rw-radar__outline.is-hit{stroke-width:4}
.rw-radar__pulse{fill:none;stroke:url(#rw-gem-gradient);stroke-width:2}
/* the icon: one crisp line in the gem's palest stop over a soft deep halo of itself, so it reads the same on every
   gem; it sits in the mist (radar.js seats and sizes it), drifts within the room it has, and lights up when the
   character shows. Line widths stay the same whatever its size (--k is its scale) */
.rw-radar__float{transform-box:fill-box;transform-origin:center;animation:rw-float calc(var(--rw-beat) * 3) ease-in-out infinite}
@keyframes rw-float{
  0%,100%{translate:0 0;rotate:0deg}
  25%{translate:calc(var(--amp,0) * 1px) calc(var(--amp,0) * -.7px);rotate:3deg}
  50%{translate:calc(var(--amp,0) * -.5px) calc(var(--amp,0) * .9px);rotate:-2deg}
  75%{translate:calc(var(--amp,0) * -1px) calc(var(--amp,0) * -.3px);rotate:2deg}}
/* the crest under the icon: the parent hexagon in small, in the hero's gem, a faint fill and a clear edge, so the icon
   reads as its heraldry (it fades with the icon when caught) */
/* Round 10, the user: "turn off the circle, but use its radius to pack the aura into a cloud": the crest is not
   drawn; radar.js keeps its reach as the bound every corpuscle stays inside */
.rw-radar__crest{display:none}
.rw-radar__crest{fill:color-mix(in oklab,var(--gem-2) 18%,transparent);stroke:color-mix(in oklab,var(--gem-3) 65%,transparent);stroke-width:1.3;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;pointer-events:none;transition:opacity var(--t2) var(--e)}
.rw-radar__place.is-done .rw-radar__crest{opacity:0;transition:opacity .25s ease-out}
:root[data-rw-theme="light"] .rw-radar__crest{fill:color-mix(in oklab,var(--gem-2) 12%,transparent);stroke:color-mix(in oklab,var(--gem-4) 55%,var(--ink))}
.rw-radar__icon{fill:none;stroke-linecap:round;stroke-linejoin:round;pointer-events:none;opacity:1;transition:opacity var(--t2) var(--e),filter var(--t2) var(--e)}
/* the halo is a wide, faint line (no blur: the icon floats every frame, and a blur would be redrawn every frame) */
.rw-radar__halo{stroke:color-mix(in oklab,var(--gem-4) 60%,var(--rw-engine-bg));stroke-width:calc(5px / var(--k,1.5))}
/* the line runs through the gem's own gradient (radar.js rw-icon-gradient): the icon wears the shape's color */
.rw-radar__glyph{stroke:url(#rw-icon-gradient)}
/* reached for, it disperses (the user, 2026-10-13: "the shape grows and its edge thins, so the shape still holds
   within, and then it turns into a cloud"). The hand's nearness (--near, the page's approach tracker) runs two
   stages. First (--s1, the near half of the reach) the icon's outline grows by a third and its line thins to less
   than half: the form still reads. Then (--s2, the last half) the line fades to a ghost under smoke: puffs seeded on
   that grown line (radar.js) that keep its shape, each breaking off and re-knitting on its own clock, swayed a
   little away from the hand. When the hand leaves, the smoke settles back into the line and it closes. No blur: dots and the air between them. The cloud takes --near from the dodge (radar.js
   follow), so its spread never widens the box the tracker measures */
.rw-radar__icon,.rw-radar__cloud-wrap{--s1:clamp(0,var(--near,0) * 2,1);--s2:clamp(0,var(--near,0) * 2 - 1,1)}
/* Round 10 (the user: the cloud separates "from the beginning, not at the end"): the smoke is out at rest, about half
   spread, and the hand only takes it further; the glyph keeps its line (--s1 untouched) */
/* and it separates from the first step of the approach, not the last half (the lead, from the user's first
   screenshot): from half spread at rest, the smoke rises with the hand's nearness from its start */
.rw-radar__cloud-wrap{--s2:clamp(.5,.5 + var(--near,0),1)}
.rw-radar__cloud .rw-radar__mote{animation-play-state:running}
.rw-radar__dodge,.rw-radar__cloud-wrap{translate:calc(var(--nx,0) * 14px * (1 - var(--tire,0) * .7)) calc(var(--ny,0) * 14px * (1 - var(--tire,0) * .7));transition:translate .35s cubic-bezier(.2,.8,.3,1)}
/* the chase's last dodges: tired out, it lunges once, big and quick; caught, the icon and its cloud give way to the mist */
.rw-radar__dodge.is-hit{translate:calc(var(--nx,0) * 34px) calc(var(--ny,0) * 34px);transition:translate .16s cubic-bezier(.2,1.4,.4,1)}
.rw-radar__place.is-done .rw-radar__icon,.rw-radar__place.is-done .rw-radar__cloud-wrap{opacity:0;transition:opacity .25s ease-out}
.rw-radar__place .rw-radar__icon{transition:opacity 1.2s ease-in}
/* the ripples: thin rings in the shape's own gradient, the outline offset outward evenly (radar.js ripple) */
.rw-radar__ripple{fill:none;stroke:var(--gem-3);stroke-width:1;stroke-linejoin:miter;vector-effect:non-scaling-stroke;shape-rendering:geometricPrecision}
.rw-radar__halo,.rw-radar__glyph{transform-box:fill-box;transform-origin:center;scale:calc(1 + var(--s1) * .35);
  transition:scale .35s cubic-bezier(.2,.8,.3,1),stroke-width .35s ease-out,opacity .4s ease-out}
.rw-radar__halo{opacity:calc(.3 * (1 - var(--s1)))}
/* the line never quite goes: a faint ghost of it stays under the smoke, so the form always reads */
.rw-radar__glyph{stroke-width:calc(2px / var(--k,1.5) * (1 - var(--s1) * .6));opacity:calc(1 - var(--s2) * .8)}
/* the cloud floats with the icon, turning round the icon's middle (its own origin, radar.js) */
.rw-radar__float--cloud{transform-box:view-box;transform-origin:0 0}
.rw-radar__cloud-wrap{pointer-events:none}
/* the smoke: puffs on the line itself, swayed only a little away from the hand, so the silhouette holds. Each one,
   on its own cycle (--c beats, started at --d of it), sits, then breaks off outward (--bx, --by), swells and thins
   to nothing, and re-knits from a speck in its place. fill-opacity carries the break, opacity the hand's nearness,
   so the two never fight. Crisp: no blur, the softness is the gaps and the fades */
.rw-radar__mote{fill:url(#rw-icon-gradient);r:calc(var(--r,1) * 1px / var(--k,1.5));opacity:calc(var(--s2) * var(--o,1) * (.55 + .45 * var(--lead-dots,.5)));
  translate:calc(var(--nx,0) * var(--w,2) * var(--s2) * 1px) calc(var(--ny,0) * var(--w,2) * var(--s2) * 1px);
  transform-box:fill-box;transform-origin:center;
  transition:translate .7s cubic-bezier(.2,.8,.3,1),opacity .45s ease-out;
  animation:rw-radar-mote-smoke calc(var(--rw-beat) * var(--c,3)) linear calc(var(--rw-beat) * var(--c,3) * var(--d,0) * -1) infinite;animation-play-state:paused}
/* the veil, the cloud's body (the user: "elusive and translucent... it has to be both"): the icon's line on the grown
   form as a wide faint band behind the puffs. It swells in over the first half of the reach and thins as the puffs
   tear off (peak near the middle, a third of it left at the catch), and breathes slowly while the cloud is out.
   Translucent by opacity alone, no blur; the puffs above it are translucent too (--o .3 to .65), so they read as
   smoke over a body, not dots */
/* Round 10, one body in three states shown together (the user: "the shape breaks down into a bunch of corpuscles
   that bind together, turning into a cloud and then into a shadow; show all of them together in superposition, and
   I need animation"). One phase, --rw-ph, turns 0 to 1 every three beats on the whole cloud; each state takes the
   lead in turn a third of a turn apart (corpuscles, then cloud, then shadow) and none ever goes below about half,
   so all three are always there. The smudge is even: each band is one flat colour, its opacity on the group, so
   overlaps never darken. Everything sits inside the crest's reach (radar.js) */
@property --rw-ph{syntax:"<number>";inherits:true;initial-value:0}
.rw-radar__cloud{--rw-ph:0;animation:rw-radar-phase calc(var(--rw-beat) * 3) linear infinite;
  --lead-dots:calc(.5 + .5 * sin(var(--rw-ph) * 360deg));
  --lead-cloud:calc(.5 + .5 * sin((var(--rw-ph) - .333) * 360deg));
  --lead-shadow:calc(.5 + .5 * sin((var(--rw-ph) - .667) * 360deg))}
@keyframes rw-radar-phase{to{--rw-ph:1}}
.rw-radar__veil{opacity:calc(var(--s2) * (.3 + .3 * var(--lead-cloud,.5)));transition:opacity .45s ease-out;
  transform-box:fill-box;transform-origin:center;scale:calc(.97 + .06 * var(--lead-cloud,.5))}
.rw-radar__veil-part{fill:none;stroke:var(--gem-2);stroke-width:calc(5px / var(--k,1.5));stroke-linecap:round;stroke-linejoin:round}
/* the shadow: the same line, wider and in the gem's deep end, settled a hair lower: the form's own shade */
.rw-radar__shadow{opacity:calc(var(--s2) * (.16 + .2 * var(--lead-shadow,.5)));transform-box:fill-box;transform-origin:center;
  translate:0 calc(.6px + .6px * var(--lead-shadow,.5));scale:calc(1 + .05 * var(--lead-shadow,.5))}
.rw-radar__shadow-part{fill:none;stroke:color-mix(in oklab,var(--gem-3) 70%,var(--bg));stroke-width:calc(9px / var(--k,1.5));stroke-linecap:round;stroke-linejoin:round}
:root[data-rw-theme="light"] .rw-radar__veil-part{stroke:color-mix(in oklab,var(--gem-2) 70%,var(--ink))}
:root[data-rw-theme="light"] .rw-radar__shadow-part{stroke:color-mix(in oklab,var(--gem-4) 45%,var(--ink))}
@media (prefers-reduced-motion:reduce){.rw-radar__cloud{animation:none;--rw-ph:.15}}
/* the smoke lives only while the cloud is out; at rest every puff holds still on its spot */
.rw-radar__cloud.is-on .rw-radar__mote{animation-play-state:running}
@keyframes rw-radar-mote-smoke{
  0%,56%{transform:translate(0,0) scale(1);fill-opacity:1}
  66%{transform:translate(calc(var(--bx,0) * .45px),calc(var(--by,0) * .45px)) scale(1.25);fill-opacity:.7}
  80%{transform:translate(calc(var(--bx,0) * 1px),calc(var(--by,0) * 1px)) scale(1.6);fill-opacity:0}
  81%{transform:translate(0,0) scale(.2);fill-opacity:0}
  100%{transform:translate(0,0) scale(1);fill-opacity:1}}
.rw-engine.is-show .rw-radar__icon{opacity:1;filter:drop-shadow(0 0 4px color-mix(in oklab,var(--gem-2) 60%,transparent))}
.rw-radar__value{font-family:var(--f-data);font-size:13px;font-weight:600;paint-order:stroke;stroke:var(--rw-value-halo);stroke-width:3px;stroke-linejoin:round}
.rw-radar__mark{font-size:9.5px;font-weight:700}

/* the clean shape (the user, 2026-10-13, on the light theme: "a blot, not parallax; it looks like Windows 98; the
   closer the mouse, the worse"). The outline is thin and the numbers are always ink.
   Revised the same day ("the shape overrides the background; it should override the hex tree only and interact as
   a mist"; "you removed the passing cloud ... the critical glue between components"). By day:
   - the shape covers only the grid: a mask cuts the rings and spokes out under it (radar.js rw-grid-mask), and its
     body is a thin wash of the gem, so whatever lies behind shows through it;
   - the panel lets the page's ground through, so the page's two mist bands (02-base.css) drift on behind the shape;
   - inside the shape the same mist passes on: the lamps and the wisp banks take the page mist's colors and its
     drift, left to right (the strips here, the lights' wind in field.js). Crisp: soft only by their own gradients
     and low opacity, no blur on anything that moves */
.rw-radar__outline{stroke-width:1.75}
.rw-radar__outline.is-hit{stroke-width:2.75}
.rw-radar__value{fill:light-dark(color-mix(in oklab,var(--gem-4) 45%,var(--ink)),var(--ink));fill-opacity:1;font-weight:700}
/* the mask's room and hole: a luminance mask reads white as kept and black as cut, so these two are not colors */
.rw-radar__grid-room{fill:white}
.rw-radar__grid-hole{fill:black}
:root[data-rw-theme="light"] .rw-engine{--rw-engine-fill:color-mix(in srgb,var(--rw-engine-bg) 45%,transparent);--rw-radar-mist-ink:var(--rose-deep)}
:root[data-rw-theme="light"] .rw-radar__grid{mask:url(#rw-grid-mask)}
:root[data-rw-theme="light"] .rw-radar__body{fill:color-mix(in oklab,var(--gem-2) 16%,transparent)}
:root[data-rw-theme="light"] .rw-radar__ring,:root[data-rw-theme="light"] .rw-radar__spoke{stroke:color-mix(in oklab,var(--ink) 18%,var(--panel))}
:root[data-rw-theme="light"] .rw-radar__glyph{stroke:color-mix(in oklab,var(--gem-4) 60%,var(--ink))}
:root[data-rw-theme="light"] .rw-radar__mote{fill:color-mix(in oklab,var(--gem-4) 60%,var(--ink))}
:root[data-rw-theme="light"] .rw-radar__halo{display:none}
/* the passing flow by day: the lights ride the wind (field.js reads --rw-flow) in the page mist's two reds, as faint
   as the page's own bands */
:root[data-rw-theme="light"] .rw-radar__lights{--rw-flow:1}
:root[data-rw-theme="light"] .rw-lamp-stop{stop-color:var(--rose-deep)}
:root[data-rw-theme="light"] .rw-lamp-stop--1,:root[data-rw-theme="light"] .rw-lamp-stop--3{stop-color:color-mix(in oklab,var(--rose) 50%,var(--rose-deep))}
:root[data-rw-theme="light"] .rw-lamp-stop--a{stop-opacity:.14}
:root[data-rw-theme="light"] .rw-lamp-stop--b{stop-opacity:.06}
/* the wisp banks by day: the strip slides one tile (460 units) left to right at about the page mist's pace, far
   slower than near, and the tiles' own sway rests */
:root[data-rw-theme="light"] .rw-mist{animation:none}
/* by day the shape holds no smears: no mist banks inside it, and the icon's veil shows only while its cloud is out
   (the user on v79: the swirls in the middle looked like the remains of earlier clouds) */
:root[data-rw-theme="light"] .rw-mist--far,:root[data-rw-theme="light"] .rw-mist--near{display:none}
/* no soft lamps by day ("still a smudge", v80): the fluid's points are crisp ink of the gem's deep end instead, so the
   shape stays one clean wash and the points read on it */
:root[data-rw-theme="light"] .rw-fluid{fill:color-mix(in oklab,var(--gem-4) 65%,var(--ink))}
:root[data-rw-theme="light"] .rw-fluid--1,:root[data-rw-theme="light"] .rw-fluid--3{fill:color-mix(in oklab,var(--gem-3) 70%,var(--ink))}
:root[data-rw-theme="light"] .rw-radar__lights{opacity:.7}
:root[data-rw-theme="light"] .rw-radar__body{fill:color-mix(in oklab,var(--gem-2) 22%,var(--panel));fill-opacity:.82}
/* Round 10: the veil stays out at rest with the smoke */
:root[data-rw-theme="light"] .rw-radar__strip--far{animation:rw-radar-strip-flow calc(var(--rw-beat) * 11) linear infinite}
:root[data-rw-theme="light"] .rw-radar__strip--near{animation:rw-radar-strip-flow calc(var(--rw-beat) * 10) linear infinite}
@keyframes rw-radar-strip-flow{from{translate:0 0}to{translate:460px 0}}
.rw-engine__hint{text-align:center;font-family:var(--f-data);font-size:11px;letter-spacing:.06em;color:var(--rw-hint-ink)}

/* caption and plate */
.rw-caption{display:flex;flex-direction:column;gap:4px;border-top:1px solid var(--rw-caption-rule);padding-top:10px}
.rw-caption__title{font-family:var(--f-display);font-size:20px;align-self:flex-start}
.rw-caption__desc{font-size:14px;color:var(--rw-caption-ink)}
.rw-caption__who{font-size:13px;color:var(--rw-who-ink);margin-top:4px}
.rw-caption__who-name{color:var(--rw-who-strong);font-weight:600}
.rw-caption__who-power{font-family:var(--f-data);font-weight:700;color:var(--rw-who-strong)}
.rw-caption__who-dev{font-family:var(--f-data);font-weight:700;color:var(--gem-3)}
/* the plate: the class figure in the card pen on the left, the sheet it sells on the right; stacks when narrow */
.rw-plate{margin-top:10px;border:1px solid color-mix(in srgb,var(--gem-3) 40%,var(--rw-plate-edge));border-radius:12px;padding:10px 14px 10px 6px;
  display:grid;grid-template-columns:minmax(120px,42%) 1fr;align-items:center;gap:10px;transition:border-color var(--t2) var(--e);
  background:radial-gradient(60% 90% at 22% 60%,color-mix(in srgb,var(--gem-2) 14%,transparent),transparent 70%)}
.rw-plate__art{width:100%;height:auto;overflow:visible;
  --c-ink:var(--ink);--c-window:var(--panel);--c-paper:var(--panel);--c-accent:var(--gem-3);--c-glow:var(--gem-2);
  --c-fill:color-mix(in oklab,var(--gem-1) 20%,var(--panel));--c-deep:color-mix(in oklab,var(--gem-3) 22%,var(--bg))}
/* the hood is dark cloth, its opening a shadow only the eyes light (the user, 2026-10-13: it had turned into "they
   killed Kenny", a pale parka with an orange face, from the gem's hot end in --c-deep; the cultist or cloaked hero
   is menacing again) */
.rw-plate__art .rw-fig__hood .rw-face{fill:color-mix(in oklab,var(--ink) 14%,var(--bg))}
.rw-plate__art .rw-fig__hood .rw-face--fold{fill:color-mix(in oklab,var(--ink) 6%,var(--bg))}
.rw-plate__art .rw-fig__hood .rw-hole{fill:color-mix(in oklab,var(--bg) 85%,#000)}
.rw-plate__art .rw-fig__hood .rw-fig__eye{fill:var(--gem-2)}
.rw-plate__art.is-on .rw-fig{animation:rw-fig-rise .6s var(--e) both}
@keyframes rw-fig-rise{from{opacity:0;translate:0 6px}to{opacity:1;translate:0 0}}
.rw-fig__shade{fill:var(--c-ink);opacity:.18}
/* the plinth glows in its gem (the user, 2026-10-13, on the Rival's violet: "this could be a game; it should glow,
   not grey"): the top stone a pale wash of the gem, the lit faces its bright stop, the shaded faces its deep end,
   and a soft aura of the gem's light behind the whole stage, strongest at the figure */
/* matte stone, not glass (the user on v71: "ease out on the reflectivity of the glass look"): a soft top wash and
   lit and shaded faces only a step apart, so the gem tints the stone instead of shining off it */
.rw-plinth__top{fill:color-mix(in oklab,var(--gem-1) 18%,var(--panel));stroke:none}
.rw-plinth__lit{fill:color-mix(in oklab,var(--gem-2) 26%,var(--panel));stroke:none}
.rw-plinth__shade{fill:color-mix(in oklab,var(--gem-3) 30%,color-mix(in oklab,var(--panel) 80%,var(--bg)));stroke:none}
.rw-plinth__glow-stop--0{stop-color:var(--gem-2);stop-opacity:.5}
.rw-plinth__glow-stop--1{stop-color:var(--gem-3);stop-opacity:.18}
.rw-plinth__glow-stop--2{stop-color:var(--gem-3);stop-opacity:0}
.rw-plinth__aura--floor{opacity:.8}
.rw-fig__eye{fill:var(--c-accent)}
/* Round 15 (the user on the plate figures: "almost the signal"): no plinth under a class; its stat shape is its
   shadow and its aura (lib/figure.js shadowGround). The shadow: the shape, dark, pushed down and right off the feet;
   its edge: one line of the gem. The aura: the same shape glowing soft under the figure, and three rings of it that
   leave on the beat, so the cast is the character's own shape, never a loose cloud */
.rw-fig__cast{fill:color-mix(in oklab,var(--c-ink) 22%,transparent);stroke:none}
.rw-fig__cast-edge{fill:none;stroke:var(--c-accent);stroke-width:.8;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.rw-fig__cast-glow{fill:var(--c-glow,var(--c-accent));opacity:.28;stroke:none;transform-box:fill-box;transform-origin:center;scale:1.18}
.rw-fig__aura-ring{fill:none;stroke:var(--c-glow,var(--c-accent));stroke-width:1;stroke-linejoin:round;vector-effect:non-scaling-stroke;opacity:0;
  transform-box:fill-box;transform-origin:center;animation:rw-fig-aura calc(var(--rw-beat,4.5s) * .75) cubic-bezier(.2,.7,.3,1) infinite}
.rw-fig__aura-ring--1{animation-delay:calc(var(--rw-beat,4.5s) * .25)}.rw-fig__aura-ring--2{animation-delay:calc(var(--rw-beat,4.5s) * .5)}
@keyframes rw-fig-aura{0%{scale:1;opacity:.7}100%{scale:1.9;opacity:0}}
/* alive (Round 15): the beard laughs, the floating thing turns in its light, the book's top page turns at its spine */
.rw-fig__beard{transform-box:fill-box;transform-origin:50% 0;animation:rw-fig-laugh calc(var(--rw-beat,4.5s) * .9) ease-in-out infinite}
@keyframes rw-fig-laugh{0%,62%,100%{rotate:0deg;scale:1 1}68%{rotate:-4deg;scale:1 1.06}74%{rotate:3deg;scale:1 .96}80%{rotate:-3deg;scale:1 1.05}86%{rotate:2deg;scale:1 .98}}
.rw-fig__float .rw-fig__prop{transform-box:fill-box;transform-origin:center;animation:rw-fig-turn calc(var(--rw-beat,4.5s) * 2) linear infinite}
@keyframes rw-fig-turn{to{rotate:360deg}}
.rw-fig__page{transform-box:fill-box;transform-origin:0% 50%;animation:rw-fig-page calc(var(--rw-beat,4.5s) * .8) ease-in-out infinite}
@keyframes rw-fig-page{0%,30%{scale:1 1}60%,100%{scale:-1 1}}
@media (prefers-reduced-motion:reduce){.rw-fig__aura-ring,.rw-fig__beard,.rw-fig__float .rw-fig__prop,.rw-fig__page{animation:none}.rw-fig__aura-ring{opacity:0}}
.rw-plate__copy{display:flex;flex-direction:column;gap:4px;align-items:flex-start;min-width:0}
.rw-plate__name{font-family:var(--f-display);font-size:24px;line-height:1.1}
.rw-plate__line{font-size:14px;line-height:1.35;color:var(--rw-caption-ink)}
.rw-plate__note{font-family:var(--f-data);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--rw-plate-note)}
/* Round 15 ("stop overselling and stop shrinking"): the price is a quiet thin-edged pill, the figure keeps the room */
.rw-plate__cta{margin-top:6px;--btn-pad-y:5px;--btn-pad-x:11px;--btn-size:12.5px;--btn-ground-a:transparent;--btn-ground-b:transparent;--btn-bloom:transparent;
  --btn-edge:color-mix(in srgb,var(--gem-3) 55%,transparent);--btn-ink:var(--gem-2);--btn-shadow:none;--btn-shadow-hover:none}
.rw-plate{grid-template-columns:minmax(150px,52%) 1fr}
/* Round 15 ("why is it so small?", Mira the Cursed filled a third of the panel): the character grows from its feet to
   fill the plate's figure column; the svg already lets it spill (overflow visible), the plate keeps its padding */
.rw-plate__art .rw-fig{transform-box:fill-box;transform-origin:50% 100%;scale:1.5}
/* Round 16 ("refine the actors and their aura further"): the actor breathes (a slow rise from its feet on the beat,
   after it has risen in), its shape's glow breathes with it and reaches wider, and the shadow sits a touch darker so
   the figure stands on the page instead of floating; one body in motion: the breath is the only idle move */
.rw-plate__art.is-on .rw-fig{animation:rw-fig-rise .6s var(--e) both,rw-fig-breathe var(--rw-beat,4.5s) ease-in-out .6s infinite}
@keyframes rw-fig-breathe{0%,100%{scale:1.5}50%{scale:1.5 1.53}}
.rw-plate__art .rw-fig__cast-glow{animation:rw-fig-glow var(--rw-beat,4.5s) ease-in-out infinite;scale:1.3}
@keyframes rw-fig-glow{0%,100%{opacity:.26}50%{opacity:.44}}
.rw-plate__art .rw-fig__cast{fill:color-mix(in oklab,var(--c-ink) 30%,transparent)}
@media (prefers-reduced-motion:reduce){.rw-plate__art.is-on .rw-fig,.rw-plate__art .rw-fig__cast-glow{animation:none}}
@media (max-width:420px){.rw-plate{grid-template-columns:1fr;padding:10px 14px}.rw-plate__art{max-width:260px;justify-self:center}}

/* gem words: the whole ladder sliding through the letters, mirrored so the loop has no seam */
/* only the gem's bright stops run through words (its shaded edge and deep end would sink into the panel) */
.rw-gemtext{background:linear-gradient(90deg,var(--gem-2),var(--gem-1),var(--gem-2),var(--gem-3),var(--gem-2),var(--gem-1),var(--gem-2));background-size:200% 100%;
  -webkit-background-clip:text;background-clip:text;color:transparent;animation:rw-sheen calc(var(--rw-beat) * 2) linear infinite}
/* the slow one: wider bands, three times slower, with a soft halo so it always reads as smeared light */
.rw-gemtext--slow{background-size:400% 100%;animation:rw-smear calc(var(--rw-beat) * 6) linear infinite;
  filter:drop-shadow(0 0 10px color-mix(in srgb,var(--gem-2) 38%,transparent)) drop-shadow(0 0 24px color-mix(in srgb,var(--gem-3) 22%,transparent))}
@keyframes rw-sheen{to{background-position:-200% 0}}
@keyframes rw-smear{to{background-position:-400% 0}}

@media (prefers-reduced-motion:reduce){
  .rw-radar,.rw-gemtext,.rw-chip[aria-pressed="true"] .rw-chip__label,.rw-mist,.rw-radar__float,:root[data-rw-theme] .rw-radar__strip{animation:none}
  /* still motion: the icon keeps its form under a hand, and no cloud breaks out */
  .rw-radar__halo,.rw-radar__glyph{scale:none;transition:none}
  .rw-radar__glyph{opacity:1;stroke-width:calc(2px / var(--k,1.5))}
  .rw-radar__cloud-wrap{display:none}
  .rw-engine__tilt{transform:none}
  .rw-plate__art.is-on .rw-fig{animation:none}
}

/* Round 18 (the user, 2026-10-14, on the radar: "this element is getting good"; radar.js, data/lexicon.js) */
/* the stat names: white, leaning a little toward the active chip's colour, and they change with it */
.rw-radar__axis{fill:color-mix(in oklab,#fff 84%,var(--gem-2));transition:fill .6s ease}
.rw-radar__axis.is-on{fill:color-mix(in oklab,#fff 55%,var(--gem-2))}
:root[data-rw-theme="light"] .rw-radar__axis{fill:color-mix(in oklab,var(--rw-axis-ink) 84%,var(--gem-4))}
.rw-radar__names{pointer-events:none}
/* the hexagram under the shape, and the grid again through its glass */
.rw-radar__star{fill:none;stroke:var(--rw-grid);stroke-width:1}
.rw-radar__through{pointer-events:none;opacity:.5}
.rw-radar__through .rw-radar__ring,.rw-radar__through .rw-radar__spoke,.rw-radar__through .rw-radar__star{stroke:color-mix(in oklab,var(--gem-1) 40%,#fff);stroke-opacity:.35}
:root[data-rw-theme="light"] .rw-radar__through .rw-radar__ring,:root[data-rw-theme="light"] .rw-radar__through .rw-radar__spoke,
:root[data-rw-theme="light"] .rw-radar__through .rw-radar__star{stroke:color-mix(in oklab,var(--gem-4) 50%,var(--ink));stroke-opacity:.25}
/* the glass over everything: a sheen from the upper left and a thin lit rim just inside the edge */
.rw-radar__glass{pointer-events:none}
.rw-radar__glass-pane{fill:url(#rw-glass-sheen)}
.rw-glass-stop--0{stop-color:#fff;stop-opacity:.17}.rw-glass-stop--1{stop-color:#fff;stop-opacity:.04}
.rw-glass-stop--2{stop-color:#fff;stop-opacity:0}.rw-glass-stop--3{stop-color:#fff;stop-opacity:.05}
.rw-radar__glass-rim{fill:none;stroke:#fff;stroke-opacity:.22;stroke-width:.8;stroke-linejoin:round}
:root[data-rw-theme="light"] .rw-glass-stop--0{stop-opacity:.32}
:root[data-rw-theme="light"] .rw-radar__glass-rim{stroke-opacity:.6}
/* the haze and the icon's smoke are one thing: the smoke's body and shade take the mist's own ink */
.rw-radar__veil-part{stroke:color-mix(in oklab,var(--gem-2) 45%,var(--rw-radar-mist-ink))}
.rw-radar__shadow-part{stroke:color-mix(in oklab,var(--rw-radar-mist-ink) 70%,var(--gem-4))}
/* the icon at the crown's weight: one bold line and a clear glow, whatever the drawing */
.rw-radar__glyph{stroke-width:calc(2.5px / var(--k,1.5) * (1 - var(--s1,0) * .6))}
.rw-radar__icon{filter:drop-shadow(0 0 3px color-mix(in oklab,var(--gem-2) 55%,transparent))}
/* the vertex gems: a brilliant cut in the vertex's colour (--gc, radar.js), a paler table, facets, a glint, a glow
   that breathes, each a little out of step (--gd) */
.rw-radar__gem{pointer-events:none}
.rw-radar__gem-glow{fill:var(--gc);opacity:.32;transform-box:fill-box;transform-origin:center;
  animation:rw-gem-glow calc(var(--rw-beat) * 2) ease-in-out calc(var(--rw-beat) * var(--gd,0) * -1) infinite}
@keyframes rw-gem-glow{0%,100%{scale:.85;opacity:.22}50%{scale:1.15;opacity:.42}}
.rw-radar__gem-body{fill:var(--gc);stroke:color-mix(in oklab,var(--gc) 50%,#000);stroke-width:.7;stroke-linejoin:round}
.rw-radar__gem-table{fill:color-mix(in oklab,var(--gc) 45%,#fff)}
.rw-radar__gem-facet{fill:none;stroke:#fff;stroke-opacity:.5;stroke-width:.45}
.rw-radar__gem-glint{fill:#fff;transform-box:fill-box;transform-origin:center;
  animation:rw-gem-glint calc(var(--rw-beat) * 3) ease-in-out calc(var(--rw-beat) * var(--gd,0) * -2) infinite}
@keyframes rw-gem-glint{0%,70%,100%{opacity:.9;scale:1}80%{opacity:1;scale:1.8}}
/* the numbers carry their vertex's colour (radar.js); the dark halo keeps them legible on the haze */
.rw-radar__value{fill-opacity:1}
/* the switch: the leaving icon's copy (radar.js dissolve) fades into the haze's colour; the arriving one gathers in */
.rw-radar__gone{pointer-events:none}
.rw-radar__gone .rw-radar__mote{fill:color-mix(in oklab,var(--gem-2) 40%,var(--rw-radar-mist-ink))}
.rw-radar__place.is-forming .rw-radar__cloud-wrap{animation:rw-form-cloud 1.5s cubic-bezier(.2,.7,.3,1) both}
@keyframes rw-form-cloud{from{scale:1.7;opacity:.2}to{scale:1;opacity:1}}
.rw-radar__place.is-forming .rw-radar__glyph{animation:rw-form-line 1.5s ease-out both}
@keyframes rw-form-line{0%,35%{opacity:0}100%{opacity:1}}
@media (prefers-reduced-motion:reduce){.rw-radar__gem-glow,.rw-radar__gem-glint,.rw-radar__place.is-forming .rw-radar__cloud-wrap,.rw-radar__place.is-forming .rw-radar__glyph{animation:none}}
