immortaly007 083744203b Phase 4: drone + T6/E-series + polish + deploy + README
Add drone synth + DronePlayer, wire T6 (mode over drone) and E1-E3 info pages
(E3 carries a drone). Screen Wake Lock while any click/drone plays. Vitest suite
for scheduler timing (no drift over 5 min) and music-layer correctness (triads,
CAGED, diatonic, fretboard). Deploy artifacts: public/_redirects, multi-stage
Dockerfile + nginx.conf (SPA fallback, immutable asset caching, gzip),
.dockerignore. README covering build, Cloudflare Pages / nginx / Docker deploy,
and the deep-link URL format. prefers-reduced-motion honored throughout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 00:36:34 +02:00

Guitar Practice Helper

A static web app that turns the drill codes from my Obsidian practice wiki (R1, F2, T3, …) into interactive helper pages: click tracks, pattern grids, chord & fretboard diagrams, and a drone. Open a drill link from the wiki on phone or desktop, press play, practise for ~5 minutes. No accounts, no backend, no analytics.

Built with Svelte 5 + Vite as a fully static SPA. Music theory is powered by tonal. Timing uses a Web Audio lookahead scheduler so the metronome never drifts.

Develop

npm install
npm run dev        # local dev server
npm run check      # svelte-check (typecheck)
npm test           # vitest (scheduler timing + music-theory correctness)
npm run build      # typecheck + production build to dist/
npm run preview    # serve the built dist/ locally

Deploy

The build is fully static (dist/). Because the app uses path routing (clean URLs like /drill/R3), the host must serve index.html for unknown paths (SPA fallback), and the base path is baked in at build time.

Base path

  • Dedicated domain / served at the root: default, base = '/'.
  • Subpath (e.g. https://example.com/practice/): build with VITE_BASE=/practice/ npm run build.

Cloudflare Pages

Framework preset: none. Build command npm run build, output directory dist. public/_redirects (already included) provides the SPA fallback:

/*    /index.html   200

For a subpath, set the VITE_BASE environment variable in the Pages build settings.

Docker + nginx

A multi-stage Dockerfile (Node build → nginx:alpine) with the correct config (nginx/default.conf: SPA fallback via try_files, immutable caching for hashed assets, no-cache for the HTML shell, gzip):

docker build -t guitar-practice .            # root deploy
docker build --build-arg VITE_BASE=/practice/ -t guitar-practice .   # subpath
docker run -p 8080:80 guitar-practice        # http://localhost:8080

Existing nginx server

Serve dist/ and add the SPA fallback to your location block:

location / {
    try_files $uri $uri/ /index.html;
}

The whole point — link to any drill directly from the wiki:

https://<host>/<base>drill/<CODE>

Optional query parameters override the stored/default settings:

Param Applies to Example
bpm click-track drills ?bpm=66
variant drills with variants ?variant=2-3-2
key T2, T4 ?key=D
root T3, T5, T6, L4 ?root=A
interval T5 ?interval=P5
mode T6 ?mode=dorian
pair R4 ?pair=g-c

Examples:

https://example.com/practice/drill/R3?bpm=66&variant=2-3-2
https://example.com/practice/drill/T6?root=A&mode=dorian
https://example.com/practice/drill/R4?pair=f-bm

Unknown codes resolve to a friendly “unknown drill” page linking back to the index (/ shows all drills grouped by category).

Drills

Code Name Helper
R1 16th-note strum, mute the off-beats metronome + strum grid
R2 Accent patterns metronome + strum grid
R3 7/8 loop (drop to 4/4 live) metronome + strum grid
R4 One-minute chord changes countdown + tap counter + chord diagrams
R5 Palm-mute chugging metronome + strum grid
F1 Travis picking metronome + picking lane + chords
F2 PIMA arpeggio over IVviIV metronome + picking lane + chords
F3 Thumb-independent bass + melody metronome + picking lane
T1 Name every note on one string metronome prompter + fretboard
T2 CAGED shapes fretboard, prev/next
T3 Triads on a 3-string set chord diagrams, inversions
T4 Diatonic chords of a key chord diagram row
T5 Intervals from a root fretboard
T6 Mode over a drone drone + fretboard
L1 Alternate picking builder metronome + picking lane
L2 Legato runs (triplets) metronome + picking lane
L3 String skipping metronome + picking lane
L4 Bends and vibrato reference tone
E1 Interval recognition info
E2 Chord quality recognition info
E3 Play along by ear info + drone

Keyboard (desktop)

  • Space — play / pause
  • ↑ / ↓ — BPM ±2

Notes

  • Audio unlocks on the first tap/keypress (mobile autoplay policy).
  • Per-drill settings (BPM, variant, key, best scores) persist to localStorage under the gph: namespace.
  • Screen Wake Lock keeps the phone awake while a click or drone is playing.
  • Respects prefers-reduced-motion: the beat still advances, without the glow/swing.
S
Description
Small web app with some tools & exercises for guitar practice.
Readme 162 KiB
Languages
Svelte 56.5%
TypeScript 39.6%
CSS 2.5%
Dockerfile 0.5%
HTML 0.4%
Other 0.4%