VoiceForge Karaoke presents itself as an AI-powered living-room karaoke app. The landing screen shows a pulsing mic logo, a gradient-text header, and an ambient pink/cyan/purple glow behind everything. On load, the app fetches a session payload and renders a two-column dashboard โ a big "Now Playing" panel on the left and a sidebar with queue, leaderboard, and AI feature toggles on the right.
Bb3 ยท Bb3 ยท C4 ยท Bb3 ยท G3 ยท F3).setInterval that advances the lyric every 3 seconds.start_ms and end_ms fields, but the app just advances every 3000ms.pitch_assist_strength (0.4) and harmony_voices (2) are displayed inline as if they were controls. No slider, no plus/minus, no dropdown. Same with style_transfer โ the chip appears when a style is set, but the JSON's available_styles array of six options is never offered as a picker.score_total, songs_sung, best_streak are all static readouts rather than live state.vocal_range: { lowest_note: "A3", highest_note: "C6" } is in the payload but nowhere on screen. A karaoke app deciding song suggestions by vocal range would be obvious โ this doesn't.queued_by is shown on each song, which implies multiple people queue songs, but there's no add-to-queue UI and no way to see which singers exist beyond the two in singers[].start_ms / end_ms. Show a thin gradient progress bar under the lyric box fed by the line's remaining time.pitch_assist_strength from 0โ100%. Turn "Harmonies (2)" into a stepper with +/- buttons bounded at 0โ4. Replace the static style-transfer chip with a dropdown seeded from ai_models.style_transfer.available_styles.notes array. This turns the app from a silent demo into something that actually responds to play/pause and AI toggles (e.g. pitch correction snaps the oscillator to the nearest semitone).score_total in state when a song ends and re-sort the leaderboard with a smooth reorder animation.best_streak as a flame count. Highlight any queued song whose root note falls inside the current singer's range.ai_settings.vocal_range, no available_styles, etc.), the corresponding UI should just not render rather than throwing.