TITLE: Waveform Viz — one signal, three bodies PROMPT: Build a single self-contained HTML page called "Waveform Viz". Full-viewport dark #05070d grid: a header row (badge "092", title "Waveform Viz", a mono frequency readout), three equal stacked panels separated by 1px #1b2a44 hairlines, and a bottom synth strip. Each panel holds one canvas absolutely filling it, sized to cssW*devicePixelRatio with ctx.setTransform(dpr,0,0,dpr,0,0), re-measured through a ResizeObserver. One requestAnimationFrame loop drives all three: panel 1 draws a time-domain oscilloscope as 340 points stroked three times (wide 8% alpha cyan, 2.6px 30% alpha, 0.9px #b7f6ff core) with a centre hairline; panel 2 draws 64 spectrum bars with fast-attack/slow-release smoothing (0.44 up, 0.13 down), a pink-to-yellow vertical gradient fill and falling yellow peak caps; panel 3 draws 260 particles orbiting a centre, angle advanced by high-band energy, radius wobbled by bass energy, coloured #fde047 / #38e8ff / #ff2d78 by per-particle hue with alpha from total energy. Each panel's background grid is stroked in canvas with alpha 0.05 + energy*0.13 so the grid pulses. Audio: a lazy AudioContext created only inside a user gesture, wrapped in try/catch, with master gain -> AnalyserNode (fftSize 2048, smoothing 0.82) -> destination. Four voices - sine 55Hz bass, triangle 220Hz mid, square 880Hz through a lowpass 2600Hz high, detuned sawtooth 110Hz through a lowpass 430Hz drone - each an oscillator plus gain ramped with setTargetAtTime. Buttons play/pause the master, toggle the four tones (keys 1-4), and a range input sets gain. Dragging across the scope spawns a lazily-created sawtooth lead through a bandpass, mapped exponentially 45Hz to ~1800Hz, released on pointerup. When the analyser is silent or absent, blend in a procedural multi-sine idle signal so the panels always look alive in a frozen render. Respect prefers-reduced-motion by slowing particles and grid pulse. No external assets and no external references of any kind. DESCRIPTION: A dark instrument that renders one synthetic signal as three simultaneous bodies: a phosphor oscilloscope trace, a smoothed 64-band spectrum with falling peak caps, and a cloud of 260 particles that orbits and swells with bass energy while the background grid breathes. A synth strip at the bottom plays four hand-built voices and a draggable lead, so the visualisation is not a recording of sound but the sound itself, made visible. TECHNIQUES: WebAudio oscillator/biquad graph with a lazily-created, gesture-unlocked AudioContext inside try/catch; AnalyserNode byte frequency and time-domain data split into bass/mid/high bands; exponential smoothing on spectrum bars with fast attack and slow release; DPR-scaled canvases sized from a ResizeObserver; layered stroke glow instead of filters; canvas-drawn pulsing grid; procedural idle signal fallback so silence still animates; particle orbit driven by per-band energy. INTERACTION: Press Play/Pause to open the audio context and ramp the master; click Bass / Mid / High / Drone (or press keys 1-4) to toggle individual voices; drag horizontally across the scope to scrub a bandpass lead from 45Hz to about 1800Hz and watch the readout; drag the Gain slider to change master level; press Space to toggle transport. The spectrum bars bounce with smoothing, peaks fall, particles swirl with bass energy, the grid pulses, and the frequency readout tracks the dominant bin while audio is running.