import { useState } from 'react' import ChordBox from './ChordBox' import RiffDiagram from './RiffDiagram' import { getGuitarVoicings, parseChord } from '../lib/voicings' import { CHORD_TYPES, NOTES, toRomanNumeral } from '../lib/theory' import { findSimilarProgressions, progressionInKey } from '../lib/education' // ─── Scale ideas per mode ───────────────────────────────────────────────────── const SCALE_IDEAS = { major: [ { name: 'Major Pentatonic', intervals: '1–2–3–5–6', scaleIntervals: [0,2,4,7,9], desc: 'Safe and bright. Everything you play will land. Start on the root, end on the root.' }, { name: 'Mixolydian', intervals: '1–2–3–4–5–6–♭7', scaleIntervals: [0,2,4,5,7,9,10], desc: 'Major with a bluesy ♭7. The defining sound of classic rock — Sweet Home Alabama lives here.' }, { name: 'Lydian', intervals: '1–2–3–♯4–5–6–7', scaleIntervals: [0,2,4,6,7,9,11], desc: 'Dreamy and floating. The ♯4 is the magic note — use it on long sustained notes for instant wonder.' }, ], minor: [ { name: 'Minor Pentatonic', intervals: '1–♭3–4–5–♭7', scaleIntervals: [0,3,5,7,10], desc: 'The blues box. Bends on ♭3 and slides to 5 are gold. Start here every time.' }, { name: 'Natural Minor', intervals: '1–2–♭3–4–5–♭6–♭7', scaleIntervals: [0,2,3,5,7,8,10], desc: 'Full Aeolian scale. Melodic and dark. The ♭6 gives it a cinematic quality.' }, { name: 'Dorian', intervals: '1–2–♭3–4–5–6–♭7', scaleIntervals: [0,2,3,5,7,9,10], desc: "Minor with a raised 6th — smooth and soulful. Santana's go-to. That major 6th is everything." }, ], dorian: [ { name: 'Dorian Mode', intervals: '1–2–♭3–4–5–6–♭7', scaleIntervals: [0,2,3,5,7,9,10], desc: "The raised 6th over minor is the colour. Mix freely with minor pentatonic and touch that 6th note." }, { name: 'Minor Pentatonic', intervals: '1–♭3–4–5–♭7', scaleIntervals: [0,3,5,7,10], desc: 'Safe backbone in Dorian. You can ignore the 6th — or highlight it for that Dorian sparkle.' }, { name: 'Blues Scale', intervals: '1–♭3–4–♭5–5–♭7', scaleIntervals: [0,3,5,6,7,10], desc: 'Add the ♭5 passing tone through the 5 — that slide is the essence of blues expression.' }, ], mixolydian: [ { name: 'Mixolydian Mode', intervals: '1–2–3–4–5–6–♭7', scaleIntervals: [0,2,4,5,7,9,10], desc: 'The ♭7 is your signature note. Hit it and slide down — instant swagger.' }, { name: 'Major Pentatonic', intervals: '1–2–3–5–6', scaleIntervals: [0,2,4,7,9], desc: 'Works beautifully over the I chord. Clean and reliable when you need to land safely.' }, { name: 'Blues Scale', intervals: '1–♭3–3–4–5–♭7', scaleIntervals: [0,3,4,5,7,10], desc: 'The hybrid blues scale. Bend the ♭3 up to the 3 — that tension and release is everything.' }, ], phrygian: [ { name: 'Phrygian Mode', intervals: '1–♭2–♭3–4–5–♭6–♭7', scaleIntervals: [0,1,3,5,7,8,10], desc: 'That ♭2 is the spine-chilling note. Lean on it. Spanish fire and metal darkness in one scale.' }, { name: 'Phrygian Dominant',intervals: '1–♭2–3–4–5–♭6–♭7', scaleIntervals: [0,1,4,5,7,8,10], desc: 'Raise the ♭3 to a major 3rd. Flamenco and Middle-Eastern intensity. Dramatic every time.' }, { name: 'Minor Pentatonic', intervals: '1–♭3–4–5–♭7', scaleIntervals: [0,3,5,7,10], desc: 'Avoid the ♭2 and play safe pentatonic runs — then hit the ♭2 as a surprise.' }, ], lydian: [ { name: 'Lydian Mode', intervals: '1–2–3–♯4–5–6–7', scaleIntervals: [0,2,4,6,7,9,11], desc: 'Float on the ♯4. John Williams writes entire film scores in Lydian. Sustain everything.' }, { name: 'Major Pentatonic', intervals: '1–2–3–5–6', scaleIntervals: [0,2,4,7,9], desc: 'The reliable base. Use Lydian mode sparingly on top for colour.' }, { name: 'Lydian Dominant', intervals: '1–2–3–♯4–5–6–♭7', scaleIntervals: [0,2,4,6,7,9,10], desc: 'Lydian with a ♭7 — the jazz/fusion ♯4 chord sound. Herbie Hancock territory.' }, ], } // Fallback const SCALE_FALLBACK = SCALE_IDEAS.major // ─── Style variations for a progression ────────────────────────────────────── const STYLE_VARIATIONS = [ { key: 'open', label: 'Open & Spacious', desc: 'Sus2 and add9 voicings — airy, gentle. Great for quiet intros and ambient sections.', typeMap: { maj: 'sus2', min: 'sus2', dom7: 'sus4', maj7: 'add9', min7: 'sus2', add9: 'sus2', sus4: 'sus4', sus2: 'sus2', dim: 'dim', aug: 'aug', half_dim: 'half_dim', maj6: 'sus2', min6: 'sus2' }, color: 'text-blue-400', border: 'border-blue-900/40', }, { key: 'jazz', label: 'Jazz Upgrade', desc: 'Triads → 7ths — instant sophistication. Works at any tempo, in any band context.', typeMap: { maj: 'maj7', min: 'min7', dom7: 'dom7', add9: 'maj7', sus2: 'sus2', sus4: 'sus4', dim: 'dim7', aug: 'aug', half_dim: 'half_dim', maj6: 'maj6', min6: 'min6' }, color: 'text-amber-400', border: 'border-amber-900/40', }, { key: 'blues', label: 'Blues Stomp', desc: 'Everything → dom7. Gritty, raw, powerful. All three chords want to slide and bend.', typeMap: { maj: 'dom7', min: 'dom7', maj7: 'dom7', min7: 'dom7', add9: 'dom7', sus2: 'dom7', sus4: 'dom7', dim: 'dim7', aug: 'aug', half_dim: 'dom7', maj6: 'dom7', min6: 'dom7' }, color: 'text-red-400', border: 'border-red-900/40', }, { key: 'modern', label: 'Neo-Soul / Modern', desc: "Add9 on majors, m7 on minors. D'Angelo, Thundercat, Childish Gambino territory.", typeMap: { maj: 'add9', min: 'min7', dom7: 'dom7', maj7: 'add9', min7: 'min7', add9: 'add9', sus2: 'sus2', sus4: 'sus4', dim: 'dim', aug: 'aug', half_dim: 'half_dim', maj6: 'add9', min6: 'min7' }, color: 'text-purple-400', border: 'border-purple-900/40', }, ] // Transform a chord via a type map function transformChord(chordStr, typeMap) { const p = parseChord(chordStr) if (!p) return chordStr const newType = typeMap[p.type] ?? p.type return NOTES[p.rootPc] + (CHORD_TYPES[newType]?.suffix ?? '') } // Get best voicings for a chord — prefer open shapes, then low-fret barre function getBestVoicings(chordStr, max = 4) { const all = getGuitarVoicings(chordStr) // Sort: open shapes first (label contains "Open"), then barre const open = all.filter(v => v.label.includes('Open')) const barre = all.filter(v => !v.label.includes('Open')) return [...open, ...barre].slice(0, max) } // ─── Per-chord voicing strip ────────────────────────────────────────────────── function ChordStrip({ chordStr, keyInfo, onChordClick }) { const voicings = getBestVoicings(chordStr, 4) const rn = keyInfo?.root ? toRomanNumeral(chordStr, keyInfo.root, keyInfo.mode) : '' return (
{v.label}
No voicings available.
)}{v.label}
Play more and lock a key — similar progressions will appear here.
) return ({prog.songs.slice(0, 3).join(' · ')}
Start listening and play some chords — your jam will appear here.
) : ( <> {/* ── Progression summary ── */}Best open and barre voicings for each chord in your jam. Click a chord name to see all its voicings.
{workingProgression.map(chord => (Scales and modes that fit {root ? `${root} ${mode}` : 'your current key'}. Start with the pentatonic — add the extra notes once you feel comfortable.
{scaleIdeas.map(idea => (Purple = root · Grey = scale tone · Fret numbers above
{idea.desc}
Pro tip: always resolve to a chord tone at the end of a phrase — ♭7 leading to root, or 3rd landing on the 1.
Your progression re-voiced four ways. Expand any style to see the chord boxes.