Commit graph

6 commits

Author SHA1 Message Date
Me Here
df213272ae Add "as-built" player variant: mono 128×64 OLED + 16-px WS2812 beat bar
New /player-asbuilt.html showing the PM-1 with parts you'd actually solder
for an RP2040 build, alongside the idealized /player.html:

- 128×64 MONOCHROME OLED (SSD1306 class): rendered as a true 1-bit
  framebuffer — drawn, then thresholded to crisp on/off pixels and scaled
  with image-rendering:pixelated — so the cramped real layout is honest
  (position / big BPM / grouping / scrolling name / bar·beat).
- Fixed 16-px WS2812 ("NeoPixel") RGB beat bar on a strip PCB: lights the
  first beatsPerBar slots (cyan downbeats, amber group-starts, dim others),
  the rest dark — showing the fixed-count hardware honestly.
- EC11 rotary encoder you actually turn (wheel / vertical drag) for tempo,
  tactile buttons, MAX98357A-style speaker grille, USB-C, PWR LED, matte case.

Shares the same firmware via src/engine.js + src/setlists.js (same seed set
lists, same scheduler); only the panel rendering differs. The device is fixed
dark hardware; the page chrome follows light/dark/system. build.sh + deploy.sh
now assemble/serve all three pages; player.html links to it ("As-built ↗").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 06:57:57 -05:00
Me Here
d1bd996675 Player full-screen: edge-to-edge themed stage + theme toggle in stage
Two fixes from on-device testing:

1. Fill the screen. The earlier stage capped the device at min(96vw,168vh)
   and centred it, leaving big margins on wide phones. Now the device frame
   goes transparent/borderless at position:absolute inset:0 and the OLED
   grows (flex:1) so the unit fills the whole viewport edge to edge.

2. Follow light/dark/system in full-screen. The full-screen skin is the
   themed page gradient (light in light mode, dark in dark, OS-driven on
   system), and a theme toggle (◐/☀/☾ — same cycle + "metronome.theme" key
   as the main page) now sits beside the exit ✕, since the top bar that
   normally holds it is hidden in stage.

The themed gradient is painted on the device element rather than the body
because a position:fixed body doesn't propagate its background to the
canvas (left a white area). The decorative PWR dot is hidden in stage so
it doesn't sit under the floating controls.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:42:30 -05:00
Me Here
075fbb51a7 Player: full-screen "stage mode" with landscape lock
Add a ⛶ button (top bar) that takes the PM-1 device full-screen and locks
it to landscape — turning it into a glanceable stage display.

A single body.stage class drives the layout: top bar + load panel hidden,
OLED / beat-LEDs / transport enlarged with viewport units, plus a floating
✕ exit (the top bar is hidden in stage mode). Per platform:

- Android: requestFullscreen() + screen.orientation.lock("landscape").
- Desktop: real fullscreen; the lock harmlessly no-ops (already landscape).
- iPhone (no Fullscreen/orientation-lock API): CSS pseudo-fullscreen + a
  "⟳ rotate to landscape" overlay shown when held in portrait.

Screen Wake Lock keeps the display awake during a performance (re-acquired
on visibility change). 'F' toggles; Esc / fullscreenchange tear the stage
down and unlock cleanly. All API calls are guarded so rejections on
unsupported platforms never throw.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 21:17:29 -05:00
Me Here
a86421eb5c Player: light/dark theme so the device stands out from the background
The device case was nearly the same tone as the room — the body's
radial-gradient even peaked *lighter* than the case — so the unit blended
into the background. Added a theme toggle mirroring the editor (◐/☀/☾,
cycles system → light → dark, shares the "metronome.theme" key, with a
pre-paint head script to avoid a flash) and reworked the palette around it:

- dark: a charcoal device sits a clear step lighter than a near-black room,
  with a rim highlight + drop shadow + faint cyan glow so it reads as an object;
- light: the dark device sits on a bright "desk" card (panel + fields go light).

Device internals (OLED, beat LEDs, buttons, knob, screws) keep fixed
dark-hardware colours in both themes via --dtxt/--dmuted, so only the
environment switches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 19:16:13 -05:00
Me Here
b548c64d2a Share engine, seed set lists & base CSS between editor and player
Both index.html (editor) and player.html (hardware-player mockup) now pull
their common code from src/ via a new build-time include marker
(/*@BUILD:include:src/…@*/), resolved by build.sh:

  src/engine.js   — audio voices (DRUMS×30), Web Audio scheduler primitives,
                    and the share-language codec (patch/set-list encode+decode)
  src/setlists.js — SEED_SETLISTS, so the player ships the SAME default set
                    lists as the editor (player BUILTIN = SEED_SETLISTS)
  src/base.css    — reset + VARASYS brand palette + type stack

The editor inlines the CC0 acoustic samples; the player passes an empty
SAMPLES object and the shared playInstrument falls back to its synth voices,
so the device stays faithfully synth-only. Each app keeps its own state
globals, setBpm, advanceMaster/scheduler, and UI. ~400 lines of duplicated
engine code removed; the player's favicon is now the shared @BUILD:favicon@.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:49:35 -05:00
Me Here
ec23da5164 Add hardware-device player mockup at /player.html
A self-contained simulator of the RP2040 "PM-1" unit: it plays the share
language (synth voices, same scheduler) and drives an OLED + beat-LED
display like the firmware would. Loads from a #p=/#sl= link, the editor's
saved set lists (localStorage), or a pasted patch / set-list code — with
validation. Transport: play/stop, prev/next item, tempo ±, tap; bar-count
segments auto-advance. deploy.sh now version-stamps and publishes it too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:04:17 -05:00