Offline-First PWA
Guitar Theory
Fretboard drills and theory for guitarists — installable, dependency-free, and usable with no signal.
Overview
A practice site for guitarists: thirteen tools covering scales, triads, chords, intervals, ear training, progression analysis, a tuner and a metronome. It installs to the home screen as a progressive web app and keeps working when the connection does not — which is usually where a guitar actually gets played.
The Problem
- Theory sites hand out lookup tables that break on awkward roots
- Enharmonic spellings taught as interchangeable when they are not
- Practice rooms, rehearsals and studios rarely have usable signal
- Each tool lives on a different site, with a different mental model
- Heavy JavaScript frameworks for what is ultimately arithmetic
- No way to check that the theory a site prints is actually correct
The Solution
Every note the site prints is generated from letter-and-interval rules rather than looked up in a table. A note is a letter plus an accidental, so a triad is spelled on every other letter name — which is why A♯ major comes out A♯ C♯♯ E♯ and G♭ diminished comes out G♭ B♭♭ D♭♭, instead of the tidy-looking enharmonics a table would return. Because the theory is generated, it can be audited by walking the entire space rather than sampling it.
// The note `letterSteps` letters above the root, `semitones` semitones up.
function spellAbove(root, letterSteps, semitones) {
var letter = LETTERS[(LETTERS.indexOf(root.letter) + letterSteps) % 7];
var desired = (pitchClass(root) + semitones) % 12;
// How far the plain letter sits from the pitch we need — that gap
// is the accidental, up to a double sharp or double flat.
var diff = ((desired - LETTER_PC[letter]) % 12 + 12) % 12;
if (diff > 6) diff -= 12;
for (var acc in ACC_OFFSET) {
if (ACC_OFFSET[acc] === diff) return { letter: letter, acc: acc };
}
return null;
}
// A triad is the root plus a third and a fifth — two letters up, then four.
// A# major -> A# C## E#, never A# Db F.
function buildTriad(rootText, intervals) {
var root = parseNote(rootText);
return [root, spellAbove(root, 2, intervals[0]), spellAbove(root, 4, intervals[1])];
}
The same primitive spells triads, seven-note scales and chord tones, so one rule keeps every page in agreement.
Capabilities
Fretboard Mapping
Scales, triads and chord shapes drawn on the neck across positions, CAGED and three-notes-per-string, in five tunings.
Progression Analyser
Chords in, key and Roman numerals out — including which chords were borrowed and where from.
Reverse Lookup
Notes in, chord and scale names out, for working out what a shape under the fingers actually is.
Ear & Fretboard Drills
Interval and chord-quality listening drills and a note trainer, graded per answer with a scored review at the end.
Tuner & Metronome
Pitch detection through the Web Audio API across eleven tunings, plus a metronome — no native app required.
Offline by Default
A service worker precaches every page and asset, so the whole site loads from the device with no network at all.
Before / After
- Theory looked up in tables that mis-spell awkward roots
- A different site, and a different model, for every tool
- Nothing usable once the practice room loses signal
- Spellings derived from rules, correct at every root
- Thirteen tools sharing one set of theory primitives
- Installs to the home screen and runs entirely offline