v2.0 · NYC Graffiti Edition
Where other instruments give you notes, LITH gives you tension.
LITH is a browser-based polyphonic instrument built around a single idea: harmonic gravity. Notes aren't on/off events — they are masses in a tonal field, each exerting measurable dissonance on every other. The Gravity Field makes that force visible and playable. Resolution is the instrument.
Visual identity: 1980s NYC subway car graffiti — wildstyle lettering, Keith Haring lines, Basquiat mark-making, Krylon/Rustoleum palette. White base. Black outlines. Maximum colour.
┌─────────────────────────────────────────────────────────────────┐
│ ▓▓▓ RED ▓▓▓ YELLOW ▓▓▓ CYAN ▓▓▓ MAGENTA ▓▓▓ GREEN ▓▓▓ ORANGE ▓ │ ← drip bar
│ ♦ ▲ ● ★ ■ ♦ ▲ ● (animated Haring icons) │
├──────────────────────────────────────────────────────────────────┤
│ LITH Tonal Gravity Instrument · v2.0 ◂ Hollow Dusk ▸ ●●○○○ │ ← header
├────────────────────────────────────┬─────────────────────────────┤
│ │ TENSION ██████░░ 0.72 │
│ G R A V I T Y F I E L D │ RESOLVE ███░░░░░ 0.28 │
│ ├─────────────────────────────┤
│ (interactive canvas — voice │ Interval Tritone │
│ nodes, arc connections, │ Voices 3 │
│ particle physics) │ Root C4 │
│ ├─────────────────────────────┤
│ │ [Gravity] [Decay] [Body] │
│ SAMO© ★ NYC ★ │ [Drift] [Space] [Spread]│
├────────────────────────────────────┤ │
│ ████████████████ WAVEFORM │ FREQ ██│ C C# D D# … scale/root │
├────────────────────────────────────┴─────────────────────────────┤
│ [C][C#][D][D#][E][F][F#][G][G#][A][A#][B][C][C#][D] Oct 4 │ ← keyboard
├──────────────────────────────────────────────────────────────────┤
│ [About] ★ LITH NYC ★ [Silence] [Resolve All · Space] │
└──────────────────────────────────────────────────────────────────┘
Synthesis engine
- Per-voice oscillator bank: sawtooth (primary) + 2nd/3rd harmonic sines + sub-octave sine
- Drift LFO with randomised rate per voice — organic beating between simultaneous notes
- Lowpass filter (body param) with resonance that increases with warmth
- ADSR envelope with 15 ms attack and configurable release
- Stereo panning distributed across keyboard range (spread param)
- Synthetic convolution reverb — IR generated locally, no audio file fetched
Harmonic intelligence
- Real-time tension calculation from psychoacoustic consonance model (Helmholtz / Plomp–Levelt)
- Tension and Resolution meters updated at 60 fps
- Auto-resolve engine — when tension exceeds threshold for ~2 s, the most dissonant voice fades out
- Resolve All gesture releases voices in dissonance order — the release arc is the resolution
Gravity Field
- Click top half to trigger notes at horizontal pitch position
- Drag anywhere to modulate drift in real time (Y axis = pitch instability)
- Quadratic arc connections between active voices — line weight and colour reflect dissonance
- Interval name labels float at arc peaks
- Haring-style concentric ripple rings on click/drag
- Paint-splatter particle physics — circles and rectangles with gravity and air resistance
Controls
- 6 knobs: Gravity, Decay, Body, Drift, Space, Spread — all with SVG arc tracks, drag/scroll/touch/keyboard
- 8 presets: Hollow Dusk, Iron Choir, Glass Lattice, Amber Field, Deep Locrian, Open Fifth, Fog Dorian, Mercury Veil
- 10 scales, 12 root notes, octave range 1–8
- 4 mode toggles: Auto-Resolve, Harmonics, Hold Mode, Particles
- Keyboard shortcuts for all primary actions
| Layer | Technology |
|---|---|
| Runtime | Vanilla HTML/CSS/JS — no framework |
| Audio | Web Audio API (native browser API) |
| Visuals | Canvas 2D API |
| Fonts | Google Fonts (Black Ops One, Permanent Marker, Share Tech Mono) |
| Build | None — single-file delivery |
| Dependencies | Zero at runtime |
Browser support: Chrome 90+, Firefox 90+, Safari 15+, Edge 90+. Requires Web Audio API support.
# Clone the repository
git clone https://github.com/your-org/lith.git
cd lith
# Open directly in browser — works with file:// protocol
open src/lith.htmlA local server avoids occasional browser quirks with file:// and prepares you for
testing the CSP headers in a realistic environment:
# Using Python (no install required)
python3 -m http.server 3000 --directory src/
# Using Node.js npx (no install required)
npx serve src/
# Using Caddy (full header support)
caddy file-server --root src/ --listen :3000Then open http://localhost:3000 in your browser.
# Copy the example environment file
cp .env.example .env
# Edit .env with your local values
# (Currently LITH needs no environment variables to run)| Input | Action |
|---|---|
| A S D F G H J K L | White keys (C–D, second octave) |
| W E T Y U | Black keys (C#, D#, F#, G#, A#) |
| Space | Resolve All — releases voices in dissonance order |
| Click top of Gravity Field | Trigger note at horizontal pitch position |
| Drag Gravity Field | Modulate drift in real time (Y = instability) |
| Drag/scroll knob | Adjust parameter |
| Arrow keys on focused knob | Increment/decrement by 1 |
| ◂ ▸ | Cycle through 8 presets |
| −/+ | Octave down/up |
- Voice nodes — bright coloured bubbles in the Gravity Field; one per active note
- Arc connections — drawn between every pair of active voices; thicker/red = more dissonant; thinner/cyan = consonant
- Tension meter — mean dissonance across all active pairs; 0.00 = pure consonance, 1.00 = maximum tension
- Resolution meter — inverse of tension; rises as voices settle toward consonance
- Interval label — identifies the most dissonant interval currently sounding
| Preset | Character |
|---|---|
| Hollow Dusk | Dark minor, medium decay, organic drift |
| Iron Choir | Dense Phrygian, heavy body, no auto-resolve |
| Glass Lattice | Airy whole-tone, heavy drift, wide stereo |
| Amber Field | Warm Lydian, long decay, lush reverb |
| Deep Locrian | Maximum tension, Locrian, no auto-resolve |
| Open Fifth | Clean major, short decay, wide spread |
| Fog Dorian | Slow Dorian, very long decay, maximum reverb |
| Mercury Veil | Diminished, extreme drift, extreme reverb |
LITH is a client-side only instrument with no server, no database, and no user data processing. The security surface is narrow by design.
- No runtime network calls. CSP
connect-src 'none'blocks allfetch()and XHR. The only external load is Google Fonts at page init. - No persistence. Nothing is written to
localStorage,sessionStorage,IndexedDB, or cookies. - No user input reaches canvas or HTML. All rendered text comes from internal constant arrays.
innerHTMLused only as= ''. No dynamic HTML construction.- AudioContext gated by user gesture. Cannot produce audio without a real pointer or key event.
When serving LITH from a web server, add these HTTP response headers. The meta CSP is a defence-in-depth measure; server-sent headers take precedence and are the authoritative control:
X-Frame-Options: DENY
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer
Permissions-Policy: camera=(), microphone=(), geolocation=()
See docs/SECURITY-NOTES.md for full technical security architecture documentation, including CSP justification, audio graph analysis, and a deployment hardening reference for Nginx.
See SECURITY.md for the responsible disclosure policy and contact channels. Please do not report security issues in public GitHub Issues.
lith/
├── src/
│ └── lith.html # Complete instrument — HTML + CSS + JS in one file
├── docs/
│ └── SECURITY-NOTES.md # Technical security architecture reference
├── .env.example # Environment variable template (no real secrets)
├── .gitignore # Excludes secrets, build artefacts, OS files
├── CHANGELOG.md # Version history
├── CONTRIBUTING.md # Development guide and style requirements
├── LICENSE # MIT
├── README.md # This file
└── SECURITY.md # Vulnerability disclosure policy
Why single-file? LITH is a standalone instrument. Single-file delivery means zero build steps, zero dependency installation, and trivial deployment to any static host — including Itch.io, GitHub Pages, or a USB drive. The architecture is a deliberate constraint, not a limitation.
Read CONTRIBUTING.md before opening a PR. The short version:
- Open an issue before coding
- No new dependencies without discussion
- Follow the code style guide
- Zero secrets in any commit
MIT — see LICENSE.
Copyright © 2025 LITH Project Contributors.