feat(dashboard): rotating Try-this card — one fresh substitution per loop pass (task L-74)

A compact TryThis card follows the playhead chord and shows ONE
suggestion at a time, cycling to the next valid substitution each time
the loop completes a pass (playhead wraps to a lower station). Over
Am-C-F the F cycles Dm -> Fm -> Fmaj7 -> E7 across passes, so the app
keeps offering a new idea and eventually teaches every honest move,
never a wrong one. Chip taps into ChordDetailModal; 0 subs -> no card,
1 sub -> static. Mounted App.jsx-only above RelatedProgressions in the
related slot; audio contract grep-clean; rotation logic exported pure
and StrictMode-safe. Critic PASS (2-pass rotation trace verified).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
vadimwit
2026-07-13 12:23:18 +01:00
parent 3469bafa0d
commit 038fdfafc8
2 changed files with 174 additions and 5 deletions
+14 -5
View File
@@ -11,6 +11,7 @@ import DrumView from './components/DrumView'
import { NOTES, detectKey, detectTopKeys, matchChordFromChroma, detectRepeatingProgression, getChordTones, getChordCandidates, getNoteHistoryAnalysis } from './lib/theory'
import ChordDetailModal from './components/ChordDetailModal'
import RelatedProgressions from './components/RelatedProgressions'
import TryThis from './components/TryThis'
import LoopStation from './components/LoopStation'
import JamGuide, { KnowledgeDock } from './components/JamGuide'
import { useLoopEngine } from './services/loopEngine'
@@ -854,11 +855,19 @@ export default function App() {
</>
}
relatedSlot={
<RelatedProgressions
loop={detectedProgression}
keyInfo={effectiveKey}
onChordClick={setSelectedChord}
/>
<div className="flex flex-col gap-3">
<TryThis
loop={detectedProgression}
keyInfo={effectiveKey}
currentChord={currentChord}
onChordClick={setSelectedChord}
/>
<RelatedProgressions
loop={detectedProgression}
keyInfo={effectiveKey}
onChordClick={setSelectedChord}
/>
</div>
}
fill={jamView}
/>