diff --git a/player-asbuilt.html b/player-asbuilt.html index d8d20f0..61e560d 100644 --- a/player-asbuilt.html +++ b/player-asbuilt.html @@ -11,8 +11,9 @@ • a 128×64 MONOCHROME OLED (SSD1306/SH1106 class): rendered as a true 1-bit framebuffer (drawn, then thresholded to crisp on/off pixels, scaled with image-rendering:pixelated) so the cramped real layout is honest; - • a fixed 16-pixel WS2812 ("NeoPixel") RGB beat bar (PIO-driven) — lights the - first beatsPerBar slots, cyan downbeats / amber group-starts / dim others; + • a 4×16 WS2812 ("NeoPixel") RGB matrix (PIO-driven): the bottom row is the + beat (cyan downbeats / amber group-starts), and the three rows above stack + the current beat's subdivisions as they pass (driven by the finest lane); • an EC11 rotary encoder (turn it: wheel or drag) for tempo, tactile buttons, a MAX98357A-style speaker, USB-C and a PWR LED in a matte 3D-printed case. Compare with the idealized /player.html. One file, no deps; shares src/engine.js. @@ -86,13 +87,15 @@ background:#000; border-radius:2px } .oled-cap{ text-align:center; font-size:10px; color:var(--muted); margin-top:6px; letter-spacing:.02em } - /* ---- WS2812 RGB beat bar (fixed 16 px) ---- */ - .ledbar{ display:flex; gap:5px; justify-content:center; align-items:center; margin:16px auto 4px; width:max-content; - background:linear-gradient(180deg,#10221c,var(--pcb)); border:1px solid #07140f; border-radius:5px; padding:7px 9px; + /* ---- 4×16 WS2812 RGB matrix: bottom row = beat, 3 rows above = subdivisions ---- */ + .ledgrid{ display:flex; flex-direction:column; gap:5px; width:max-content; margin:16px auto 4px; + background:linear-gradient(180deg,#10221c,var(--pcb)); border:1px solid #07140f; border-radius:5px; padding:8px 9px; box-shadow:inset 0 1px 2px rgba(0,0,0,.6) } - .npx{ width:16px; height:16px; border-radius:3px; background:#0c0e10; border:1px solid #05measure; - border:1px solid #060708; position:relative; transition:background .05s, box-shadow .05s } - .npx::after{ content:""; position:absolute; inset:4px; border-radius:1px; background:rgba(255,255,255,.06) } /* the 5050 die */ + .ledrow{ display:flex; gap:5px } + .ledrow.beatrow{ margin-top:4px; padding-top:6px; border-top:1px solid rgba(255,255,255,.07) } + .npx{ width:15px; height:15px; border-radius:3px; background:#0c0e10; border:1px solid #060708; + position:relative; transition:background .05s, box-shadow .05s } + .npx::after{ content:""; position:absolute; inset:4px; border-radius:1px; background:rgba(255,255,255,.05) } /* the 5050 die */ .ledbar-cap{ text-align:center; font-size:10px; color:var(--muted); margin:2px 0 0; letter-spacing:.02em } /* ---- controls: encoder + tactile buttons ---- */ @@ -165,8 +168,8 @@