/* The small mill's paper and ink: cream paper, sepia ink, madder, ochre, moss, millpond blue.
   Square corners, flat colour; the only loose, hand-made thing is the handwriting. */
:root {
  --paper: #FBF4E4; --ink: #2B2118; --red: #B3472C; --blue: #5E8494; --moss: #5F7A36; --ochre: #C98B2B;
  --grey: #7A6F5E; --rule: #E2D4B6; --wash: #F4EAD3;
  --ui: "Inter Tight", system-ui, sans-serif;
  --hand: "Caveat", cursive;

  /* Motion: one rule for everything that moves. What plays is quick: the hand, the lamps and the pulse keep to the
     beat, and things arriving snap in, overshoot a touch and shake once, settled within a quarter of a second. A thing
     being moved is a part, not a picture: it pops out of the plane (--lift), travels to its new place and size
     (--travel) and pops back in (--lift), each phase on --mech, deliberate, with a held --beat between them. The beat
     never waits for the animation. Change these and the whole toy moves differently. */
  --tick: 50ms;                                  /* the hand stepping on a 16th */
  --move: 200ms;                                 /* a ring being moved, or flying to a stack */
  --pop: 200ms;                                  /* a ring or a panel arriving */
  --settle: 250ms;                               /* the shake as something lands */
  --lift: 85ms;                                  /* a moved thing popping out of the plane, or back in */
  --beat: 45ms;                                  /* the held pause between popping out, travelling and popping in */
  --fade: 200ms;                                 /* a light changing: the old one goes out over this, the new one comes on over this */
  --travel: 210ms;                               /* and going to its new place and size, with everything making room */
  --rotate: 400ms;                               /* a ring turned to start a beat earlier or later, however far, on --mech */
  --spin: 120ms;                                 /* a ring the computer turns while playing (#143): the same rotation, at most a step long */
  --grow: 1000ms;                                /* how long a ring is carried before the stage makes room for another container */
  --mech: cubic-bezier(.65, 0, .35, 1);          /* slow off, steady, slow in: a part on a slide */
  --spring: cubic-bezier(.3, 1.45, .55, 1);      /* quick, past the mark, back */
  --stride: 1100ms;                              /* a cat's boots swinging while it waits (#208); twice as quick under the pointer */
  --wire: 250ms;                                 /* a link's wire in the pattern editor shooting from the lane that played to the one it reached */
  --whoosh: 1;                                   /* a ring's turn sweeps in over this many quarters of its loop, fades over as many */
  --spin-icon: 1900ms;                          /* the action picker's spin icon (#464): one turn over its first 47% (about 900 ms, eased out to a halt), a second held, round again. The only icon that moves */
  /* lights switch on and off over --fade, status lines included. The pulse round a ring moves constantly with the beat
     (no timing of its own). A lamp that sounds blazes white with a bright glow, holds two of its ring's steps (one on a
     ring of four places or fewer) and fades back over --flash, so you can see what played (Robin, 2026-10-23, #109, #122) */
  --flash: 1000ms;
  --flip: 360ms;                                 /* the page turning over to the pattern editor and back, half each way */
  --word: 45ms;                                  /* the promo's captions (#482): each word springs up this long after the one before */
  --cam: 700ms;                                  /* the promo's camera (#482) moving to what it looks at, on --mech; a punch out on --spring takes half */
  --intro: 3200ms;                               /* one round of a picture in the intro (#462): the hand once round a bar, the drag once, four switches of a lamp */
}
@keyframes flash { from { fill: var(--ink); } to { fill: var(--c); } }
@keyframes arrive { from { scale: .9; opacity: 0; } 60% { scale: 1.03; opacity: 1; } to { scale: 1; } }
* { box-sizing: border-box; }
html, body { height: 100%; }
html { background: var(--paper); }
body { position: relative; max-width: 1400px; margin: 0 auto; background: var(--paper); color: var(--ink); font: 500 14px/1.35 var(--ui); overflow: hidden; display: flex; flex-direction: column; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

.top { position: relative; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 18px 28px 14px; }
.top h1 { margin: 0; font: 700 26px/1 var(--ui); letter-spacing: -.03em; }
.top h1 span { font: 600 30px/0 var(--hand); color: var(--red); letter-spacing: 0; padding: 0 2px; }
.top .genre { margin-right: auto; }                                      /* by the title (#198) */
.transport { display: flex; align-items: center; gap: 18px; }
/* the loop the container in view is on (#256), kept after stop */
.loops { min-width: 3ch; text-align: right; color: var(--ink); opacity: .6; font-variant-numeric: tabular-nums; cursor: default; }
.loops::before { content: 'loop '; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; }
#play { min-width: 76px; padding: 8px 16px; border: 2px solid var(--ink); background: var(--paper); font-weight: 700; }
#play.on { background: var(--ink); color: var(--paper); }
#slow { min-width: 52px; font-variant-numeric: tabular-nums; }
#slow.on { background: var(--ochre); border-color: var(--ochre); color: var(--paper); }
#fix, #clear, #songs { padding: 8px 12px; border: 2px solid var(--rule); background: var(--paper); font-weight: 700; }
#fix:hover, #clear:hover, #songs:hover { border-color: var(--ink); }
#clear { color: var(--grey); }
/* the cats (#208): five down the right edge (#433), each dealing its own cards, asked one at a time. The cats and the
   handwriting are the only loose things, so round shapes are theirs */
#cats { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); z-index: 4; display: flex; flex-direction: column; align-items: center; gap: 4px; }
#cats .cat { position: relative; width: 52px; height: 74px; padding: 0; border: 0; background: none; cursor: pointer; }
#cats .cat-art { width: 100%; height: 100%; overflow: visible; animation: bob var(--stride) ease-in-out infinite; }
#cats .leg { transform-box: fill-box; transform-origin: top center; animation: swing var(--stride) ease-in-out infinite alternate; }
#cats .leg.r { animation-delay: calc(var(--stride) * -1); }
#cats .cat:nth-child(2n) .cat-art, #cats .cat:nth-child(2n) .leg { animation-delay: calc(var(--stride) * -.4); }
#cats .cat:nth-child(2n) .leg.r { animation-delay: calc(var(--stride) * -1.4); }
#cats .cat:hover .cat-art, #cats .cat:focus-visible .cat-art { animation-duration: calc(var(--stride) / 2); transform-origin: bottom center; }
#cats .cat:hover .leg, #cats .cat:focus-visible .leg { animation-duration: calc(var(--stride) / 2); }
#cats .cat:hover .head { transform: rotate(-6deg); transform-box: fill-box; transform-origin: bottom center; transition: transform var(--pop) var(--spring); }
#cats .think { position: absolute; right: 64px; bottom: 26px; width: 220px; padding: 8px 11px; border: 2px solid var(--ink); border-radius: 18px; background: var(--paper);
  font: 500 12px/1.35 var(--ui); text-align: left; color: var(--ink); opacity: 0; transform: translateX(6px); pointer-events: none; transition: opacity var(--fade), transform var(--pop) var(--spring); }
#cats .think b { display: block; font: 700 18px/1 var(--hand); margin-bottom: 3px; }
#cats .think::before, #cats .think::after { content: ""; position: absolute; border: 2px solid var(--ink); border-radius: 50%; background: var(--paper); }
#cats .think::before { right: -15px; bottom: 8px; width: 11px; height: 11px; }
#cats .think::after { right: -25px; bottom: 2px; width: 6px; height: 6px; }
#cats .cat:hover .think, #cats .cat:focus-visible .think { opacity: 1; transform: none; }
@keyframes swing { from { transform: rotate(14deg); } to { transform: rotate(-14deg); } }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
@media (prefers-reduced-motion: reduce) { #cats .cat-art, #cats .leg { animation: none; } }
.kit { font: 600 13px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); border-radius: 0; padding: 5px 8px; min-height: 34px; cursor: pointer; }
.kit:hover { border-color: var(--ink); }
.num { cursor: ns-resize; user-select: none; color: var(--grey); padding: 4px 2px; touch-action: none; }
.num b { color: var(--ink); font-size: 20px; font-variant-numeric: tabular-nums; display: inline-block; min-width: 1.6em; text-align: right; }

.room { position: relative; z-index: 1; flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(250px, 24%) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); gap: 20px; padding: 6px 86px 0 28px; }
.right { min-height: 0; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.side { overflow-y: auto; padding-bottom: 40px; }
/* the sound browser (#431, #440): a tab per kind, every sound a ring tile, the rhythm and its length picked above them */
.browse { position: relative; margin: 0 0 14px; }
.browse .tabs { display: flex; margin: 0 0 8px; }
.browse .tabs button { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; height: 34px; padding: 0; border: 1.5px solid var(--ink); border-left-width: 0; background: var(--paper); font: 700 9px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); cursor: pointer; }
.browse .tabs .icon { width: 18px; height: 18px; }
.browse .tabs button.on .icon { stroke: var(--paper); }
.browse .tabs button:first-child { border-left-width: 1.5px; }
.browse .tabs button:hover { background: var(--wash); }
.browse .tabs button.on { background: var(--ink); color: var(--paper); }
.browse .bar { display: flex; gap: 6px; margin: 0 0 10px; }
.browse .bar select, .browse .pick-rhythm { height: 30px; border: 1.5px solid var(--ink); background: var(--paper); font: 600 12px var(--ui); color: var(--ink); }
.browse .bar select { flex: none; max-width: 34%; padding: 0 4px; cursor: pointer; }
.browse .pick-rhythm { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; padding: 0 6px 0 3px; text-align: left; }
.browse .pick-rhythm span { flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.browse .pick-rhythm i { font-style: normal; font-size: 10px; }
.browse .pick-rhythm:hover, .browse .pick-rhythm.open { background: var(--wash); }
.browse .pick-rhythm .mini { width: 26px; height: 26px; flex: none; }
/* the keys tab condensed (#472): instruments as a list, the arp as a row of chips, off first, the one ring under them */
.browse .keyspick h3 { margin: 4px 0 4px; font: 700 9px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.browse .keyspick .instrs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; border-top: 1.5px solid var(--ink); border-left: 1.5px solid var(--ink); margin: 0 0 8px; }
.browse .keyspick .instr { display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 6px 0 4px; border: 0; border-right: 1.5px solid var(--ink); border-bottom: 1.5px solid var(--ink); background: var(--paper); font: 600 12px var(--ui); color: var(--ink); text-align: left; cursor: pointer; }
.browse .keyspick .instr span { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.browse .keyspick .instr .wave { flex: none; width: 30px; height: 18px; stroke: var(--grey); stroke-width: 1.2; fill: none; }
.browse .keyspick .instr:hover { background: var(--wash); }
.browse .keyspick .instr.on { background: var(--ink); color: var(--paper); } .browse .keyspick .instr.on .wave { stroke: var(--paper); }
.browse .keyspick .arpchips { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 10px; }
.browse .keyspick .arpchips button { height: 24px; padding: 0 7px; border: 1.5px solid var(--ink); background: var(--paper); font: 600 11px var(--ui); color: var(--ink); cursor: pointer; white-space: nowrap; }
.browse .keyspick .arpchips button:hover { background: var(--wash); }
.browse .keyspick .arpchips button.on { background: var(--ink); color: var(--paper); }
.browse .keyspick .arpchips button.edit { border-style: dashed; color: var(--grey); }
.browse .sounds.one { grid-template-columns: 34% 1fr; align-items: center; gap: 10px; }
.browse .sounds.one .how { font: 500 11px/1.35 var(--ui); color: var(--grey); }
.browse .sounds { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px 6px; }
.browse .sound.tile { position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 0; border: 0; background: none; color: var(--ink); cursor: grab; touch-action: none; }
.browse .sound .disc { width: 100%; aspect-ratio: 1; overflow: visible; }
.browse .sound .disc .band { fill: none; opacity: .28; }
.browse .sound .disc .band.thin { stroke: var(--rule); stroke-width: 1.5; opacity: 1; }
.browse .sound .disc .round { stroke: var(--c); stroke-width: 1.6; fill: none; }
.browse .sound .disc .prog { fill: none; stroke: var(--ink); stroke-width: 2; stroke-dasharray: 0 1; }
.browse .sound:hover .disc .band { opacity: .45; }
.lamps .band { fill: none; }
.mini .lamps .band { opacity: .3; }
.browse .lamps .hit, .chooser .lamps .hit { fill: var(--c, var(--ink)); }
.browse .lamps .rest, .chooser .lamps .rest { fill: var(--grey); }
.browse .lamps .note, .chooser .lamps .note { fill: var(--c, var(--ink)); opacity: .7; }
.browse .lamps .now, .chooser .lamps .now { fill: var(--paper); stroke: var(--c, var(--ink)); stroke-width: 1.5; }
.browse .lamps .rest.now { r: 2.4px; }
.browse .sound .mid { position: absolute; left: 0; right: 0; top: 0; aspect-ratio: 1; display: grid; place-items: center; pointer-events: none; }
.browse .sound .mid .icon { width: 34%; height: 34%; }
.browse .sound .mid .wave { width: 46%; stroke: var(--ink); stroke-width: 1.2; fill: none; }
.browse .sound .len { position: absolute; left: 0; top: 0; font: 700 10px/1 var(--ui); font-variant-numeric: tabular-nums; color: var(--grey); }
.browse .sound .name { font: 600 11px/1.15 var(--ui); text-align: center; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.browse .sound.none { opacity: .4; }
.browse .sound.offered .disc, .browse .sound:focus-visible .disc { outline: 1.5px solid var(--ink); outline-offset: 1px; }
/* the demo containers under the tiles (#455): a row each, its rings in little, name over genre and tempo */
.browse .demos { display: grid; grid-template-columns: 1fr 1fr; gap: 0 8px; margin-top: 18px; border-top: 1px solid var(--rule); padding-top: 10px; }
.browse .demos h2 { grid-column: 1 / -1; margin: 0 0 6px; font: 700 10px/1 var(--ui); letter-spacing: .12em; text-transform: uppercase; color: var(--grey); }
.browse .demo { display: flex; align-items: center; gap: 8px; width: 100%; padding: 3px 4px; border: 0; background: none; text-align: left; color: var(--ink); cursor: grab; touch-action: none; }
.browse .demo:hover, .browse .demo.offered { background: var(--wash); }
.browse .demo .mini { width: 34px; height: 34px; flex: none; overflow: visible; }
.browse .demo .lamps .band { opacity: .3; }
.browse .demo .words { display: flex; flex-direction: column; min-width: 0; }
.browse .demo b { font: 600 12px/1.2 var(--ui); }
.browse .demo .words span { font: 600 10px/1.2 var(--ui); color: var(--grey); }
svg.ghost { position: fixed; z-index: 7; width: 64px; height: 64px; margin: -32px 0 0 -32px; pointer-events: none; overflow: visible; }
svg.ghost .lamps .hit, svg.ghost .lamps .note { fill: var(--c, var(--ink)); }
svg.ghost .lamps .rest { fill: var(--grey); }
svg.ghost .lamps .band { fill: none; opacity: .3; }
/* the rhythms, every one the editor's library has, in columns over the stage */
.chooser { position: fixed; z-index: 6; overflow-y: auto; columns: 4 170px; column-gap: 18px; padding: 12px 14px 14px; background: var(--paper); border: 1.5px solid var(--ink); box-shadow: 4px 4px 0 rgb(0 0 0 / .08); }
.chooser section { display: flex; flex-direction: column; break-inside: avoid; margin-bottom: 6px; }
.chooser h3 { margin: 4px 0 4px; font: 700 10px/1 var(--ui); letter-spacing: .12em; text-transform: uppercase; color: var(--grey); }
.chooser button { display: flex; align-items: center; gap: 8px; padding: 3px 4px; text-align: left; font: 600 12px/1.2 var(--ui); }
.chooser button:hover { background: var(--wash); }
.chooser button.on { background: var(--ink); color: var(--paper); }
.chooser .mini { width: 30px; height: 30px; flex: none; }
.chooser button { width: 100%; }
.chooser button.on .lamps .hit, .chooser button.on .lamps .note { fill: var(--paper); }
.chooser .filters { column-span: all; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--rule); }
.chooser .facet { display: flex; align-items: center; gap: 0; }
.chooser .facet button { width: auto; padding: 4px 8px; border: 1px solid var(--ink); margin-left: -1px; font-size: 11px; }
.chooser .facet.refs { gap: 4px; }
.chooser .facet.refs button { padding: 2px; margin: 0; border-color: transparent; }
.chooser .facet.refs button.on { background: none; border-color: var(--ink); }
.chooser .facet.refs .mini { width: 26px; height: 26px; }
.chooser .filters .label { font: 600 11px/1 var(--ui); color: var(--grey); }
.chooser .filters select { font: 600 11px/1.2 var(--ui); padding: 3px 4px; border: 1px solid var(--ink); background: var(--paper); }
.chooser .none { font: 11px/1.3 var(--ui); color: var(--grey); margin: 2px 4px; }
/* shaded by how it sits with the ring picked: the best few outlined, the rest fainter as they score less */
.chooser button.scored { opacity: calc(.35 + .65 * var(--s)); }
.chooser button.scored .score { margin-left: auto; flex: none; width: 22px; height: 4px; background: linear-gradient(90deg, var(--red) calc(var(--s) * 100%), var(--grey) 0); opacity: .8; }
.chooser button.best { opacity: 1; outline: 1.5px solid var(--red); outline-offset: -1.5px; }
/* a click on a tile: where it goes */
.addto { position: fixed; z-index: 6; min-width: 190px; display: flex; flex-direction: column; padding: 8px; background: var(--paper); border: 1.5px solid var(--ink); box-shadow: 4px 4px 0 rgb(0 0 0 / .08); }
.addto h3 { margin: 0 0 6px; font: 700 10px/1 var(--ui); letter-spacing: .12em; text-transform: uppercase; color: var(--grey); }
.addto button { padding: 5px 6px; text-align: left; font: 600 12px var(--ui); }
.addto button:hover:not(:disabled) { background: var(--wash); }
.addto button:disabled { color: var(--grey); cursor: default; }
.addto button.new { border-top: 1px solid var(--rule); margin-top: 4px; }
.addto p { margin: 0; font: 600 12px var(--ui); color: var(--grey); }
.side h2 { margin: 0 0 10px; font: 700 11px/1 var(--ui); letter-spacing: .14em; text-transform: uppercase; color: var(--grey); }
.side h2 span { font: 600 18px/1 var(--hand); letter-spacing: 0; text-transform: none; color: var(--red); margin-left: 4px; }
.aside-note { font: 600 17px/1.1 var(--hand); color: var(--grey); margin: 10px 0 0; }

/* the map: every E(k, n) as a ring */
.key { margin: 2px 0 0; font: 600 17px/1.15 var(--hand); color: var(--grey); }
.key i { display: inline-block; width: 11px; height: 11px; margin: 0 6px 0 0; border: 2px solid var(--red); background: color-mix(in srgb, var(--red) 22%, transparent); vertical-align: -1px; }
.map { display: block; width: 100%; max-height: calc((100vh - 150px) * .66); user-select: none; touch-action: none; }
.map .axis { font: 600 10px var(--ui); fill: var(--grey); }
.map .axis.k, .map .axis.n { text-anchor: middle; font-variant-numeric: tabular-nums; }
.m { cursor: grab; }
.m .bg { stroke: none; }
.m .bg { fill: var(--red); fill-opacity: var(--heat, 0); }
.m:hover .bg { stroke: var(--ink); stroke-width: 1; }
.m.named .track { stroke: var(--ink); stroke-width: 1.2; }
.m.fit1 .bg, .m.fit2 .bg, .m.top .bg { stroke: var(--red); stroke-width: 2; }
.m.fit2 .bg { stroke-dasharray: 3 2; }
.m.ref .bg { fill: var(--wash); fill-opacity: 1; stroke: var(--ink); stroke-width: 2.5; stroke-dasharray: 4 2; }
.mapctl { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 0 0 8px; font: 600 11px var(--ui); color: var(--grey); text-transform: uppercase; letter-spacing: .1em; }
.mapctl select { margin-left: 4px; font: 600 13px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); border-radius: 0; padding: 2px 5px; text-transform: none; letter-spacing: 0; }
.mapctl select:hover { border-color: var(--ink); }
.m.on .bg { fill: var(--paper); stroke: var(--ink); stroke-width: 2.5; }
.m.aud .bg { fill: var(--wash); stroke: var(--ink); stroke-width: 2.5; }
.track { fill: none; stroke: #CDBB97; stroke-width: 1; }
.poly { fill: var(--c); fill-opacity: .14; stroke: var(--c); stroke-width: 1.4; stroke-linejoin: round; }
.rest { fill: #BBA984; }
.hit { fill: var(--c); stroke: var(--ink); stroke-width: .8; transform-box: fill-box; transform-origin: center; }
.hit.lit { animation: lit .22s ease-out; }
@keyframes lit { from { transform: scale(1.9); } to { transform: scale(1); } }
.hand { pointer-events: none; stroke: var(--ink); stroke-width: 2.5; stroke-linecap: square; }

/* the stage: containers on a grid, 3 by 3 and then 5 by 5, as big as fit, rows centred (stage.js size) */
.deck { flex: 1; min-height: 0; display: flex; gap: 14px; }
.stage { flex: 1; min-height: 0; min-width: 0; position: relative; touch-action: none; }
/* the event log (#154): newest at the top, the older rows fading down the column */
.log { flex: none; width: 232px; min-height: 0; display: flex; flex-direction: column; overflow: hidden; -webkit-mask-image: linear-gradient(#000 70%, transparent); mask-image: linear-gradient(#000 70%, transparent); }
.log h2 { margin: 0 0 8px; font: 700 11px/1 var(--ui); letter-spacing: .14em; text-transform: uppercase; color: var(--grey); }
.log:not(:has(.rows > *)) { visibility: hidden; }
.log .rows { list-style: none; margin: 0; padding: 0; }
.log .row { display: flex; align-items: center; gap: 5px; height: 22px; white-space: nowrap; font: 600 11px/1 var(--ui); animation: arrive var(--pop) var(--spring); }
.log .cn { width: 10px; flex: none; color: var(--grey); text-align: right; font-variant-numeric: tabular-nums; }
.log .ring-pic { width: 18px; height: 18px; flex: none; }
.log .ev { width: 12px; height: 12px; flex: none; fill: var(--ink); stroke: var(--ink); stroke-width: 1.3; stroke-linecap: round; }
.log .ev.rests circle { fill: none; }
.log .to { color: var(--grey); }
.log .res { display: inline-flex; align-items: center; gap: 2px; }
/* a switch that reached a whole container (#169): its number, boxed */
.log .res .whole { min-width: 10px; padding: 0 2px; border: 1px solid currentColor; font-size: 9px; line-height: 11px; text-align: center; font-variant-numeric: tabular-nums; }
.log .act { display: inline-flex; align-items: center; gap: 2px; height: 16px; padding: 0 4px; background: var(--k); color: #1c1916; }
.log .act svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.log .act.play svg { fill: currentColor; }
.log .act i { font: 700 10px/1 var(--ui); font-style: normal; }
.log .n { color: var(--grey); font-weight: 600; font-variant-numeric: tabular-nums; }
/* the editor's: one line under its header, newest on the left (#158) */
.log.line { grid-column: 1 / -1; width: auto; flex-direction: row; align-items: center; gap: 14px; height: 24px; -webkit-mask-image: linear-gradient(90deg, #000 75%, transparent); mask-image: linear-gradient(90deg, #000 75%, transparent); }
.log.line h2 { margin: 0; flex: none; }
.log.line .rows { display: flex; gap: 18px; }
.log.line .cn { display: none; }
.log.line .none { font-size: 14px; white-space: nowrap; }
.box, .slot { position: absolute; transition: left var(--move), top var(--move), width var(--move), height var(--move); }
.box svg, .slot svg { display: block; width: 100%; height: 100%; overflow: visible; }
.hoop { fill: none; stroke: var(--rule); stroke-width: 1.5; }
.box.over .hoop, .slot.over .hoop { stroke: var(--red); stroke-width: 3; stroke-dasharray: 6 4; }
.box.muted .hoop { stroke-dasharray: 2 4; }
/* a whole container held back (#251), the hatch the standard way of saying so: muted red, not listened to grey, over the
   hoop, and everything inside at half */
.box.muted::after, .box.unheard::after { content: ''; position: absolute; inset: calc((1 - 121 / 134) * 50%); border-radius: 50%; pointer-events: none;
  background: repeating-linear-gradient(-45deg, var(--hatch) 0 1.5px, transparent 1.5px 8px); }
.box.muted { --hatch: color-mix(in srgb, var(--red) 70%, transparent); }
.box.unheard { --hatch: color-mix(in srgb, var(--ink) 30%, transparent); }
.box :is(svg.rings > .ring, > .scope) { transition: opacity var(--fade); }
.box:is(.muted, .unheard) :is(svg.rings > .ring, > .scope) { opacity: .5; }
.box.deep::after { display: none; }
.slot { visibility: hidden; }
.stage.grow .slot { visibility: visible; animation: arrive var(--pop) var(--spring); }
.slot .hoop { stroke-dasharray: 4 4; }
.slot .plus { stroke: var(--grey); stroke-width: 3; stroke-linecap: square; }
.slot.over .plus { stroke: var(--red); }
/* the scope in the hole (#106): drawn by stage.scope, sized by stage.fit, never in the way of a click */
.box > .scope { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); pointer-events: none; }
.box .x { display: none; stroke: var(--red); stroke-width: 6; stroke-linecap: square; pointer-events: none; }
.stage.dragging .box.full:not(.from) .x { display: block; }
/* the container's clock (#445): ticks on the hoop, heavier on the beat, and the hand riding it, faint while stopped */
.clock .tick { stroke: var(--ink); stroke-width: 1; opacity: .35; }
.clock .tick.beat { stroke-width: 1.5; opacity: .7; }
.rings .chand { fill: var(--ink); opacity: .3; pointer-events: none; transition: opacity var(--fade); }
.stage.playing .rings .chand { opacity: 1; }
/* the tools' panel at the top right (#444), a band round the hoop */
.rings .toolbed { fill: var(--wash); stroke: var(--rule); stroke-width: 1; pointer-events: none; }
.box.bare .toolbed, .stage.dragging .toolbed { display: none; }
.tool { cursor: pointer; }
.tool .target { fill: transparent; stroke: none; }
/* every icon is the same 16-unit drawing (stage.js ICON), inset in its circle so nothing reaches the edge */
.icon { overflow: visible; fill: none; stroke: var(--ink); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.tool .icon { stroke: var(--grey); }
.tool:hover .icon { stroke: var(--ink); }
.tool:hover .target { fill: var(--wash); }
/* a tool that is on (effects in use, the solo held, something muted) is filled: ink, or --on */
.tool.on .target, .tool.on:hover .target { fill: var(--on, var(--ink)); }
.tool.on .icon, .tool.on:hover .icon { stroke: var(--paper); }
.tool.mute.on { --on: var(--red); }
.tool.mute.on:hover { --on: var(--ink); }
.stage.dragging .tool { visibility: hidden; }
/* the cards tool, a fanned deck (#432): paper faces so they overlap, rising a little apart on hover */
.icon .card rect { fill: var(--paper); }
.tool .icon .card { transition: transform var(--pop, .15s) ease-out; }
.tool:hover .icon .card.c0 { transform: translate(-.6px, -1.2px); }
.tool:hover .icon .card.c1 { transform: translateY(-1.8px); }
.tool:hover .icon .card.c2 { transform: translate(.6px, -1.2px); }
/* the question after a drop (#435): a paper circle the size of the second place's hole, its buttons the only thing
   that takes the pointer */
.box > .ask-edit { position: absolute; left: 50%; top: 50%; width: var(--d); aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 50%;
  border: 2px solid var(--c, var(--ink)); background: color-mix(in srgb, var(--paper) 94%, transparent); display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 4px; text-align: center; pointer-events: none; z-index: 2; animation: pop-in var(--pop) var(--spring); }
.ask-edit p { margin: 0; font: 600 26px/1 var(--hand); color: var(--c, var(--ink)); }
.ask-edit .go { display: flex; gap: 6px; margin-top: 6px; }
.ask-edit button { pointer-events: auto; padding: 5px 14px; border: 2px solid var(--rule); background: var(--paper); font: 700 12px var(--ui); cursor: pointer; }
.ask-edit button:hover { border-color: var(--c, var(--ink)); }
.ask-edit button.main { background: var(--c, var(--ink)); border-color: var(--c, var(--ink)); color: var(--paper); }
@keyframes pop-in { from { opacity: 0; transform: translate(-50%, -50%) scale(.9); } }
/* an empty song (#462): the first circle asks what you'd like to make, a button a kind, each opening its intro. Only the
   buttons take the pointer, so a sound still drops in under it; while one is carried the question goes and the circle
   says where to drop */
.box > .welcome { position: absolute; left: 50%; top: 50%; width: var(--d); aspect-ratio: 1; transform: translate(-50%, -50%); display: flex;
  flex-direction: column; align-items: center; justify-content: center; gap: 10px; text-align: center; pointer-events: none; z-index: 2; animation: pop-in var(--pop) var(--spring); }
.welcome p { margin: 0; font: 600 32px/1 var(--hand); color: var(--ink); }
.welcome .go { display: flex; gap: 6px; }
.welcome button { pointer-events: auto; display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 12px; border: 1.5px solid var(--ink); background: var(--paper);
  font: 700 10px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); cursor: pointer; }
.welcome button .icon { width: 18px; height: 18px; }
.welcome button:hover { background: var(--ink); color: var(--paper); }
.welcome button:hover .icon { stroke: var(--paper); }
.welcome .or { font: 600 19px var(--hand); color: var(--grey); }
.box:has(> .welcome) .rings .empty, .stage.dragging .welcome { display: none; }
.stage.dragging .box:has(> .welcome) .rings .empty { display: inline; }
/* an empty container shows nothing round its rim until a ring is in (#430): first there is only somewhere to drop */
.box.bare .tool, .box.bare .layers { display: none; }
/* the layers in a row under a container (#179, #446): a mini of each, the one being changed framed in ink, the one heard
   with an ochre bar; the framed one goes ochre and counts down while it waits for the top of the loop, as a launched clip waits for its quantise */
.layer .target { fill: var(--paper); stroke: var(--rule); stroke-width: 1; }
.layer.shown .target, .layer.shown:hover .target { stroke: var(--ink); }
.layer .band { fill: none; stroke-width: 1.3; }
.layer .band.off { stroke-dasharray: 1.2 1.1; }
.layer .notch { stroke: var(--ink); stroke-width: .9; }
.layer .face.muted { opacity: .45; }
.layer .letter { font: 700 7px var(--ui); text-anchor: middle; fill: var(--ink); pointer-events: none; }
.layer .tab { fill: var(--paper); stroke: var(--rule); stroke-width: .8; }
.layer.shown .tab { fill: var(--ink); stroke: var(--ink); }
.layer.shown .letter { fill: var(--paper); }
.layer .lit { fill: var(--ochre); opacity: 0; transition: opacity var(--fade); }
.layer.heard .lit { opacity: 1; }
.layer .target { transition: stroke var(--fade); }
.box.waiting .layer.shown .target, .box.waiting .layer.shown:hover .target { stroke: var(--ochre); stroke-width: 1.6; }
/* the steps left before the layer shown comes in (#236), counted down beside it */
.layer .wait { font: 700 7px var(--ui); text-anchor: middle; fill: var(--ochre); opacity: 0; transition: opacity var(--fade); pointer-events: none; }
.box.waiting .layer.shown .wait { opacity: 1; }
.layer .drop { opacity: 0; transition: opacity var(--fade); }
.layer:hover .drop { opacity: 1; }
.layer .drop rect { fill: var(--paper); stroke: var(--grey); stroke-width: .8; }
.layer .drop path { stroke: var(--ink); stroke-width: .9; }
.layer .drop:hover rect { fill: var(--red); stroke: var(--red); }
.layer .drop:hover path { stroke: var(--paper); }
.layer.add .target { stroke: none; }
/* the layers stacked in 3D (#179): the flat drawing fades, and the plates lift from where it was into an isometric stack,
   A on top; playing, they spread further apart and the one heard is lit, the rest dimmed */
.box.deep svg.rings > :not(.tool):not(.layers), .box.deep > .scope { opacity: 0; pointer-events: none; transition: opacity var(--fade); }
.box > .pile { position: absolute; inset: 0; pointer-events: none; transform-style: preserve-3d; --gap: calc(var(--cell) * .08);
  transform: translateY(calc(var(--cell) * -.05)) rotateX(56deg) rotateZ(-38deg) scale(.62);
  transition: transform calc(var(--lift) + var(--travel)) var(--mech); }
.stage.playing .box > .pile { --gap: calc(var(--cell) * .12); }
.pile .plate { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none;
  transform: translateZ(calc(var(--k) * var(--gap))); transition: transform calc(var(--lift) + var(--travel)) var(--mech), opacity var(--fade); }
.box > .pile.flat, .pile.flat .plate { transform: none; }
.plate .disc { fill: var(--paper); stroke: var(--rule); stroke-width: 2; }
.plate .disc, .plate .band { pointer-events: visiblePainted; cursor: pointer; }
.plate .band:hover { stroke: var(--ink); stroke-width: 3; }
.panel .layered { margin: 4px 0 0; color: var(--dim); font-size: 11px; max-width: 26ch; }
.plate:hover .disc { fill: var(--wash); }
.plate.shown .disc { stroke: var(--ink); }
.plate.heard .disc { stroke: var(--ochre); stroke-width: 5; }
.stage.playing .pile .plate:not(.heard), .pile .plate.muted { opacity: .5; }
/* a layer's mini under the pointer lights its plate (#446) */
.pile.lighting .plate:not(.lit) { opacity: .25; }
.pile .plate.lit .disc { fill: var(--wash); stroke: var(--ink); stroke-width: 3; }
.plate .band.off { opacity: .5; }
.plate .pin { fill: var(--paper); pointer-events: none; }
/* a layer's links (#236): the gaps they cross in each action's light, held faint, the heard plate's flashing as they fire */
.plate .gap { opacity: .8; stroke-width: 3; }
.plate .letter { font: 700 18px var(--ui); fill: var(--ink); text-anchor: end; pointer-events: none; }
.rings { display: block; width: 100%; user-select: none; cursor: pointer; }
.rings .empty { text-anchor: middle; font: 600 19px var(--hand); fill: var(--grey); }
/* the band is the ring's top face in steel with a breath of its colour, opaque so its side (.wall, below it) shows
   only past its edges. The grain and the sheen (steel.js) lie over it; the sheen turns to face the pointer */
.ring .band { fill: none; stroke: color-mix(in srgb, var(--c) 55%, #b8b3a9); }
.ring .wall { fill: none; stroke: color-mix(in srgb, var(--c) 50%, #4a463f); pointer-events: none; }
.ring .face { pointer-events: none; }
/* the angle the ring itself is turned to round the container's middle (#131, stage.js turn): the whole ring rotates,
   a part ring travelling round the circle. Its light stays where it is, and the sheen keeps facing the pointer */
@property --turned { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
.ring .sheen { opacity: .55; transform: rotate(calc(var(--light, -45deg) - var(--turned))); transform-box: view-box; transform-origin: 0 0; }
.ring .groove { fill: none; stroke: #4a443c; stroke-opacity: .55; stroke-width: 3.2; pointer-events: none; }
.ring .groove.lip { stroke: #fffdf6; stroke-opacity: .7; stroke-width: 2.6; }
/* a lamp in its socket: a bright bezel lit from the top left, a dark recess, the glass with a speck of light on it */
.ring .sockets, .ring .glass, .ring .halo, .ring .ghost { pointer-events: none; }
.ring .bezel { fill: #2f2a25; stroke-width: .8; }
.ring .recess { fill: none; stroke-width: .4; }
.ring .glass circle { fill: #fffdf6; fill-opacity: .55; }
.ring .halo { opacity: 0; mix-blend-mode: screen; }
.ring .h0 { stop-color: #fff; stop-opacity: 1; }
.ring .hm { stop-color: #fff; stop-opacity: .55; }
.ring .h1 { stop-color: #fff; stop-opacity: 0; }
/* the metal: a hairline at each edge of the band, bright where the light catches it and dark where it doesn't */
.ring .rim { fill: none; stroke-width: 1; pointer-events: none; }
.ring .rim.in { stroke-width: .8; }
.rings .shine { stop-color: #fffdf6; stop-opacity: .95; }
.rings .mid { stop-color: #b9a888; stop-opacity: .45; }
.rings .shade { stop-color: #3a2c1e; stop-opacity: .6; }
.rings .clear { stop-color: #fffdf6; stop-opacity: 0; }
.ring .rim.glint { stroke-width: 1.4; }
.ring:hover .band { stroke: color-mix(in srgb, var(--c) 65%, #c2bdb3); }
/* a ring's states (material.js dresses it): the steel never changes or fades. The status lines along its two edges
   light up instead, white selected, a trace where a lifted ring was; muted lights the groove red and its lit lamps go
   dim. The lines come on and go off over --fade (stage.js wear) */
.ring .status { fill: none; stroke: var(--status); stroke-width: 1.5; pointer-events: none; opacity: 0; filter: drop-shadow(0 0 .6px rgb(28 24 20 / calc(.9 * var(--glow)))) drop-shadow(0 0 calc(1px + 3px * var(--glow)) var(--status)); }
.ring.lit .status { opacity: 1; }
.ring .hush { fill: none; stroke: var(--hush); stroke-width: 2.2; pointer-events: none; opacity: 0; filter: drop-shadow(0 0 .6px rgb(28 24 20 / calc(.9 * var(--hglow)))) drop-shadow(0 0 calc(1px + 3px * var(--hglow)) var(--hush)); }
.ring.hushed .hush { opacity: 1; }
/* the inner strip lit while the container's filter is on (#207) */
.ring .filt { fill: none; stroke: #8fd3ff; stroke-width: 1.6; pointer-events: none; opacity: 0; transition: opacity var(--fade); filter: drop-shadow(0 0 2px #8fd3ff); }
.ring.filtered .filt { opacity: 1; }
.ring.bodiless > :not(.status) { visibility: hidden; }
.ring.hidden { visibility: hidden; }
/* the selected ring has an arrow out and an arrow in at its top right */
.shift .arrow { fill: var(--ink); stroke: var(--ink); stroke-width: 1.4; stroke-linejoin: round; filter: drop-shadow(0 1.5px 1.2px rgb(43 33 24 / .35)); }
.shift .target { fill: none; stroke: transparent; stroke-width: 2.5; stroke-linejoin: round; pointer-events: all; }
.shift:hover .arrow { fill: var(--red); stroke: var(--red); }
.shift:hover .target { fill: none; }
/* while rings move (stage.js put) the script sets their scale, shadow and fade: .rise is out of the plane towards you,
   .sink pushed in behind. The rule lines and arrows wait until they have stopped */
.box.moving .gap, .box.moving .shifts { visibility: hidden; }
/* lamps are white whatever the ring (#103): a hit lit low, a warm white with a soft rim of light round it so it reads
   as a lamp that is on rather than grey paint (#108), the one sounding full white, the rest dark */
.ring .spin .hit { fill: color-mix(in srgb, #f4ecd6 calc(82% * var(--lit, 1)), #1c1916); stroke: rgb(255 246 222 / calc(.38 * var(--lit, 1))); stroke-width: .8; }
.ring .spin { transform-box: view-box; transform-origin: 0 0; }
.ring .chase { pointer-events: none; display: none; }
/* the pulse (#110): a white light in the groove that moves round constantly, its tail fading out over a few steps
   behind it (stage.js glide, TRAIL). One glow for the whole of it */
.ring .chase { filter: drop-shadow(0 0 .8px rgb(28 24 20 / .9)) drop-shadow(0 0 4px #fff); }
.ring .chase path { fill: none; stroke: #fff; stroke-width: 3; }
.ring .chase path.head { stroke-linecap: round; }
/* a part ring's ends are round (#111) */
.ring.part .band, .ring.part .wall { stroke-linecap: round; }
/* a ring shorter than the circle: the rest of the band is a faint ghost, the part closed off with metal at each end */
.ring .track { fill: none; stroke: var(--c); stroke-opacity: .09; }
.ring .rim.end { stroke: #b9a888; stroke-opacity: .7; fill: none; }
.playing .ring:not(.still) .chase { display: inline; }
.ring { transform-box: view-box; transform-origin: 0 0; rotate: var(--turned); }
.ring.fresh { animation: arrive var(--pop) var(--spring); }
.ring .spin .cut { fill: #1c1916; stroke: none; }
/* a rest is no lamp, a pinhole in the steel a little darker than the band, its socket gone (#120) */
.ring .spin .rest { fill: color-mix(in srgb, var(--c) 45%, #4f4a42); stroke: none; }
.ring .hole { opacity: 0; }
.ring .bezel, .ring .recess, .ring .glass circle { transition: opacity var(--fade); }
/* flat colour for now (Robin, 2026-10-23, #130, FLAT in stage.js): the band is the ring's colour itself, with no wall,
   no light on it and no metal edges; a lamp sits in a plain dark socket and a rest is a darker pinhole. In the hand the
   slices behind go too, so it is the same flat ring tipped in perspective */
.flat .ring .wall, .flat .ring .face, .flat .ring .rim, .flat .ring .groove.lip, .flat .ring .recess, .flat .ring .glass, .flat .carry3d .slice { display: none; }
.ring .marks { fill: none; stroke: #fff; stroke-opacity: .45; stroke-width: .7; pointer-events: none; }
.ring .marks.beat { stroke-opacity: .8; stroke-width: 2.2; }
.ring .marks.sub { stroke-opacity: .6; stroke-width: .6; }
.ring .note { fill: #fff; fill-opacity: .75; pointer-events: none; transform-box: fill-box; transform-origin: center; }
/* a keyboard ring's notes (#474): a place is a group of segments, one a note, dressed by the lamp's classes and fills
   (the segments inherit them: a hit cream, a ghost amber, a cut dark, frozen dark outlined red). A rest is no note at
   all, the group going out over --fade and coming on over the same as a lamp's light does */
.ring .spin > g { transition: opacity var(--fade); }
.ring .spin > g.rest:not(.frozen) { opacity: 0; }
.ring .spin .seg { stroke-linejoin: miter; }
/* a note at rest is lit a little lower than a lamp, the ring's colour showing through, so the one sounding reads as on
   along its whole length for as long as it is held (stage.hit) */
.flat .ring .spin > g.hit:not(.ghost) { fill: color-mix(in srgb, color-mix(in srgb, #fff8e6 86%, var(--c)) calc(100% * var(--lit, 1)), #1c1916); }
/* its socket: a hairline of the lamp's socket colour round each segment, so a note reads on a light band too */
.flat .ring.keyed .spin > g:not(.frozen) { stroke: color-mix(in srgb, var(--c) 35%, #1c1916); stroke-width: .7; }
.flat .ring .band { stroke: var(--c); }
.flat .ring:hover .band { stroke: color-mix(in srgb, var(--c) 85%, #fff); }
.flat .ring .bezel { fill: color-mix(in srgb, var(--c) 35%, #1c1916); stroke: none; }
.flat .ring .groove { stroke: #1c1916; stroke-opacity: .3; }
.flat .ring .spin .rest { fill: color-mix(in srgb, var(--c) 50%, #1c1916); }
/* flat lamps: a lit hit is a clean cream dot in its dark socket, no rim of grey, so it reads as a light on flat colour */
.flat .ring .spin .hit { fill: color-mix(in srgb, #fff8e6 calc(100% * var(--lit, 1)), #1c1916); stroke: none; }
.flat .carry3d .front { filter: drop-shadow(0 12px 8px rgb(43 33 24 / .3)); }
/* a ghost hit (#91): played quieter, lit amber at the same brightness a hit has */
.ring .spin .hit.ghost, .flat .ring .spin .hit.ghost { fill: color-mix(in srgb, #F2A33A calc(100% * var(--lit, 1)), #1c1916); stroke: none; }
/* a frozen hit: dark, with a red ring round the lamp. Its own red, not the kick's */
.ring .spin .frozen { fill: #1c1916; stroke: #E5321C; stroke-width: .8; }
.flat .ring.keyed .spin > g.frozen { fill: #1c1916; }
.ring.sel .spin .hit, .ring.sel .spin .frozen { cursor: pointer; }
/* a pass condition (#104): its status ring in ticks, one per pass, the one it plays on lit */
.ring .ticks path { fill: none; stroke: rgb(255 255 255 / .3); stroke-width: .7; }
.ring .ticks path.on { stroke: #fff; }
.ring .dash { display: none; fill: none; stroke: var(--ink); stroke-width: .9; stroke-dasharray: 3 2.5; pointer-events: none; }
/* swap with (#77): every ring the one in hand could swap with wears a dashed line; the one under it goes red */
.ring.swap .dash { display: inline; }
.ring.swap.over .dash { stroke: var(--red); stroke-width: 1.6; }
.stage.swapping .tool, .stage.swapping .shift { pointer-events: none; }
.ring .cross { fill: none; stroke: rgb(255 255 255 / .5); stroke-width: .7; stroke-linecap: round; pointer-events: none; }
.whoosh path { fill: none; stroke-dasharray: 1 1; animation: whoosh calc(var(--q) * var(--whoosh) * 2) linear forwards; pointer-events: none; }
/* the turn a ring is on (#87): the segments of its groove it will turn by, from its start, flashing once a bar up to
   each turn in the turn's colour (the whoosh's). Dark between flashes */
.ring .clock { opacity: 0; pointer-events: none; }
.ring .clock path { fill: none; stroke: var(--h); stroke-linecap: round; }
.ring .clock .core { stroke-width: 2.4; filter: drop-shadow(0 0 .8px rgb(28 24 20 / .9)); }
.ring .clock .glow { stroke-width: 9; mix-blend-mode: plus-lighter; filter: blur(2px); opacity: .7; }
@keyframes whoosh { from { stroke-dashoffset: 1; } 50% { stroke-dashoffset: 0; opacity: 1; } to { stroke-dashoffset: 0; opacity: 0; } }
body.paused .whoosh path { animation-play-state: paused; }
/* the lights between a ring and the one inside it that its rule works (material.js link): a dark socket in the gap
   at each place, lit white at half where the rule lets it through, red where it takes the hit away. As the rule
   works a place its light flashes the rule's colour (stage.js spark) */
.gap { fill: none; stroke-width: 2.4; opacity: 0; pointer-events: none; transform-box: view-box; transform-origin: 0 0; rotate: -90deg; }

/* the lights: one meaning everywhere. Green on the usual path, amber off it, red likely to sound wrong */
.light { fill: var(--lc); stroke: var(--paper); stroke-width: 1.5; pointer-events: none; }
.lv0 { --lc: #6F8A3C; } .lv1 { --lc: #D99A1E; } .lv2 { --lc: #C2410C; }
i.light, button.light { display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: var(--lc); flex: none; }
button.light.big { width: 16px; height: 16px; box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--ink); pointer-events: auto; }
button.light[hidden] { display: none; }

/* a ring's panel, hanging over its stack on a neck */
.pop { position: fixed; inset: 0; z-index: 5; pointer-events: none; display: none; }
.pop.show { display: block; }
.pop .neck { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.pop .neck .fill { fill: var(--paper); stroke: none; }
.pop .neck .side { fill: none; stroke: var(--ink); stroke-width: 2; }
.panel { position: absolute; left: 0; top: 0; z-index: 1; pointer-events: auto; background: var(--paper); border: 2px solid var(--ink); padding: 8px; display: flex; flex-direction: column; gap: 6px; }
.panel.fresh { transform-origin: 50% 100%; animation: arrive var(--pop) var(--spring); }
.panel.below.fresh { transform-origin: 50% 0; }
.panel .row { display: flex; gap: 5px; align-items: center; }
.panel .icon { width: 18px; height: 18px; flex: none; }
.panel .row > .icon { margin: 0 3px 0 1px; }
.panel .sound .light { margin-left: auto; width: 12px; height: 12px; cursor: help; }
.panel button, .panel select { font: 600 13px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); padding: 3px 7px; border-radius: 0; min-height: 28px; }
.panel button { min-width: 30px; display: inline-flex; align-items: center; justify-content: center; }
.panel button .icon { width: 15px; height: 15px; }
.panel button:hover:not(:disabled), .panel select:hover { border-color: var(--ink); }
.panel select.kit:has(option[value=""]:checked) { color: var(--grey); }    /* the song's own kit, said quietly (#152) */
.panel .num { min-width: 2ch; text-align: center; font-variant-numeric: tabular-nums; }
.panel .num.k { margin-right: 6px; }
.panel button:disabled { opacity: .3; cursor: default; }

/* the strip (#133): the container in focus, a lane per ring, each one revolution of its ring stretched across the
   width and standing still; a scope beside each lane and the pencil that opens the editor at the right */
.strip { flex: none; height: 124px; display: grid; grid-template-columns: auto 1fr auto; align-items: end; gap: 10px; visibility: hidden; padding-bottom: 6px; }
.strip.show { visibility: visible; }
.scopes { display: flex; flex-direction: column; }
.scopes canvas { display: block; margin: calc((var(--lane) - 24px) / 2) 0; }
.lanes { display: block; width: 100%; }
.lanes .bed { fill: var(--wash); }
.lanes .quiet .bed { fill: none; stroke: var(--ink); stroke-opacity: .3; stroke-width: 1; vector-effect: non-scaling-stroke; }
.lanes .quiet.muted .bed { stroke: #c43a2b; stroke-opacity: .5; }
.lanes .tick { fill: none; stroke: var(--ink); stroke-opacity: .14; stroke-width: 1; vector-effect: non-scaling-stroke; }
.lanes .tick.q { stroke-opacity: .1; }
.lanes .tick.beat { stroke-opacity: .45; stroke-width: 1.5; }
.lanes .on { fill: var(--c); }
.lanes .on.cond { fill-opacity: .45; }
.lanes .on.sub { fill-opacity: .8; }
.lanes .quiet .on { fill-opacity: .35; }
.lanes .on.lit { animation: flash calc(var(--settle) * 1.2) ease-out; }
.lanes .cut rect, .lanes .cut path { fill: none; stroke: var(--ink); stroke-opacity: .55; stroke-width: 1; vector-effect: non-scaling-stroke; }
.lanes .frozen { fill: none; stroke: #c43a2b; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.lanes .head { fill: var(--ink); fill-opacity: .12; }
.strip .edit { width: 40px; height: 40px; margin-bottom: 4px; border-radius: 50%; border: 1.5px solid var(--ink); background: var(--paper); display: grid; place-items: center; cursor: pointer; padding: 0; }
.strip .edit:hover { background: var(--ink); color: var(--paper); }
.strip .edit .icon { width: 18px; height: 18px; }
.strip .edit:hover .icon { stroke: var(--paper); }

/* the modal: plain, in the middle, the rest blurred behind it (modal.js) */
.modal-back { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; background: rgb(251 244 228 / .45); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.modal { background: var(--paper); border: 2px solid var(--ink); padding: 16px 18px; min-width: 300px; max-width: min(640px, 92vw); max-height: 86vh; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; animation: arrive var(--pop) var(--spring); }
.modal h2 { margin: 0 0 2px; font: 700 11px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.modal.ask h2 { font: 600 16px var(--ui); letter-spacing: 0; text-transform: none; color: var(--ink); }
.modal .field { display: grid; grid-template-columns: 70px 1fr; align-items: center; gap: 10px; font: 600 13px var(--ui); }
.modal .field > span { color: var(--grey); font-size: 12px; }
.modal button, .modal select, .computer button, .computer select { font: 600 13px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); padding: 4px 10px; border-radius: 0; min-height: 30px; cursor: pointer; }
.modal button:hover, .modal select:hover, .computer button:hover, .computer select:hover { border-color: var(--ink); }
.modal button.main, .computer button.main { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.modal button.toggle { display: inline-flex; align-items: center; gap: 6px; justify-self: start; }
.modal button.toggle .icon { width: 15px; height: 15px; }
.modal button.toggle.on { border-color: var(--red); color: var(--red); }
.modal button.toggle.on .icon { stroke: var(--red); }
.modal input[type=range] { width: 100%; accent-color: var(--ink); }
.modal .actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
/* a new ring from the editor (#470, new-ring.js): the browser in the modal, its tiles clicked rather than dragged */
.modal.newring { width: min(520px, 92vw); }
.modal.newring .browse { margin: 0; }
.modal.newring .browse button { min-height: 0; }
.modal.newring .browse .sound.tile { cursor: pointer; }
.modal.newring .browse .sound.tile:hover .disc { outline: 1.5px solid var(--ink); outline-offset: 1px; }
.chooser, .addto { z-index: 25; }
/* the intro (#462, #471, intro.js): the steps on the left, each a choice of three or a thing to change, heard through
   the browser's audition, the pictures on --intro; what a ring of that kind is on the right */
.modal.intro { width: min(1060px, 94vw); max-width: min(1060px, 94vw); }
.intro .grid { display: grid; grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr); gap: 22px; }
.intro .steps { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.intro .scene { height: 300px; padding: 12px; display: flex; align-items: center; justify-content: center; gap: 24px; border: 1.5px solid var(--rule); background: var(--wash); }
.intro .scene .pic { height: 100%; max-width: 100%; }
.intro .words { min-height: 92px; }
.intro .words h3 { margin: 0; font: 700 15px var(--ui); }
.intro .words p { margin: 4px 0 0; max-width: 60ch; }
.intro .nav { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.intro .nav [hidden] { display: inline-block; visibility: hidden; }
.intro .dots { display: flex; gap: 6px; }
.intro .dots .dot { width: 12px; height: 12px; min-height: 0; padding: 0; border: 1.5px solid var(--ink); background: var(--paper); }
.intro .dots .dot.on { background: var(--ink); }
.intro .concept { border-left: 1.5px solid var(--rule); padding-left: 20px; }
.intro .concept h3 { margin: 0; font: 600 28px/1 var(--hand); }
.intro .concept .pic { display: block; width: 100%; max-width: 230px; margin: 8px auto 10px; }
.intro .concept ul { margin: 0; padding-left: 16px; }
.intro .concept li { margin: 0 0 6px; }
.intro .hoop { fill: none; stroke: var(--rule); stroke-width: 1.5; transition: stroke var(--fade); }
.intro .iring .band, .intro .mini .lamps .band { fill: none; opacity: 1; }
.intro .iring .mark { stroke: var(--paper); stroke-opacity: .5; stroke-width: .8; }
.intro .iring .mark.beat { stroke-width: 1.6; }
.intro .iring .hit { fill: #f5edd9; transition: fill var(--fade); }
.intro .iring .rest { fill: #4b4438; }
.intro .iring .hit.lit, .intro .iring .hit.now { fill: #fff; filter: drop-shadow(0 0 2px #fff); transition: none; }
.intro .iring .rest.now { fill: var(--paper); }
.intro .iring .slice { font: 700 7px var(--ui); fill: var(--grey); text-anchor: middle; }
.intro .ihand, .intro .spun, .intro .carry, .intro .cursor { transform-box: view-box; transform-origin: 0 0; }
.intro .ihand { transition: transform var(--tick) linear; }
.intro .ihand path { fill: var(--ink); }
.intro .spun { transition: transform var(--rotate) var(--mech); }
.intro .cursor path { fill: var(--ink); stroke: var(--paper); stroke-width: 1; }
.intro .cursor.press path { fill: var(--red); }
/* 1: the browser's own tiles, three to choose from */
.intro .picks { display: flex; gap: 28px; align-items: flex-start; }
.intro .sound.tile { width: 132px; cursor: pointer; touch-action: auto; }
.intro .sound.tile .name { font: 700 13px var(--ui); }
.intro .sound.tile .how { font-size: 12px; color: var(--grey); text-align: center; }
.intro .sound.tile:hover .disc { outline: 1.5px solid var(--rule); outline-offset: 3px; }
.intro .sound.tile.chosen .disc { outline: 2px solid var(--ink); outline-offset: 3px; }
/* the rows of choices, the play button, the key roll */
.intro .scene.col { flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 10px; }
.intro .scene .row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.intro .scene .row .label { width: 62px; font: 700 10px var(--ui); text-transform: uppercase; letter-spacing: .06em; color: var(--grey); }
.intro .arpedit { display: flex; flex-direction: column; gap: 6px; }
.intro .arpedit .row:first-child { position: relative; padding-right: 50px; }
.intro .arpedit .row:first-child button.hear { position: absolute; right: 0; }
.intro .choices { display: flex; gap: 6px; flex-wrap: wrap; }
.intro .choices button { padding: 3px 9px; font-size: 12px; }
.intro .choices button.on { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.intro button.hear { display: inline-flex; align-items: center; justify-content: center; width: 40px; }
.intro button.hear .icon { width: 14px; height: 14px; }
.intro .rollhost .keyroll { width: 100%; }
.intro .scene .side { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.intro .words .told { color: var(--red); }
/* 2: lifted off the left, carried over the circle, grown to its place and landed, once a round */
.intro .drag .side { fill: var(--paper); stroke: var(--rule); stroke-width: 1.5; }
.intro .drag .from { opacity: .3; }
.intro .drag .hoop { animation: intro-over var(--intro) linear infinite; }
.intro .drag .carry { animation: intro-carry var(--intro) var(--mech) infinite; }
.intro .drag .cursor { animation: intro-hand var(--intro) var(--mech) infinite; }
@keyframes intro-carry {
  0%, 10% { transform: translate(-122px, var(--y0)) scale(1); opacity: 0; }
  14% { transform: translate(-122px, var(--y0)) scale(1); opacity: 1; }
  20% { transform: translate(-118px, calc(var(--y0) - 5px)) scale(1.15); }
  52% { transform: translate(70px, -5px) scale(1.15); }
  66%, 88% { transform: translate(70px, 0) scale(3.85); opacity: 1; }
  100% { transform: translate(70px, 0) scale(3.85); opacity: 0; }
}
@keyframes intro-hand {
  0% { transform: translate(-100px, calc(var(--y0) + 12px)); opacity: 0; }
  8%, 14% { transform: translate(-110px, calc(var(--y0) + 8px)); opacity: 1; }
  20% { transform: translate(-106px, calc(var(--y0) + 3px)); }
  52% { transform: translate(82px, 3px); opacity: 1; }
  62%, 100% { transform: translate(110px, 40px); opacity: 0; }
}
@keyframes intro-over { 0%, 40% { stroke: var(--rule); stroke-dasharray: none; } 44%, 60% { stroke: var(--red); stroke-dasharray: 5 4; } 64%, 100% { stroke: var(--rule); stroke-dasharray: none; } }
/* 3: a click on a step switches it; the pointer beckons until the first */
.intro .edit .cell { fill: transparent; cursor: pointer; }
.intro .edit .cell:hover { fill: rgb(255 255 255 / .16); }
.intro .ihand.live { transition: none; }
.intro .cursor.beckon { pointer-events: none; }
.intro .cursor.beckon path { animation: intro-press var(--intro) steps(1) infinite; }
@keyframes intro-press { 0%, 70% { fill: var(--ink); } 75%, 90% { fill: var(--red); } }
/* 4: one script in the Moves tab's own blocks (blocks.css), the three spins over it and the ring it spins */
.intro .scene.moves { justify-content: space-between; }
.intro .scene.moves .pic { height: 260px; }
.intro .bl .ws { overflow: visible; padding: 0; }
.intro .bl .script { margin: 0; }
.intro .bl .blk { cursor: default; }
.intro .bl .pill::after { content: none; }
.intro .count { font: 600 18px var(--hand); color: var(--grey); min-height: 1.2em; }
/* 5: the ring made, into the song or the tab alone */
.intro .sound.tile.made { width: 150px; }
.intro .scene button.go { display: inline-flex; align-items: center; gap: 8px; padding: 10px 18px; font-size: 14px; }
.intro .scene button.go .icon { width: 18px; height: 18px; stroke: var(--paper); }
/* the fix list: what the lights say, how much may change, then Claude's changes, each ticked with a button to hear it */
/* the computer (computer.js, #137), the editor's second tab (#171): the scripts on the left, the blocks in the middle, the
   script being edited on the right. A script is a when block (a hat) with its action blocks clipped under it by a notch,
   each action in its light colour; square corners throughout */
.computer { display: flex; flex-direction: column; gap: 14px; position: relative; }
.computer h3 { margin: 0 0 6px; font: 700 10px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.computer .panes { display: grid; grid-template-columns: 230px 1fr; gap: 22px; min-height: min(64vh, 700px); }
/* the blocks to drag from only when asked for (#285); G always has them */
.computer .panes.blocks { grid-template-columns: 230px 190px 1fr; }
.computer .scripts { display: grid; gap: 2px; align-content: start; border-right: 1.5px solid var(--rule); padding-right: 14px; }
.computer .scripts .line { display: flex; align-items: stretch; border: 1.5px solid transparent; }
.computer .scripts .line.on { border-color: var(--ink); }
.computer .scripts .line.empty .go { color: var(--grey); }
.editor .computer .scripts button { border: 0; background: none; min-height: 30px; padding: 3px 6px; font: 600 11px var(--ui); color: var(--ink); text-align: left; }
.editor .computer .scripts button.go { flex: 1; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.editor .computer .scripts button.del { color: var(--grey); padding: 3px 8px; }
.editor .computer .scripts button.del:hover { color: var(--red); }
.computer .scripts .act { display: inline-flex; padding: 1px; background: color-mix(in srgb, var(--k) 42%, var(--paper)); border: 1.5px solid color-mix(in srgb, var(--k) 45%, var(--ink)); }
.computer .scripts .act.idle { opacity: .45; }
.computer .scripts .act svg { width: 16px; height: 16px; }
.computer .scripts .go > svg { width: 20px; height: 20px; }
.editor .computer .scripts button.new { justify-self: start; margin-top: 8px; font-weight: 500; color: var(--grey); border: 1.5px dashed var(--rule); }
.editor .computer .scripts button.new:hover { color: var(--ink); border-color: var(--ink); }
.editor .computer .scripts button.blocks { justify-self: start; margin-top: 4px; font-weight: 500; color: var(--grey); }
.editor .computer .scripts button.blocks.on { color: var(--ink); }
.computer .palette { display: grid; gap: 8px; align-content: start; justify-items: start; }
.computer .palette h3:not(:first-child) { margin-top: 8px; }
.computer .program { display: grid; align-content: start; border-left: 1.5px solid var(--rule); padding-left: 18px; }
.computer .scripts.over, .computer .program.over { background: var(--wash); }
.computer .script { --k: var(--grey); display: grid; justify-items: start; }
.computer .block { --k: var(--hat, #c9c3b3); display: inline-flex; align-items: center; gap: 6px; font: 600 12px var(--ui); color: var(--ink); padding: 5px 9px; min-height: 30px; box-sizing: border-box;
  background: color-mix(in srgb, var(--k) 42%, var(--paper)); border: 1.5px solid color-mix(in srgb, var(--k) 45%, var(--ink)); position: relative; }
.computer .block.drag { cursor: grab; user-select: none; }
.computer .block.drag:hover { border-color: var(--ink); }
.computer .block .hole { width: 18px; height: 18px; border: 1.5px dashed color-mix(in srgb, var(--k) 45%, var(--ink)); border-radius: 50%; box-sizing: border-box; }
/* a whole container's hole is square, as containers are on a switch's far end; never class box, the stage's (#285) */
.computer .block .hole.whole { border-radius: 0; }
.computer .block.when { border-top-width: 5px; }
/* a hat, and its line in the list, as its event fires (#214): lit, then fading over a few --fade */
.computer .block.when.lit, .computer .scripts .line.lit .go { animation: hat-lit calc(var(--fade) * 3) ease-out; }
@keyframes hat-lit { from { background: color-mix(in srgb, var(--ochre) 60%, var(--paper)); } }
.computer .block.when > span:first-child { font-weight: 700; text-transform: uppercase; font-size: 10px; letter-spacing: .06em; }
/* an action hangs under the block above it, its notch in the gap */
.computer .script .block.then { margin: -1.5px 0 0 14px; }
.computer .block.then::before { content: ''; position: absolute; left: 10px; top: -1.5px; width: 14px; height: 4px; background: color-mix(in srgb, var(--k) 42%, var(--paper));
  border: 1.5px solid color-mix(in srgb, var(--k) 45%, var(--ink)); border-top: 0; transform: translateY(-100%) scaleY(-1); transform-origin: bottom; }
.computer .palette .block.then::before { display: none; }
/* a condition (#151), Scratch's "if" in its own colour: it sits flush under the hat, the actions hang under it */
.computer .block.only { --k: #a993cf; }
/* a state (#153): its letter on the state light's colour, square, for a set and for the scripts waiting on one */
.state { display: inline-flex; align-items: center; justify-content: center; flex: none; min-width: 18px; height: 18px; padding: 0 3px;
  background: #21d0c3; color: #1c1916; font: 700 11px/1 var(--ui); }
.computer .scripts .act .state { height: 16px; min-width: 16px; }
/* the sections side by side (#168): the one picked lit in the sections' colour */
.computer .sections { display: inline-flex; gap: 2px; }
.editor .computer .sections button.section { min-width: 20px; min-height: 0; height: 20px; padding: 0 4px; font: 700 11px/1 var(--ui);
  border: 1.5px solid color-mix(in srgb, var(--ink) 35%, transparent); background: var(--paper); color: var(--grey); }
.editor .computer .sections button.section.on { background: #21d0c3; color: #1c1916; border-color: #1c1916; }
.editor .computer .sections button.section.gone { border-style: dashed; text-decoration: line-through; }
.computer .script .about { margin: 8px 0 0 14px; max-width: 34em; font: 500 11px/1.4 var(--ui); color: var(--grey); }
.computer .script .block.only { margin-top: -1.5px; border-left-width: 5px; }
/* a C-block (#170), Scratch's if in our ink: its conditions across the top, an arm down the left, the actions it holds in
   its mouth, an else and its mouth under that (#330, always open), a foot. Several under one hat are independent ifs,
   each judged on its own. The one picked has ink edges */
.computer .c { --k: #a993cf; --fill: color-mix(in srgb, var(--k) 42%, var(--paper)); --edge: color-mix(in srgb, var(--k) 45%, var(--ink));
  display: grid; justify-items: start; margin: 6px 0 0 14px; cursor: grab; }
.computer .c > .block.only { border-left-width: 1.5px; }
.computer .c > .block.only + .block.only { border-top-style: dashed; }
.computer .c > .mouth { display: grid; justify-items: start; min-height: 30px; margin-top: -1.5px; padding: 0 0 6px 14px; box-sizing: border-box;
  background: linear-gradient(90deg, var(--edge) 0 1.5px, var(--fill) 1.5px 12.5px, var(--edge) 12.5px 14px) 0 0 / 14px 100% no-repeat; }
.computer .c .mouth > .block.then { margin: -1.5px 0 0; }
/* inside a C-block the actions sit flush, no notch; the first C-block sits flush under the hat when nothing is above it (#250) */
.computer .c .mouth > .block.then::before { display: none; }
.computer .c.flush { margin-top: -1.5px; }
.computer .c .mouth > .zone { margin: 6px 0 0 0; }
.computer .c > .block.only.else { min-width: 96px; margin-top: -1.5px; }
.computer .c.on > .block.only.else { border-color: var(--ink); }
.computer .c > .foot { width: 96px; height: 14px; margin-top: -1.5px; background: var(--fill); border: 1.5px solid var(--edge); box-sizing: border-box; }
.computer .c.on > .block.only, .computer .c.on > .foot { border-color: var(--ink); }
.computer .c.on > .mouth { --edge: var(--ink); }
/* a C-block's lamp (#249), to the right of its conditions: dark until an event comes, then green let through or red held
   back, fading as a hat's light does */
.computer .c .gate { position: absolute; left: calc(100% + 7px); top: 50%; width: 10px; height: 10px; margin-top: -5px; border-radius: 50%;
  border: 1.5px solid var(--edge); background: var(--paper); box-sizing: border-box; }
.computer .c .gate.lit.pass { animation: gate-pass calc(var(--fade) * 3) ease-out; }
.computer .c .gate.lit.held { animation: gate-held calc(var(--fade) * 3) ease-out; }
@keyframes gate-pass { from { background: var(--moss); border-color: var(--ink); } }
@keyframes gate-held { from { background: var(--red); border-color: var(--ink); } }
.computer .c.over > .mouth, .computer .zone.over { background-color: var(--wash); }
.computer .program .block.then { cursor: grab; }
/* The drop point between actions (#274), painted without moving their controls. */
.computer .program .block.then.drop-before { box-shadow: 0 -3px 0 var(--ink); }
.computer .program .block.then.drop-after { box-shadow: 0 3px 0 var(--ink); }
.computer .lifted { opacity: .4; }
.computer .palette.over { background: var(--wash); }
.computer .palette .block.only { border-left-width: 8px; }
.computer .block.when.blank { border-style: dashed; background: none; }
/* the builder's menus (#285): a dashed select is a slot still to fill, the way the zone it sits in is */
.computer select.add, .computer select.on, .computer select.only-when, .computer select.and { font-weight: 500; color: var(--grey); border-style: dashed; }
.computer select.add:hover, .computer select.on:hover, .computer select.only-when:hover, .computer select.and:hover { color: var(--ink); }
.computer select.only-when { display: block; margin: 8px 0 0 14px; }
.computer .zone select.add { border: 0; padding: 0; min-height: 0; background: none; width: 100%; }
.computer .scripts .line.blank .go { color: var(--grey); font-style: italic; }
.editor .computer .block.only button.loop { min-width: 22px; min-height: 0; padding: 1px 4px; font: 700 11px var(--ui); font-variant-numeric: tabular-nums;
  border: 1.5px solid color-mix(in srgb, var(--k) 45%, var(--ink)); background: var(--paper); color: var(--grey); }
.editor .computer .block.only button.loop.on { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.computer .scripts .only { font: 700 10px var(--ui); color: var(--grey); font-variant-numeric: tabular-nums; }
.computer .block.idle, .computer .script.idle { opacity: .45; }
.computer .block select { font: inherit; color: inherit; background: none; border: 0; border-bottom: 1.5px dashed currentColor; padding: 0 2px; cursor: pointer; }
/* the ramp pill (#332): at once reads quiet, a length reads as part of the sentence, its unit a click to swap */
.pill.ramp { display: inline-flex; align-items: baseline; gap: 3px; margin-left: 4px; }
.pill.ramp:not(.on) select { opacity: .55; }
.pill.ramp button.in { font: inherit; color: inherit; background: none; border: 0; border-bottom: 1.5px dashed currentColor; padding: 0 2px; min-height: 0; cursor: pointer; }
.editor .computer .block button.ref { padding: 1px; min-height: 0; border: 1.5px solid transparent; background: color-mix(in srgb, var(--paper) 70%, transparent); display: inline-flex; }
.editor .computer .block button.ref:hover { border-color: var(--ink); }
.editor .computer .block button.del { padding: 0 2px 0 6px; min-height: 0; border: 0; background: none; color: var(--grey); font: 600 13px var(--ui); }
.editor .computer .block button.del:hover { color: var(--red); }
.editor .computer .block button.dup { padding: 0 0 0 6px; min-height: 0; border: 0; background: none; color: var(--grey); display: inline-flex; align-items: center; }
.editor .computer .block button.dup .icon { width: 12px; height: 12px; stroke: currentColor; }
.editor .computer .block button.dup:hover { color: var(--ink); }
.place.empty { background: none; color: var(--grey); box-shadow: inset 0 0 0 1.5px var(--rule); }
.computer .zone { margin: 8px 0 0 14px; font: 500 12px var(--ui); color: var(--grey); border: 1.5px dashed var(--rule); padding: 5px 9px; min-height: 30px; box-sizing: border-box; display: flex; align-items: center; }
.computer .program > .zone { margin-left: 0; }
/* the visual dropdown for a ring: places, then rings */
.computer .ref-menu { position: absolute; z-index: 5; background: var(--paper); border: 1.5px solid var(--ink); padding: 6px 8px; box-shadow: 0 6px 18px rgba(0,0,0,.12); }
.computer .ref-menu h4 { margin: 2px 0 4px; font: 700 9px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.computer .ref-menu .opts { display: flex; gap: 2px; margin-bottom: 4px; }
.editor .computer .ref-menu button.opt { padding: 2px; min-height: 0; border: 1.5px solid transparent; background: none; display: inline-flex; }
.editor .computer .ref-menu button.opt:hover:not(:disabled) { border-color: var(--rule); }
.editor .computer .ref-menu button.opt.on { border-color: var(--ink); }
.editor .computer .ref-menu button.opt:disabled, .editor .computer .ref-menu button.opt.off { opacity: .25; cursor: not-allowed; }
/* an action made before the reach rule (#257): it plays, a dashed red edge says it breaks it */
.computer .block.then.against { outline: 1.5px dashed var(--red); outline-offset: 1px; }
.computer .ref-menu svg { width: 24px; height: 24px; }
/* a switch's far end (#169): a ring in another container, or a whole container, with that container's number */
.far { position: relative; display: inline-flex; vertical-align: middle; }
.far .mini { width: 20px; height: 20px; }
.far.box { align-items: center; gap: 4px; }
.far .c { width: 22px; height: 22px; flex: none; display: grid; place-items: center; border: 1.5px solid var(--ink); font: 700 12px/1 var(--ui); color: var(--ink); background: var(--paper); }
.far.box i { position: static; padding: 0; background: none; font: 700 12px var(--ui); font-style: normal; white-space: nowrap; max-width: 14ch; overflow: hidden; text-overflow: ellipsis; }
.far i { position: absolute; right: -4px; bottom: -3px; padding: 0 1px; font: 700 8px/9px var(--ui); font-style: normal; color: var(--ink); background: var(--paper); font-variant-numeric: tabular-nums; }
/* a place (#147): its number on a chip of the place's own colour, never the ring's; a ring itself as its arc */
.computer .ring-pic { width: 22px; height: 22px; flex: none; overflow: visible; }
.place { display: inline-flex; align-items: center; justify-content: center; flex: none; min-width: 26px; height: 18px; padding: 0 3px;
  background: var(--c, var(--grey)); color: var(--paper); font: 700 10px/1 var(--ui); letter-spacing: .02em; font-variant-numeric: tabular-nums; }
.tool.program.set .icon { stroke: var(--ink); }
.panel button.computer { padding: 3px 9px 3px 7px; border-left: 4px solid var(--k, var(--rule)); }
.modal.fix { width: min(560px, 92vw); }
.modal.songs { width: min(560px, 92vw); }
.modal.songs .keep { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.modal.songs input[type=text] { font: 600 13px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); padding: 4px 8px; min-height: 30px; border-radius: 0; }
.modal.songs input[type=text]:focus { outline: none; border-color: var(--ink); }
.modal.songs ol { list-style: none; margin: 0; padding: 0; display: grid; }
.modal.songs li { display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: center; padding: 6px 0; border-top: 1px solid var(--rule); }
.modal.songs li.now b { text-decoration: underline; text-decoration-color: var(--red); }
.modal.songs .minis { display: flex; gap: 2px; min-width: 24px; }
.modal.songs .minis .mini { width: 22px; height: 22px; }
.modal.songs .when { color: var(--grey); font: 500 11px var(--ui); }
.modal.songs .none { color: var(--grey); font: 500 13px var(--ui); margin: 0; }
.modal.fix .lights { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font: 500 13px/1.35 var(--ui); }
.modal.fix .lights li { display: flex; gap: 8px; align-items: baseline; }
.modal.fix .lights .light { position: relative; top: 1px; }
.modal.fix .levels { display: flex; }
.modal.fix .levels button + button { margin-left: -1.5px; }
.modal.fix .levels button.on { background: var(--ink); color: var(--paper); border-color: var(--ink); position: relative; }
.modal.fix .about, .modal.fix .state { margin: 0; font: 500 12px/1.4 var(--ui); color: var(--grey); }
.modal.fix .state:empty { display: none; }
.modal.fix button.ask { justify-self: start; align-self: flex-start; border-color: var(--ink); }
.modal.fix button:disabled { opacity: .35; cursor: default; }
.modal.fix .changes { display: grid; gap: 8px; }
.modal.fix .changes:empty { display: none; }
.modal.fix .change { display: grid; grid-template-columns: auto 1fr auto; gap: 10px; align-items: start; padding: 8px 0; border-top: 1.5px solid var(--rule); }
.modal.fix .change input { margin: 2px 0 0; accent-color: var(--ink); }
.modal.fix .change .text { display: grid; gap: 2px; font: 500 13px/1.35 var(--ui); }
.modal.fix .change .text span { color: var(--grey); }
/* the cards (#181): a hand of three, each a move, why, the idea, and the ways to take it at its foot */
.modal.cards { width: min(1100px, 96vw); max-width: 96vw; }
/* a cat's hand is its speech bubble (#208): rounded, with a tail down towards the cats */
.said-hold { position: relative; }
.modal.cards.said { border-radius: 22px; }
.said-hold .tail { position: absolute; left: 70px; bottom: -20px; width: 26px; height: 22px; background: var(--paper);
  border-left: 2px solid var(--ink); border-bottom: 2px solid var(--ink); transform: skewX(40deg); transform-origin: top left; }
.said-hold .tail::before { content: ""; position: absolute; left: -2px; right: 0; top: -2px; height: 4px; background: var(--paper); }
.modal.cards .who { display: flex; align-items: center; gap: 10px; margin: -4px 0 10px; }
.modal.cards .who .cat-art { width: 44px; height: 62px; flex: none; }
.modal.cards .who p { margin: 0; font: 600 18px/1.2 var(--hand); }
.modal-back:has(.modal.cards) { backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); background: rgb(251 244 228 / .6); }
.modal.cards .table { display: grid; grid-template-columns: 1fr 210px; gap: 16px; align-items: start; }
.modal.cards .side { display: grid; gap: 10px; justify-items: center; position: sticky; top: 0; }
.modal.cards .shown { display: grid; width: 200px; gap: 8px; }
.modal.cards .shown.two { grid-template-columns: 1fr 1fr; }
.modal.cards .pic { margin: 0; display: grid; gap: 4px; justify-items: center; }
.modal.cards .pic figcaption { font: 700 10px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.modal.cards .disc { width: 100%; height: auto; aspect-ratio: 1; overflow: visible; }
.modal.cards .disc .hand { stroke: var(--ink); stroke-width: 1.2; stroke-linecap: round; display: none; }
.modal.cards .foot { margin-top: 14px; padding-top: 10px; border-top: 1.5px solid var(--rule); }
.modal.cards .foot .key { margin: 0 0 6px; font: 500 12px/1.35 var(--ui); color: var(--grey); }
.modal.cards .bars { display: block; width: 100%; height: auto; overflow: visible; }
.modal.cards .bars .bar { fill: none; }
.modal.cards .bars .bar.changed { fill: var(--red); opacity: .2; }
.modal.cards .bars .n { font: 600 9px var(--ui); fill: var(--grey); }
.modal.cards .bars .barline { stroke: var(--ink); stroke-width: 1; }
.modal.cards .bars .beat { stroke: var(--ink); stroke-width: .6; opacity: .55; }
.modal.cards .bars .eighth { stroke: var(--rule); stroke-width: .9; }
.modal.cards .bars .sixteenth, .modal.cards .bars .lane { stroke: var(--rule); stroke-width: .6; }
.modal.cards .bars .tick { stroke: var(--rule); stroke-width: .4; stroke-dasharray: 2 3; }
.modal.cards .bars .is.new { stroke: var(--ink); stroke-width: .6; }
/* what a pick changes, plain (#255): a hit it brings in flashes as it comes, one it takes out keeps a red outline */
.modal.cards .bars .is.fresh { animation: came var(--flash) ease-out; }
.modal.cards .bars .was.gone { stroke: var(--red); stroke-width: .9; }
@keyframes came { from { stroke: var(--ink); stroke-width: 3; } }
.modal.cards .bars .head { stroke: var(--ink); stroke-width: 1.6; display: none; }
.modal.cards .disc .plate { fill: none; stroke: var(--rule); stroke-width: 1; }
.modal.cards .disc .band { fill: none; stroke: var(--c); stroke-width: 5; stroke-linecap: round; opacity: .55; }
.modal.cards .disc .changed .band { stroke-width: 7.5; opacity: 1; }
.modal.cards .disc .lamp { fill: var(--paper); stroke: var(--ink); stroke-width: .8; }
.modal.cards .disc .rest { fill: var(--ink); opacity: .45; }
.modal.cards .disc .muted .band { stroke-dasharray: 3 3; }
.modal.cards .side .note { margin: 0; font: 500 12px/1.35 var(--ui); color: var(--grey); text-align: center; }
.modal.cards .reading { margin: 0; font: 500 12px/1.4 var(--ui); color: var(--grey); }
.modal.cards .dealt { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.modal.cards .card { --c: var(--ink); display: flex; flex-direction: column; gap: 6px; min-height: 290px; padding: 10px 12px 12px; border: 1.5px solid var(--ink); border-top: 7px solid var(--c); background: var(--paper); }
.modal.cards .top { display: flex; justify-content: space-between; align-items: center; min-height: 34px; }
.modal.cards .mark { font: 700 22px/1 var(--ui); color: var(--c); }
.modal.cards .top .glyph { width: 34px; height: 34px; overflow: visible; }
.modal.cards .top .rings { display: flex; gap: 4px; }
.modal.cards .who { margin: -2px 0 0; font: 600 11px/1.3 var(--ui); color: var(--c); text-transform: lowercase; }
.modal.cards .title { font: 700 14px/1.25 var(--ui); }
.modal.cards .why { margin: 0; font: 500 13px/1.35 var(--ui); }
.modal.cards .idea { margin: 0; font: 500 12px/1.4 var(--ui); color: var(--grey); }
.modal.cards .choices { margin-top: auto; display: grid; gap: 6px; padding-top: 8px; border-top: 1.5px solid var(--rule); }
.modal.cards .choice { display: flex; align-items: center; gap: 8px; width: 100%; padding: 4px 6px; text-align: left; }
.modal.cards .choice .tick { width: 16px; height: 16px; flex: none; display: inline-flex; align-items: center; justify-content: center; border: 1.5px solid var(--ink); background: var(--paper); }
.modal.cards .choice .tick .icon { width: 11px; height: 11px; visibility: hidden; }
.modal.cards .choice.on { border-color: var(--c); box-shadow: inset 4px 0 0 var(--c); }
.modal.cards .choice.on .tick { background: var(--ink); color: var(--paper); }
.modal.cards .choice.on .tick .icon { visibility: visible; }
.modal.cards .choice .label { flex: 1; font: 600 12px/1.25 var(--ui); }
.modal.cards .none { margin: 0; color: var(--grey); }
.modal.cards .asking { margin: -4px 0 0; font: 500 12px/1.4 var(--ui); color: var(--grey); }
.modal.cards .asking.err { color: var(--red); }
.modal.cards .asking[hidden] { display: none; }
.modal.cards .concern { font: 700 10px/1 var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--paper); background: var(--c); padding: 4px 6px; }
.modal.cards .genre { margin: -4px 0 0; font: 600 11px/1.3 var(--ui); color: var(--grey); }

/* the preview control, everywhere a change is offered: play from the top, A/B in time, stop. A is as it was, B with
   the change; the one sounding is filled. A/B and stop wake up while this one is being heard */
.preview { display: inline-flex; align-items: stretch; }
.preview button { min-width: 28px; min-height: 26px; padding: 2px 6px; display: inline-flex; align-items: center; justify-content: center; }
.preview button + button { margin-left: -1.5px; }
.preview button .icon { width: 13px; height: 13px; }
.preview.on .play { border-color: var(--ink); }
.preview .ab { gap: 0; padding: 0; }
.preview .ab b { font: 700 11px var(--ui); width: 17px; line-height: 22px; text-align: center; color: var(--grey); }
.preview.on .ab b.a, .preview.on.with .ab b.b { color: var(--ink); }
.preview.on:not(.with) .ab b.a, .preview.on.with .ab b.b { background: var(--ink); color: var(--paper); }
.preview button:disabled { opacity: .3; cursor: default; }
.preview.one .play { gap: 6px; padding: 2px 10px; font: 600 12px var(--ui); }
.preview.one.on .play { background: var(--moss); border-color: var(--moss); color: var(--paper); }
.panel .ideas { align-items: flex-start; }
.panel .ideas .list { display: grid; gap: 4px; }
.panel .ideas .idea { display: flex; gap: 5px; align-items: center; }
.panel .ideas .glyph { width: 26px; height: 26px; flex: none; overflow: visible; }
.glyph .track { fill: none; stroke: var(--rule); stroke-width: 1; }
.glyph .hit { fill: var(--c); }
.glyph .rest { fill: var(--rule); }
.panel .ideas button.keep { min-width: 28px; min-height: 26px; padding: 2px 6px; }

/* clears the row of five cats fixed at the bottom left (#208), 286 px wide */
.hint { position: relative; z-index: 2; margin: 0; padding: 10px 86px 14px 304px; font: 600 21px/1.1 var(--hand); color: var(--red); min-height: 1.1em; }

/* a ring in the hand: a hoop hanging by its top edge, in perspective (carry.js moves it) */
.carry3d { position: fixed; left: 0; top: 0; width: 0; height: 0; z-index: 10; pointer-events: none; display: none; perspective-origin: 0 0; }
.carry3d.show { display: block; }
.carry3d .solid { position: absolute; transform-origin: 50% 50%; transform-style: preserve-3d; }
.carry3d svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; overflow: visible; }
/* the slices behind are its sides now, and it isn't playing in the hand */
.carry3d .ring .wall, .carry3d .ring .chase { display: none; }
body.dragging, body.dragging * { cursor: grabbing !important; }

/* the side columns give way, never the stage (#313, #336). The log leaves the deck for the foot of the map's column,
   the map narrows with it. A third column cost two containers 123 px at every width until the stage meets the window's
   height, about 2.4 wide to 1 high with the cats' gutter on the right, so three columns only past that; the page is a 1400 column (#440), so
   past 1400 wide that is under 584 high; below 720 the stage goes first, full width and square, the map and log under it */
@media (max-width: 1100px), (max-aspect-ratio: 12/5), (min-height: 584px) {
  .room { grid-template-columns: minmax(180px, 24%) minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas: "side stage" "log stage" "log strip"; gap: 14px 20px; }
  .right, .deck { display: contents; }
  .side { grid-area: side; min-height: 0; padding-bottom: 0; }
  .log { grid-area: log; width: auto; }
  .stage { grid-area: stage; }
  .strip { grid-area: strip; }
  .top, .transport { flex-wrap: wrap; row-gap: 10px; }
  .top h1 { white-space: nowrap; }
}
@media (max-width: 720px) {
  .room { grid-template-columns: minmax(0, 1fr); grid-template-rows: repeat(4, max-content); grid-template-areas: "stage" "strip" "side" "log";
    overflow-y: auto; padding-bottom: 90px; }
  .stage { height: min(calc(100vw - 56px), calc(100vh - 160px)); }
  .side { overflow: visible; }
  .log { height: 200px; }
  .hint { padding-left: 28px; }
}

/* The pattern editor (#134): the page the pencil turns over to. Library left, a lane per ring in the middle, moves right */
.editor { position: fixed; left: max(0px, calc((100vw - 1400px) / 2)); right: max(0px, calc((100vw - 1400px) / 2)); bottom: 0; z-index: 3; display: none; grid-template: auto auto 1fr auto / 210px 1fr minmax(0, min(34vw, 476px, 56vh)); gap: 14px 22px; padding: 6px 28px 22px; background: var(--paper); }
body.editing .editor { display: grid; }
body.editing main.room { visibility: hidden; }
/* in the editor the cats keep dealing for the container open (#261) from where they used to sit, a row at the foot of
   the library, which keeps room for them; the editor has its whole width (#433) */
body.editing #cats { left: 18px; right: auto; top: auto; bottom: 6px; transform: none; flex-direction: row; align-items: flex-end; gap: 2px; }
body.editing .editor .log.line { padding-left: 276px; }
body.editing #cats .think { right: auto; left: 30px; bottom: 82px; }
body.editing #cats .think::before { right: auto; left: 6px; bottom: -14px; }
body.editing #cats .think::after { right: auto; left: -2px; bottom: -24px; }
.editor .head { grid-column: 1 / -1; display: flex; align-items: center; gap: 18px; border-bottom: 2px solid var(--ink); padding-bottom: 8px; }
.editor h2 { margin: 0; font: 700 11px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.editor h3 { margin: 12px 0 4px; font: 700 10px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.editor h3:first-child { margin-top: 0; }
.editor .pick { display: flex; gap: 6px; flex: 1; }
.editor .pick button { width: 34px; height: 34px; padding: 2px; border: 1.5px solid transparent; }
.editor .pick button.on { border-color: var(--ink); }
.editor .pick .box-name { align-self: center; margin-left: 10px; width: 16ch; padding: 2px 0; border: 0; border-bottom: 1px solid var(--rule); background: none; color: var(--ink); font: 700 14px var(--ui); outline: none; }
.editor .pick .box-name:focus { border-bottom-color: var(--ink); }
.editor .pick button:hover { border-color: var(--rule); }
.editor .mini { width: 100%; height: 100%; display: block; }
.editor .close { width: 30px; height: 30px; border: 1.5px solid var(--ink); display: grid; place-items: center; font: 400 20px/1 var(--ui); }
.editor .close:hover { background: var(--ink); color: var(--paper); }
/* the foot clears the cats standing over it (74px and 6 below), so the last pattern scrolls up to be picked */
.editor .lib { overflow-y: auto; min-height: 0; padding-bottom: 88px; }
.editor .item { display: flex; align-items: stretch; }
.editor .load { flex: 1; display: grid; grid-template-columns: 1fr 70px; align-items: center; gap: 8px; padding: 3px 4px; text-align: left; font: 500 12px var(--ui); cursor: grab; touch-action: none; }
.editor .thumb .place { fill: var(--grey); }
.editor .how small { flex-basis: 100%; font: 500 11px var(--ui); color: var(--grey); }
/* how much of a library pattern goes on (#202, #227): a plain dropdown in steps */
.editor .sizes { display: flex; align-items: center; gap: 0; margin: 0 0 6px; }
.editor .sizes small, .editor .filter small { margin-right: 8px; font: 700 10px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.editor .filter { display: flex; align-items: center; margin: 0 0 6px; }
.editor .sizes .size, .editor .filter .pick { flex: 1; padding: 3px 5px; border: 1.5px solid var(--rule); border-radius: 0; background: var(--paper); color: var(--ink); font: 600 12px var(--ui); cursor: pointer; }
.editor .sizes .size:hover, .editor .sizes .size:focus, .editor .filter .pick:hover, .editor .filter .pick:focus { border-color: var(--ink); outline: none; }
/* a library pattern in the hand (#159): the lane under it outlined, dashed while Shift replaces */
body.dragging-pattern, body.dragging-pattern * { cursor: grabbing !important; }
.pattern-ghost { position: fixed; left: 0; top: 0; z-index: 50; pointer-events: none; display: flex; align-items: center; gap: 8px; padding: 4px 7px; background: var(--paper); border: 1.5px solid var(--ink); font: 600 12px var(--ui); }
.pattern-ghost .thumb { width: 70px; height: 9px; fill: var(--ink); }
.pattern-ghost b { font: 700 10px var(--ui); text-transform: uppercase; letter-spacing: .08em; color: var(--grey); }
.pattern-ghost.replace b { color: var(--red); }
.editor .lane.target { outline: 2px solid var(--ink); outline-offset: 4px; opacity: 1; }
.editor .lane.target.replace { outline-style: dashed; outline-color: var(--red); }
.editor .load:hover { background: var(--wash); }
.editor .thumb { width: 70px; height: 9px; fill: var(--ink); background: linear-gradient(var(--rule), var(--rule)) 0 100% / 100% 1px no-repeat; }
.editor .del { padding: 0 6px; color: var(--grey); }
.editor .del:hover { color: var(--red); }
.editor .swap { display: flex; align-items: center; gap: 6px; margin: 0 0 6px; cursor: pointer; }
.editor .swap input { width: 13px; height: 13px; margin: 0; accent-color: var(--ink); cursor: pointer; }
.editor .swap small { font: 700 10px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.editor .how { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin: 2px 0 6px; font: 500 11px var(--ui); color: var(--grey); }
.editor .tabs { display: inline-flex; border: 1.5px solid var(--ink); }
.editor .tabs button { padding: 4px 12px; font: 700 11px var(--ui); letter-spacing: .08em; text-transform: uppercase; color: var(--grey); }
.editor .tabs button:hover { color: var(--ink); }
.editor .tabs button.on { background: var(--ink); color: var(--paper); }
.editor .cpu { grid-column: 1 / -2; min-height: 0; overflow-y: auto; }
.editor .log.line { grid-column: 1 / -2; }
/* the container being edited, read only (#201): the stage's own drawing behind a diagonal hatch, no tools */
.editor .spin { grid-column: -2; grid-row: 2 / -1; position: relative; min-height: 0; }
/* on Patterns the lanes take the whole width, so every slot is wide enough to click, and the picture sits small in the
   corner below them */
.editor:not(.computing) .lib { grid-column: 1; grid-row: 3; }
.editor:not(.computing) .mid { grid-column: 2 / -1; grid-row: 3; }
.editor:not(.computing) .spin { position: absolute; right: 28px; bottom: 22px; width: min(20vw, 30vh); height: min(20vw, 30vh); }
/* a block aimed at in the script takes its ring from the picture (#248): the place under the pointer washed in ink, an
   empty one dashed */
.editor .spin.aiming { cursor: pointer; }
.editor .spin .aim-place { fill: none; stroke: var(--ink); stroke-opacity: .22; pointer-events: none; }
.editor .spin .aim-place.empty { stroke-opacity: .12; }
/* the ring a block under the pointer names (#259), flashing in its own colour over the picture */
.editor .spin .hint-place { fill: none; stroke: var(--paper); pointer-events: none; animation: hinted calc(var(--flash) / 2) ease-in-out infinite alternate; }
.editor .spin .hint-place.empty { stroke: var(--ink); }
@keyframes hinted { from { stroke-opacity: .65; } to { stroke-opacity: 0; } }
/* the block a click on the picture gives its ring to */
.computer .script .block.aim { outline: 2px solid var(--ink); outline-offset: 1px; }
.editor .spin .box { pointer-events: none; }
.editor .spin .tool, .editor .spin .toolbed, .editor .spin .layers, .editor .spin .shifts { display: none; }
.editor .spin::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(-45deg, transparent 0 7px, color-mix(in srgb, var(--ink) 7%, transparent) 7px 8px); }
.editor .computer .panes { min-height: 100%; }
.editor .lane.focus { opacity: 1; }
.editor .lane.focus .chip { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--ink); }
.editor .mid { position: relative; display: flex; flex-direction: column; gap: 10px; min-width: 0; overflow-y: auto; padding: 6px; margin: -6px; }
.stage > .wires { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 5; }
.stage > .wires path { stroke-width: 2.4; stroke-linecap: round; stroke-dasharray: 1 2; stroke-dashoffset: 1; }
.stage > .wires circle { stroke-width: 2; transform-box: fill-box; transform-origin: center; }
.editor .wires { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.editor .wire line { stroke-width: 2.4; stroke-linecap: round; stroke-dasharray: 1 2; stroke-dashoffset: 1; }
.editor .wire circle { stroke-width: 2; transform-box: fill-box; transform-origin: center; }
/* the lanes that already have the library pattern under the pointer (#174) */
.editor .lane.has { opacity: 1; }
.editor .lane.has .cells { animation: has calc(var(--fade) * 2) ease-in-out infinite alternate; }
@keyframes has { from { outline: 2px solid transparent; outline-offset: 3px; } to { outline: 2px solid var(--c); outline-offset: 3px; } }
.editor .lane { display: grid; grid-template-columns: auto auto auto auto auto auto 1fr auto; align-items: center; gap: 10px; opacity: .55; }
.editor .lane.on { opacity: 1; }
/* the headphones and mute columns (#205): grey when off, ink headphones listening, a red speaker muted */
.editor .lane .hear, .editor .lane .mute { display: flex; width: 22px; height: 22px; padding: 0; align-items: center; justify-content: center; border: 0; background: none; cursor: pointer; }
.editor .lane .hear .icon, .editor .lane .mute .icon { width: 16px; height: 16px; stroke: var(--grey); }
.editor .lane .hear.on .icon { stroke: var(--ink); }
.editor .lane .mute.on .icon { stroke: var(--red); }
/* a lane's own filter (#206): a short flat slider, ink once it closes at all */
.editor .lane .cut { width: 44px; height: 14px; margin: 0; appearance: none; -webkit-appearance: none; background: none; cursor: ew-resize; }
.editor .lane .cut::-webkit-slider-runnable-track { height: 2px; background: var(--rule); }
.editor .lane .cut::-webkit-slider-thumb { -webkit-appearance: none; width: 6px; height: 12px; margin-top: -5px; background: var(--grey); border: 0; }
.editor .lane .cut.on::-webkit-slider-thumb { background: var(--ink); }
.editor .lane .cut::-moz-range-track { height: 2px; background: var(--rule); }
.editor .lane .cut::-moz-range-thumb { width: 6px; height: 12px; background: var(--grey); border: 0; border-radius: 0; }
.editor .lane .cut.on::-moz-range-thumb { background: var(--ink); }
.editor .lane .hear:hover .icon, .editor .lane .mute:hover .icon { stroke: var(--ink); }
.editor .lane.muted .time { opacity: .4; }
.editor .lane.condensed .hear .icon, .editor .lane.condensed .mute .icon { width: 12px; height: 12px; }
.editor .chip { width: 86px; height: 26px; display: flex; align-items: center; gap: 6px; padding: 0 5px; background: var(--c); color: var(--paper); font: 600 11px var(--ui); }
.editor .chip .icon { width: 16px; height: 16px; flex: none; stroke: var(--paper); }
/* a lane's name and colour (#188): the name typed in place, the drum's icon opening the colours */
.editor .chip { width: 122px; }
.editor .chip .drum { display: flex; padding: 0; border: 0; background: none; cursor: pointer; }
.editor .chip .tint { flex: none; width: 12px; height: 12px; padding: 0; border: 1.5px solid var(--paper); background: conic-gradient(#C42B1C, #E0A21B, #2E8B3A, #1F4FC4, #7A3BB5, #C42B1C); cursor: pointer; }
.editor .chip .tint:hover, .editor .chip .drum:hover .icon { outline: 1px solid var(--paper); outline-offset: 1px; }
.editor .swatches.drums { grid-template-columns: repeat(2, auto); }
.editor .swatches .dr { display: flex; align-items: center; gap: 6px; padding: 3px 8px 3px 4px; border: 1.5px solid transparent; background: none; font: 600 11px var(--ui); color: var(--ink); cursor: pointer; }
.editor .swatches .dr .icon { width: 16px; height: 16px; stroke: var(--ink); }
.editor .swatches .dr:hover { border-color: var(--rule); }
.editor .swatches .dr.on { border-color: var(--ink); }
.editor .chip .name { flex: 1; width: 0; min-width: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-overflow: ellipsis; outline: none; cursor: text; }
.editor .chip .name:focus { box-shadow: inset 0 -1px 0 var(--paper); }
.editor .swatches { position: fixed; z-index: 30; display: grid; grid-template-columns: repeat(6, 22px); gap: 4px; padding: 6px; background: var(--paper); border: 1px solid var(--ink); }
.editor .swatches .sw { width: 22px; height: 22px; padding: 0; border: 0; cursor: pointer; }
.editor .swatches .sw.on { outline: 2px solid var(--ink); outline-offset: 1px; }
.editor .swatches .any { width: 22px; height: 22px; padding: 0; border: 1px solid var(--ink); background: none; cursor: pointer; }
.editor .swatches .reset { width: 22px; height: 22px; padding: 0; border: 1px solid var(--ink); background: var(--paper); font: 13px var(--ui); cursor: pointer; }
/* the lanes not ticked (#176): quiet while the page is open, so drawn small below the ticked ones */
.editor .lane.on + .lane.condensed { margin-top: 12px; }
.editor .lane.condensed .chip { height: 16px; }
.editor .lane.condensed .chip .icon { width: 11px; height: 11px; }
.editor .lane.condensed .cells { height: 14px; }
.editor .lane.condensed .len, .editor .lane.condensed .clear { visibility: hidden; }
.editor .s.drop { box-shadow: inset 0 0 0 2px var(--ink); }
/* a library pattern over a lane (#187): the slots its notes will fill flash with a diagonal hatch in the lane's colour,
   its start marked; replacing, the notes it takes away go faint */
.editor .cells .s.land { background: repeating-linear-gradient(-45deg, var(--c) 0 2px, var(--paper) 2px 5px); animation: land calc(var(--fade) * 2) ease-in-out infinite alternate; }
.editor .cells .s.start { box-shadow: inset 2px 0 0 var(--ink); }
.editor .s.gone { opacity: .25; }
@keyframes land { to { opacity: .35; } }
.editor .len { display: inline-flex; align-items: center; gap: 2px; font: 600 12px var(--ui); font-variant-numeric: tabular-nums; }
.editor .len b { width: 22px; text-align: center; }
.editor .len button { width: 18px; height: 22px; color: var(--grey); }
.editor .len button:hover { color: var(--ink); }
.editor .cells { display: grid; height: 38px; align-items: end; border-left: 1.5px solid var(--ink); }
.editor .time { display: flex; min-width: 0; }
/* a shorter ring's next loops to the end of the circle (#222): read-only and faded, a heavier line where each starts */
.editor .echo { display: grid; height: 38px; align-items: end; opacity: .32; pointer-events: none; }
.editor .echo .s.loop { border-left: 1.5px dashed var(--ink); }
.editor .lane.condensed .echo { height: 14px; }
.editor .s { height: 100%; background: var(--wash); box-shadow: inset 0 0 0 .5px var(--paper); }
.editor .s.q1, .editor .s.q2, .editor .s.q3 { height: 55%; background: rgb(43 33 24 / .045); }
.editor .s.q0 { border-left: 1px solid var(--rule); }
.editor .s.beat { border-left: 1.5px solid var(--ink); }
.editor .s.hit { background: var(--c); box-shadow: inset 0 0 0 .5px var(--paper); }
.editor .s.cond.hit { background: linear-gradient(to top, var(--c) 50%, var(--wash) 50%); }
/* a ghost hit (#91): filled to its loudness, like a velocity bar */
.editor .s.ghost.hit { background: linear-gradient(to top, var(--c) var(--vel, 40%), var(--wash) var(--vel, 40%)); }
/* the velocity lane (#331): under the time column, a bar per hit as tall as it is played */
.editor .lane .vels { grid-column: 7 / 8; display: flex; height: 12px; margin-top: -8px; }
.editor .lane.condensed .vels { display: none; }
.editor .vels .bars { display: grid; height: 100%; align-items: end; border-left: 1.5px solid var(--ink); cursor: ns-resize; }
.editor .vels .v { height: 100%; }
.editor .vels .v.on { height: var(--vel, 100%); margin-right: 75%; background: var(--c); min-height: 1px; }
/* the key roll (keyroll.js, #466): the keys down the left, named, a row a semitone, a column a place; held notes solid
   over their hold, an arp's notes hatched in an outline over the chord, the chord then a line under them; the playhead
   and the notes under it lit */
.keyroll { display: flex; position: relative; }
.modal.arps .keyroll { --c: var(--red); }
.keyroll .keyside { position: relative; flex: none; width: 34px; height: 100%; border: 1.5px solid var(--ink); border-right: 0; background: var(--paper); }
.keyroll .key { position: absolute; left: 0; right: 0; margin: 0; display: flex; align-items: center; justify-content: flex-end; padding-right: 3px; box-sizing: border-box; border-bottom: 1px solid var(--rule); cursor: pointer; }
.keyroll .key.black { left: 0; right: 10px; background: var(--ink); border-bottom-color: var(--ink); }
.keyroll .key.c { border-bottom-color: var(--grey); }
.keyroll .key b { font: 600 9px/1 var(--ui); font-variant-numeric: tabular-nums; color: var(--grey); pointer-events: none; }
.keyroll .key.black b { color: #a9a59b; }
.keyroll .key.sounds b { color: var(--ink); } .keyroll .key.black.sounds b { color: var(--paper); }
.keyroll .key.now { background: var(--c); } .keyroll .key.now b { color: var(--paper); }
.keyroll .key:hover { box-shadow: inset 0 0 0 1.5px var(--ink); }
.keyroll .roll { position: relative; display: grid; flex: 1; min-width: 0; height: 100%; border: 1.5px solid var(--ink); cursor: pointer; background: var(--paper); }
.keyroll .k { border-bottom: 1px solid #e4e1d8; }
.keyroll .k.black { background: #ebe8df; }
.keyroll .k.c { border-bottom-color: var(--grey); }
.keyroll .k.hit { box-shadow: inset 1px 0 0 var(--grey); }
.keyroll .k:hover { box-shadow: inset 0 0 0 1.5px var(--ink); }
.keyroll .notes { position: absolute; inset: 0; pointer-events: none; }
.keyroll .n { position: absolute; box-sizing: border-box; }
.keyroll .n.held { background: var(--c); box-shadow: inset 0 0 0 .5px var(--paper); }
.keyroll .n.held.root { background: color-mix(in srgb, var(--c) 35%, transparent); }
.keyroll .n.held.under { background: none; box-shadow: none; border-bottom: 2px solid color-mix(in srgb, var(--c) 55%, transparent); }
.keyroll .n.arp { background: repeating-linear-gradient(-45deg, var(--c) 0 1.5px, transparent 1.5px 4px); border: 1.5px solid var(--c); }
.keyroll .n.now { background: var(--c); border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.keyroll .n.under.now { background: none; }
.keyroll .head { position: absolute; top: 0; bottom: 0; width: 1.5px; margin-left: -.75px; background: var(--ink); }
/* on a keyboard ring's lane (#469) the roll is the lane: its keys in the length column, the roll on the one time grid */
.editor .lane.kb .keyroll { grid-column: 6 / 8; display: grid; grid-template-columns: subgrid; margin: 0 0 4px; }
.editor .lane.kb .keyroll .keyside { justify-self: end; width: 34px; }
.editor .lane.kb .keyroll .roll { justify-self: start; }
.editor .lane.kb .time { align-self: center; }
.editor .lane.condensed .keyroll { height: 22px !important; }
.editor .lane.condensed .keyroll .keyside, .editor .lane.condensed .arp { visibility: hidden; }
.editor .lane.refuse { outline: 2px dashed var(--grey); outline-offset: 4px; opacity: 1; }
.editor .lane .arp { display: flex; gap: 4px; align-items: center; }
.editor .lane .arp select { flex: 0 0 auto; width: auto; max-width: 220px; height: 22px; font: inherit; font-size: 11px; border: 1px solid var(--grey); border-radius: 0; background: var(--paper); color: var(--ink); padding: 0 2px; }
.editor .lane .arp button { height: 22px; font: inherit; font-size: 11px; border: 1px solid var(--grey); border-radius: 0; background: var(--paper); color: var(--ink); padding: 0 6px; cursor: pointer; }
.editor .lane .arp button.arp-on.on { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.editor .lane .arp small { color: var(--grey); font-size: 11px; margin-left: 4px; }
/* the arp editor (#465), from the keys lab: a row a setting, the walks as buttons with their semitones under the name,
   the rhythm as a sequencer's steps, the chord on a little keyboard, and the bar playing in the key roll */
.modal.arps { width: min(680px, 94vw); gap: 10px; }
.modal.arps .rows { display: flex; flex-direction: column; gap: 7px; }
.modal.arps input[type=text] { font: 600 13px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); padding: 4px 8px; min-height: 30px; border-radius: 0; }
.modal.arps input[type=text]:focus { outline: none; border-color: var(--ink); }
.modal.arps .row { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; } .modal.arps .row > span { width: 80px; color: var(--grey); font-size: 12px; }
.modal.arps .row > b { font: 600 13px var(--ui); margin-right: 6px; }
.modal.arps button { min-height: 26px; padding: 2px 8px; } .modal.arps button.on { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.modal.arps .walks { align-items: stretch; } .modal.arps .walks > span { align-self: center; }
.modal.arps .walk { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 3px; padding: 3px 6px; font-size: 11px; }
.modal.arps .walk .steps { display: flex; gap: 1px; }
.modal.arps .walk .steps i { width: 4px; height: 4px; border: 1px solid var(--grey); }
.modal.arps .walk .steps i.in { background: var(--ink); border-color: var(--ink); }
.modal.arps .walk .steps i.held { border-style: dotted; }
.modal.arps .walk.on .steps i { border-color: var(--paper); } .modal.arps .walk.on .steps i.in { background: var(--paper); }
.modal.arps .rhythm .cells { display: flex; gap: 2px; }
.modal.arps .rhythm .cells button { width: 30px; padding: 0; font-variant-numeric: tabular-nums; }
.modal.arps .rhythm .cells button.on { background: var(--red); border-color: var(--red); color: var(--paper); }
.modal.arps .rhythm .cells button.rest { background: var(--paper); color: var(--grey); }
.modal.arps .rhythm .cells button.more { border: 1.5px dashed var(--rule); color: var(--rule); background: none; }
.modal.arps .rhythm .cells button.more:hover { border-color: var(--grey); color: var(--grey); }
.modal.arps .rhythm .cells button.now { box-shadow: 0 0 0 2px var(--ink); }
.modal.arps .rhythm .cut { width: 26px; padding: 0; margin-left: 4px; } .modal.arps .rhythm .cut:disabled { color: var(--rule); cursor: default; border-color: var(--rule); }
.modal.arps .rhythm .read { color: var(--grey); font-size: 11px; margin-left: 6px; }
.modal.arps .probe { display: grid; grid-template-columns: repeat(24, 1fr); height: 26px; margin-left: 84px; }
.modal.arps .probe i { border: 1px solid var(--rule); cursor: pointer; background: #fffaf0; } .modal.arps .probe i.b { background: var(--ink); } .modal.arps .probe i.on { background: var(--red); }
.modal.arps .shown { margin-left: 50px; }
.modal.arps .keyroll .roll { background-image: repeating-linear-gradient(90deg, transparent 0 calc(25% - 1px), var(--rule) calc(25% - 1px) 25%); }
.editor .s.frozen { outline: 1.5px solid var(--red); outline-offset: -2px; }
.editor .s:hover { box-shadow: inset 0 0 0 1.5px var(--ink); }
/* each lane's scrub bar (#186), gliding through its place as the ring plays, and where a link fired, marked for a loop */
.editor .cells { position: relative; }
.editor .scrub { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; background: var(--ink); pointer-events: none; }
.editor .scrub[hidden] { display: none; }
.editor .wires .fired { stroke-width: 2.5; }
.editor .s.lit { animation: flare var(--flash) ease-out; }
@keyframes flare { from { filter: brightness(1.9); } to { filter: none; } }
.editor .clear { color: var(--grey); padding: 0 4px; }
.editor .clear:hover { color: var(--red); }
.editor .foot { display: flex; gap: 8px; margin-top: 4px; }
/* a new ring from the patterns page (#212), under the lanes */
.editor .fresh { display: flex; gap: 6px; align-items: center; padding-top: 6px; border-top: 1px dashed var(--rule); }
.editor .fresh button, .editor .fresh select { font: 600 12px var(--ui); color: var(--ink); background: var(--paper); border: 1.5px solid var(--rule); border-radius: 0; padding: 3px 8px; cursor: pointer; }
.editor .fresh button:hover:not(:disabled), .editor .fresh select:hover:not(:disabled) { border-color: var(--ink); }
.editor .fresh :disabled { color: var(--grey); opacity: .5; cursor: default; }
.editor .foot button { font: 600 12px var(--ui); border: 1.5px solid var(--rule); padding: 4px 10px; }
.editor .foot button:hover:not(:disabled) { border-color: var(--ink); }
.editor .foot button:disabled { color: var(--grey); opacity: .5; cursor: default; }
.editor .move { display: block; width: 100%; text-align: left; padding: 5px 6px; font: 600 12px var(--ui); border-bottom: 1px solid var(--rule); }
.editor .move:hover { background: var(--wash); }
.editor .move small { display: block; font: 500 11px var(--ui); color: var(--grey); }
.editor .none { font: 500 12px var(--ui); color: var(--grey); }

/* the rules that reach a ring, in its panel (#136): the computer's scripts, small */
.panel .rules { flex-direction: row; flex-wrap: wrap; gap: 10px; align-items: start; }
.panel .rules .script { cursor: pointer; }
.panel .rules .block { font-size: 10px; min-height: 22px; padding: 2px 6px; gap: 4px; }
.panel .rules .block.when { border-top-width: 3px; }
.panel .rules .block.when > span:first-child { font-size: 8px; }
.panel .rules .ring-pic { width: 16px; height: 16px; }
.panel .rules .place { min-width: 22px; height: 15px; font-size: 9px; }
.panel .rules .script:hover .block { border-color: var(--ink); }
/* on the scripts engine (#409) a script reaching the ring is its sentences, wrapped */
.panel .rules .script.words .block { display: block; max-width: 240px; line-height: 1.35; }

/* The global program keeps the computer's blocks and motion rule (#262). */
.computer.global .program .block.then.lit { animation: hat-lit calc(var(--fade) * 3) ease-out; }
.editor .cpu.global { grid-column: 1 / -1; }
/* A cat's selected containers stay together in one comparison (#261). */
.modal.cards.multi .table { grid-template-columns: minmax(0, 1fr) 300px; }
.modal.cards .shown.multi { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.modal.cards .scope-container { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px; align-content: start; }
.modal.cards .scope-container .container-name { grid-column: 1 / -1; }
.modal.cards .container-name { font: 600 11px var(--ui); }
.modal.cards.multi .foot { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 16px; }
.modal.cards.multi .foot .key { grid-column: 1 / -1; }
.modal.cards .choice .change { display: block; margin-top: 4px; font: 500 11px/1.3 var(--ui); }

.modal.cards.multi { display: flex; flex-direction: column; max-height: 92vh; overflow: hidden; }
.modal.cards.multi .table { min-height: 80px; overflow-y: auto; flex: 1 1 auto; }
.modal.cards.multi .foot { flex: 0 0 auto; max-height: 28vh; overflow-y: auto; }
.modal.cards.multi .actions { flex: 0 0 auto; }
.modal.cards .shown.multi { width: 100%; }
.modal.cards .shown.multi:not(.two) .scope-container { grid-template-columns: 1fr; }
.modal.cards.multi .disc { max-width: 90px; }
/* Two writers disagreeing is a nudge, never a refusal (#258). */
.computer .program .block.then.contradiction { box-shadow: inset -4px 0 #b77b18; }

/* The ring's own clock, separate from its headphones and mute (#234). */
.editor .lane .advance { width: 22px; height: 22px; padding: 0; border: 0; background: none; }
.editor .lane .advance .icon { width: 16px; height: 16px; stroke: var(--grey); }
.editor .lane .advance.on .icon { stroke: var(--ink); }
.computer .clock-note { font: 500 10px var(--ui); padding-left: 5px; }

/* A library click chooses among the container's rings (#298). */
.editor .pattern-rings .pattern-ring { width: 32px; height: 32px; padding: 2px; }
.editor .pattern-rings .ring-pic { width: 26px; height: 26px; }

/* The library reset is a small control until its layout is settled (#297). */
.editor .lib .reset-filters { justify-self: start; padding: 3px 6px; font-size: 10px; }

/* The live mini shares the icon's flat rings, with lamps and its own clock (#275, #172). */
.live-mini { width: 200px; color: var(--ink); }
.live-mini .mini-caption { font: 600 11px var(--ui); padding-bottom: 5px; }
.live-mini .mini-live-rings { width: 200px; height: 200px; display: block; overflow: visible; }
.live-mini .mini-ring { transform-origin: 0 0; transform-box: view-box; transition: transform var(--rotate); }
.live-mini .mini-band { fill: none; stroke-width: 12px; stroke-linecap: round; }
.live-mini .mini-hush { fill: none; stroke: var(--red); stroke-width: 14px; stroke-linecap: round; }
.live-mini .mini-mark { stroke: var(--paper); stroke-opacity: .5; }
.live-mini .mini-lamp.frozen { stroke: var(--red); stroke-width: 1px; }
/* a keyboard ring's notes (#474): arcs for as long as each is held, square-ended */
.live-mini .mini-note { fill: none; stroke-linecap: butt; }
.live-mini .mini-condition { fill: var(--ink); }
.live-mini .mini-pulse { fill: none; stroke: white; stroke-width: 1px; }
.mini-tooltip { position: fixed; z-index: 100; background: var(--paper); border: 1px solid var(--ink); padding: 10px; pointer-events: none; }
.mini-tooltip[hidden] { display: none; }

/* the other containers along the editor's foot (#296): headphones off until clicked */
.editor .others { grid-column: 2; padding-left: 30px; grid-row: 4; display: flex; gap: 10px; flex-wrap: wrap; padding-top: 8px; border-top: 1px dashed var(--rule); }
.editor .others .other { background: var(--paper); border: 1.5px solid var(--rule); border-radius: 0; padding: 4px; cursor: pointer; opacity: .45; transition: opacity var(--fade), border-color var(--fade); }
.editor .others .other:hover { border-color: var(--ink); }
.editor .others .other.on { opacity: 1; border-color: var(--ink); }
.editor .others .live-mini { width: 76px; pointer-events: none; }
.editor .others .live-mini .mini-caption { font-size: 10px; padding-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.editor .others .live-mini .mini-live-rings { width: 76px; height: 76px; }

/* the layers beside the picture in the editor (#437): under it on the Computer, a column left of it on Patterns. The
   minis are the stage's (.layer), drawn larger */
.editor .lbar { display: flex; align-items: center; gap: 6px; min-width: 0; }
.editor .lbar h3 { margin: 0 6px 0 0; }
.editor .lbar button.layer { width: 46px; height: 38px; padding: 0; border: 0; background: none; cursor: pointer; }
.editor .lbar button.layer svg { width: 100%; height: 100%; overflow: visible; }
.editor .lbar button.layer:hover .target { stroke: var(--ink); }
.editor .lbar button.add { width: 30px; height: 30px; border: 1.5px dashed var(--rule); font: 500 16px/1 var(--ui); color: var(--grey); }
.editor .lbar button.add:hover { border-color: var(--ink); color: var(--ink); }
.editor.computing .spin { grid-row: 2 / 4; }
.editor.computing .lbar { grid-column: -2; grid-row: 4; padding-top: 8px; border-top: 1px dashed var(--rule); }
.editor:not(.computing) .lbar { position: absolute; right: calc(36px + min(20vw, 30vh)); bottom: 22px; flex-direction: column; align-items: flex-end; }
.editor:not(.computing) .lbar h3 { margin: 0 0 2px; }
.modal.told { max-width: 460px; }
.modal.told p { margin: 0 0 10px; font: 500 13px/1.45 var(--ui); }
