Phase 3: chord/fretboard diagrams + theory drills + R4

Add ChordDiagram (SVG chord box) and horizontal Fretboard components, plus a
tonal-backed music layer: fretboard note mapping, scale/interval/diatonic helpers,
curated chord shapes, and computed triad inversions + CAGED shapes. Wire T1
(note prompter), T2 (CAGED), T3 (triads, optional click + auto-advance), T4
(diatonic), T5 (intervals), R4 (one-minute changes with best score), and L4
(reference tone). Upgrade F1-F3 to show real chord diagrams.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-22 00:31:33 +02:00
parent c7e8e457da
commit 365aac58a0
18 changed files with 1888 additions and 14 deletions
+9 -2
View File
@@ -8,6 +8,8 @@
import DrillLayout from '../common/DrillLayout.svelte'
import Transport from '../metronome/Transport.svelte'
import PickingLane from '../patterns/PickingLane.svelte'
import ChordDiagram from '../diagrams/ChordDiagram.svelte'
import { getChordShape } from '../../lib/music/chords'
interface Props {
drill: PickingDrill
@@ -89,10 +91,15 @@
{#if drill.chordLabels && drill.chordLabels.length}
<div class="chords">
<span class="eyebrow">Chords{drill.chordLabels.length > 1 ? ' (per bar)' : ''}</span>
<span class="eyebrow">Chords{drill.chordLabels.length > 1 ? ' (one per bar)' : ''}</span>
<div class="chip-row">
{#each drill.chordLabels as c}
<span class="chord num">{c}</span>
{@const shape = getChordShape(c)}
{#if shape}
<ChordDiagram {shape} label={c} size={96} />
{:else}
<span class="chord num">{c}</span>
{/if}
{/each}
</div>
</div>