The suggested-progressions panel lays its entries out as a 2x2 grid
(grid-cols-1 sm:grid-cols-2) instead of a vertical list, using the
left-column width and halving the block height. Layout-only: a grid
class + a render-time slice(0,4); the ranker, scoring, cap
(RELATED_MAX_ENTRIES=5), and every entry's chips/labels are untouched,
so the C-50 ranking pins stay green. Idle/empty states stay
single-column. Critic PASS (combined gate).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Try this now shows all of the current chord's valid substitutions at
once (no more rotation), each as a card with the chord name, a mini
diagram of how to play it in the selected instrument (guitar
ChordDiagram 4-across, piano MiniPiano keyboards in a 2x2, bass a root
caption), and the plain why. Still follows the live playhead so the
set refreshes per chord as the progression evolves; honest-empty
without a key/loop; the rolled-jam visibility fallback preserved.
App.jsx change is the single instrument prop, contract-clean. Critic
PASS (combined gate: diagrams resolve, root badge correct, reactivity
verified).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The rotating Try-this card was gated on a live-detected currentChord,
so a rolled Jam Roulette (which locks a key + loop but leaves the
history empty until you play) showed nothing. TryThis now falls back
to the first loop chord that yields a substitution, so the card is
visible whenever a loop is on screen in a locked key; the live-playing
path is unchanged and honest-empty (no key / no loop) is preserved.
Critic PASS (combined gate: renders for the rolled-jam case, no
infinite render).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dashboard licks strip now follows the global GUITAR/PIANO/BASS
selector: guitar shows LickCard tabs, piano shows the PianoLickCard
piano-roll (jazz/blues/gospel/rnb), bass shows an honest empty line.
Every strip card is a uniform compact 220x150 box (tab/roll normalized
to a 104px-tall panel) so the licks stop hogging space. Play buttons
removed from the strip. Knowledge Center LicksSection + LickCard left
byte-identical. .dark-scroll applied to the rail/strip scrollers.
Critic PASS (combined gate).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dashboard voicings rail: guitar galleries capped to 4 shapes
(recommended-first, then open, then movable by base fret; prop-gated so
the Knowledge Center and chord modal keep all shapes); piano voicings
render as a 2x2 grid of size="mini" (scale 0.60) keyboards under the
rail's dense path only. Play buttons removed globally from
VoicingBrowser per the user ("leave them off, better not") — the
Knowledge Center + modal render byte-identical minus the buttons.
A scoped .dark-scroll utility (thin, #2a2a2a on transparent) dresses
the dashboard scrollers. Critic PASS (combined gate: byte-identity
proven, zero play buttons everywhere, contract intact).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
When the loop matches a KB style (rolled or live-detected),
RelatedProgressions leads with that style's other progressions under a
"Try these in {style}" header, labelled by data-derived character
(minor version / shorter form / extended form / reharmonized) computed
from mode/bars/qualities — no cross-style jumping. The role phrase is
suppressed unless the sibling is genuinely related (same changes or a
shared transition), so no false "variation" claim. When no style is
locked, today's cross-style list is preserved byte-for-byte. Smoke
893/893: §8 re-pinned (scores stable 92/156, labels moved) plus two
gate-added durable assertions (finding-B suppression + no-match
fallback). Critic PASS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 🎲 button opens a genre popover (Surprise me + the 10 KB styles);
rollJam seeds a random key + an interesting round-trip-safe
progression as a committed loop, so the whole dashboard fills exactly
as if detection found it — banner chips, voicing rail, licks, related
progressions. Three commit-layer guards keep the seed alive until the
band takes over: the null-clear skips seeded loops (a seed would
otherwise die one commit before the earliest possible confirmation),
the agreement branch confirms it, replacement swaps once real playing
is consistent, New Song clears it. An amber "rolled · style · name ·
bars — play it!" provenance chip flips to the normal loop marker on
first agreeing detection. Audio contract grep: zero hits. Critic PASS
(seed timeline hand-traced; §3.5 invariant verified at every write).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
buildLoopIndex additionally indexes each progression's collapsed form
(adjacent (degree,suffix) dedup + wrap), appended after raw entries so
every prior matcher winner is preserved except the enumerated
country-145 self-attribution. Repairs a pre-existing LIVE-detection
bug: a real 12-bar or 8-bar blues stream collapses to fewer names than
the raw KB degrees, so it matched NOTHING and the Jam Guide sat empty.
JamGuide reads authored plays through the collapsed station's
sourceIndex (all four guitar/piano/bass paths). Adds seedableLoop +
the round-trip roulette pool (smoke sweep: 4 failures / pool 52).
theory.js canonicalize exported. Critic PASS (fix-(a) additivity
proven registry-wide; pool reproduced from the spec; bass sourceIndex
station 5 -> raw 10 hand-checked).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
KB-sourced ranking per the one-screen spec: same canonical degree
shape +100 (with the mandatory collapse of consecutive equal
degree/quality pairs — a real detector-produced 12-bar fires its blues
relatives despite the raw-index matcher bug), same style +40, shared
transitions +12 capped 36, degree-set Jaccard, length penalty; floor
24, max 5, never padded; entries render name/style/level/annotation +
the chord chain realized in the live key as real buttons ->
ChordDetailModal. match.js: additive exports only. Ride-along: dead
currentChord prop dropped from the banner mount. Critic PASS (both
hand-verified scores recomputed independently; full entry lists
byte-matched on three scenarios; collapse counterfactual = 39).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Chrome shave (rail p-2, rows p-1.5, dense cells p-1.5) so the
284+160 piano pair fits with real margin even under a classic Windows
scrollbar (was a genuine break: 452 > 439 at old paddings); gallery
basis 300->320 so a piano recommended cell can never share line one
(prominence for free) while guitar keeps 4 cells per line;
recommended-cell border strengthened to full accent. Playhead
highlight-only contract proven intact; non-dense mounts byte-identical
(28/28 at the gate). Critic PASS (arithmetic recomputed from source
AND the built CSS; flex-basis override confirmed in dist).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Key chip + last-5 history + loop chips on one wrapping row; the
playhead loop chip and the enlarged current history chip are the
"now"; p-2 chrome trim. The text-6xl Now Playing column, its divider,
and the dead currentRN computation are gone — the loop shows once.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SVG circle in the Knowledge Center Explore section: 12 majors outer
ring with key-signature glyphs, relative minors inner, live/locked key
solid accent with subdominant/dominant/relative soft-tiered; diatonic
chord chips inline (tap -> ChordDetailModal); wedge tap = local
preview only, app key state never touched; modal keys light the
correct ring and the hub teaches the parent-major relationship
("1# - G major's notes" for A dorian; 72/72 mode x root uniqueness
proven). Critic returned once (hub showed the wedge signature, not
the mode's), fixed, PASS on scoped re-gate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Realizes SCHEMA bass patterns per station (root at lowest playable
position, degs via the shared resolveDegree, typed approaches derived
from the next station with the open-E octave-displacement rule), lays
them out as compact E-A-D-G tab cards (lick-tab visual idiom), all
plays side by side, each with sequential playback through chordAudio
(negative notes documented-legal; one sequence at a time). Computed
root-fifth-approach line remains the fallback for pack-less styles.
BASS is now real end-to-end. Critic PASS (independent re-realization
of all 912 placements exact; untouched instrument paths byte-identical;
import cycle proven safe in both load orders).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every loop chord is a permanently expanded vertical row: education
header (solo-scale label, guide-tone aim dots with honest 5th
fallback, voice-leading chip incl. the wrap-around loop rail) + the
full voicing gallery for the global instrument; galleries flex-wrap,
zero row-level horizontal scroll; playhead adds highlight classes only
(rows proven byte-equal modulo highlight artifacts); pin simplified to
a focus toggle (onFocusChord contract byte-compatible with L-40).
VoicingBrowser: show='bass' now renders an honest one-liner instead of
falling through to both galleries; dense drops section chrome
(non-dense proven byte-identical across 336 SSR combos). Critic PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The always-open zero-chrome band (GlanceRail + licks strip +
heard-live fallback) replaces CurrentJamPanel right below the
instrument view; the four-section dock becomes KnowledgeDock at the
bottom; RoadmapTrack unmounted (banner is the single loop display);
JamGuide's internal instrument/style tabs die — App's global
GUITAR/PIANO/BASS selector drives everything incl. the dock's
VoicingsSection; honest bass state (computed root-fifth-approach rows
+ notice, no galleries/licks); GlanceRail's scrollIntoView effect
deleted same-commit (would yank the document in page flow).
Ride-along: JamGuide resolveDegree exported (logic byte-identical) for
the C-40 drift guard. Critic PASS (SSR 22/22, audio-contract grep
zero hits, deletion sweep clean).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The station under the playhead auto-expands to the full voicing
gallery (VoicingBrowser dense) and advances with the music; other
stations keep their recommended thumb; level-filtered licks strip
below with token-boundary context sort and strip-owned "fits — now"
chrome; pin replaces tap-to-enlarge with identical onFocusChord
semantics; auto-follow never emits focus or audio; heard-live fallback
shows the live chord gallery. App.jsx and all renderers untouched.
Critic PASS (SSR 37/37, matcher proven on hostile cases, dense-less
render byte-identical to 0945a08).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All placeable guitar shapes and all four pianoVoicing styles render
simultaneously, each cell with its own play button; one-at-a-time
playback and the show prop semantics preserved. Critic PASS (SSR-verified
cell counts, zero aria-pressed, rootPc badge guard intact).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Piano branch prefers kb[style].instruments.piano.plays[prog][0],
resolving recipe degrees via a validator-mirrored resolveDegree +
strict-ascending stacking into MiniPiano's [0,36] space; per-station
fallback to computed pianoVoicingChain (reachable: 4 wide gospel
stations in key B); pack-less styles byte-identical to the computed
path. Critic PASS (0 drift cells vs the validator's resolveDegree;
390-cell sweep; key-B fallback confirmed rendering, not dead).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
GuitarTab/PianoTab pass show=guitar/show=piano to VoicingBrowser
(D-23 prop); Knowledge Center + station-enlarge keep both rows by
design. Critic PASS (SSR: each tab renders only its row, legacy
content intact below).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Thumb window = whole octaves from the octave-C at-or-below the lowest
note (+ closing high C): shell thumbs 266px -> 142px, level with guitar
diagram thumbs. size=full and the legacy lh/rh path byte-identical.
Critic PASS (SVG geometry decoded back to absolute notes incl. the
octave-2 offset case; 793/793 smoke).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ChordDetailModal Guitar/Piano tabs mount VoicingBrowser on top with
legacy grips/technique reference preserved below; Jam Guide enlarged
station view gains the browser on both instrument tabs; parse-null
never mounts a wrong-chord fallback. App.jsx untouched. Critic PASS
(SSR-verified both entry points; onFocusChord effects byte-untouched).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Guitar row (placeable GUITAR_SHAPES via ChordDiagram) + piano row (4
pianoVoicing styles via MiniPiano), chips + explicit play button per
voicing through chordAudio; single shared stop handle; graceful
guitar-empty cell (only add9@E across 168 quality x root cells).
voicings.js gains an export-only GUITAR_SHAPES line. Critic returned
once (rootless voicings badged lowest voice as root — rootPc now passed
through), PASS on scoped re-gate.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Piano is computed (pianoVoicingChain over canonical stations), no
authored KB needed; guitar path value-identical; tap-station guide-tone
contract intact; App.jsx untouched. Critic PASS (303/303 empirical
station checks across 3 progressions x 3 keys; voice-leading threads).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MiniPiano now dispatches: with a voicing={pianoVoicing(...)} prop it renders the
{notes,pcs,bass,style,label} on a 2-3 octave keyboard (root accent, bass amber-ringed,
thumb/full); without it, the legacy {rootPc,lh,rh} path is byte-unchanged so
ChordDetailModal + ExplorePanel render identically. Critic PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Completes the flagship Roadmap feature. App.jsx lifts a jamFocusChord state (additive,
+10/-0, audio callbacks/refs untouched); JamGuide emits the tapped station's {rootPc,
quality} via onFocusChord; Fretboard halos the 3rd/7th with a degree badge.
Also fixes root-cause guideTones: hasSeventh now keys on real m7/M7 (interval 10/11),
not length>=4 -- so add9/maj6/min6 no longer badge their 5th/6th as a '7'. Fretboard
badge derives its label from the actual interval (belt-and-suspenders). RoadmapTrack
lane self-corrects. Critic returned-then-PASS on re-gate; build + smoke + validator green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Renders movable {rootStr,offsets} and open {frets,onlyRoot} KB shapes; computes movable
base fret from chord rootPc in standard tuning (E-shape A7 -> fret 5); root in accent
purple; thumb/full sizes; graceful '-' fallback for unplaceable shapes. Critic PASS.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>