Adds docs/roadmap.md outlining the 4-track plan (foundation, surface aesthetics, organizable panel, theming) and ships the first track. - Resizable splitter between editor and control surface (drag the seam, double-click to reset). Width persists in localStorage. - Custom scrollbars (WebKit pseudo-elements + Firefox scrollbar-color) applied globally so CodeMirror's .cm-scroller, the right pane and the piano roll all match the dark theme. - Header separators between transport / gain / info groups. - Smooth transitions on buttons, range thumbs and surface borders. - :focus-visible rings using accent-glow color token. - Pulse animation on the live status dot. - New design-system tokens for layout (--right-w, --splitter-w), timing (--t-fast/base/slow), and panel hierarchy (--panel-hi, --gutter-hi, --divider, --fg-mute, --accent-glow). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.9 KiB
roadmap — code-sinth MVP → product
The MVP works end-to-end: parser, audio engine (Python + JS/AudioWorklet), hot-reload, inline waveforms, knobs, faders, step sequencer, piano roll. Now we polish the web app into something that looks and feels like an instrument, not a developer demo.
Vision
A single static web page where:
- The patch language is the source of truth for what's connected.
- The control surface (right pane) is the source of truth for how you play it: positions, layout, color, scrubbing.
- Everything you change in either place persists across reloads (patch in
whatever editor you use; surface state in
localStorageindexed by patch). - The aesthetic sits between Reaktor 6, Teenage Engineering OP-1, and a modern terminal — dark base, phosphor accents, no skeuomorphism.
Tracks
Four tracks. Each is independently shippable; the order below reflects "unblocks the most other work first".
Track 1 — Foundation polish · status: in progress
Concrete bricks the rest of the work sits on.
- Resizable splitter between editor and control surface. Drag the
vertical seam to rebalance widths.
localStoragepersistence. Min widths so neither pane collapses. - Custom scrollbars (WebKit
::-webkit-scrollbar+ Firefoxscrollbar-color) — thin, dark, accent on hover. Applied globally so CodeMirror's.cm-scroller, the right pane, the piano roll and step seq overflow inherit the same style. - Focus / hover micro-states. Buttons, inputs, controls all get
consistent
transitiontimings and:focus-visiblerings. - Header polish. The top bar gets a proper visual hierarchy, grouped controls (transport, gain, status) instead of a flex blob.
Done when: dragging the seam feels natural, scrollbars match the rest of the dark theme everywhere, no default-browser styling leaks through.
Track 2 — Surface aesthetics
Rebuild each surface to feel premium. For each, deliver 2–3 visual variants in a sandbox before committing.
- Knob: dimensional dial with gradient + accent ring, micro-anim on change, label in small caps, value display below.
- Fader: gradient track, slimmer cap, optional scale marks.
- Step sequencer: cells with subtle inner glow when on, more prominent beat dividers, animated playhead trail.
- Piano roll: more realistic key strip (white keys with border, black keys inset), cells with rounded corners, beat dividers every 4 columns more visible, octave C row marked.
- Wave widgets (inline): grid lines optional, peak indicator, smoother line drawing (anti-aliased Bezier).
Reference: Ableton Live's macros, Bitwig modulators, Reaktor 6 Blocks, Teenage Engineering's hardware.
Track 3 — Organizable surface panel
Each surface becomes a card the user can rearrange and customize. This is the largest track — needs careful state design.
- Card chrome: header with node name, drag handle, color override picker, compact/expanded toggle.
- Drag-drop reorder within the right pane. Probable approach: CSS Grid with grid-auto-flow + a Sortable-style implementation (we won't pull in a library — ~150 lines hand-rolled).
- Per-card accent color override. Defaults to the global
--accent; user can pick per-surface. - Per-card size (compact knob row vs full panel) where it makes sense.
- Persistence: layout state in
localStorage, keyed by a hash of the patch text + node name so each patch remembers its layout. - Reset layout button.
Decision deferred: should the layout be expressible in the patch
language as @layout directives? Pro: shareable, reproducible.
Con: muddies the language. Default answer for now: no, layout is
UI-only state. Add export/import to a JSON blob if shareability
matters later.
Track 4 — Theming
The current single-file approach already uses CSS custom properties. Make it a real theme system.
- Theme tokens consolidated and named coherently
(
--surface-1,--surface-2,--accent-primary,--accent-mute). - 3 packaged themes: phosphor (current), monochrome, warm.
- Theme picker in the header. Persists in
localStorage. - Per-card override (Track 3) layered on top.
Out of scope (for now)
- MIDI input. Web MIDI works but not on Safari and the UX needs design.
- Mobile / touch optimization. Worth a pass later but not in this round.
- A landing / docs page. After the app itself feels finished.
- Patch-language enhancements (string literals, named voices in poly, modulation matrices). Engine-track work, separate roadmap.
Working agreement
- One track at a time, but tracks are paralleliable when ergonomic.
- Each track ends with a screenshot review before merging the changes
into the main
web/index.html. - For visually-driven changes, propose 2–3 variants and pick before committing.