Soundless Symphonies
A playful “silent music” composer where users build looping songs by arranging animated visual notes on a timeline grid—each note represents an instrument and intensity, but playback is purely visual (no audio). The app includes preset “scores,” a random motif generator, and an exportable share card (PNG) of the loop plus a compact JSON score saved to localStorage. Clear component boundaries: timeline/grid editor, instrument palette, loop preview animation, preset/random panel, and save/export gallery.
Run: npm create vite@latest . -- --template react-ts && npm i && npm i -D tailwindcss postcss autoprefixer && npx tailwindcss init -p && npm i class-variance-authority clsx tailwind-merge lucide-react && npx shadcn@latest init
by system
Configure Tailwind content and add base styles in src/index.css.
by system
Add shadcn/ui primitives (button, card, dialog, tabs, tooltip, toast) via generated components.
by system
Create src/lib/types.ts with Score, NoteEvent, Instrument, and GridSize TypeScript types.
by system
Create src/lib/instruments.ts exporting instrument metadata (id, name, color, icon, intensity range).
by system
Create src/lib/presets.ts exporting a small list of built-in preset Score objects.
by system
Create src/lib/random.ts that generates a motif Score from a seed and current grid settings.
by system
Create src/lib/storage.ts for load/save/delete of scores and app settings using localStorage.
by system
Create src/lib/shareCard.ts to render a score to a canvas and export a PNG data URL.
by system
Implement src/App.tsx with the main split layout (palette, editor, side panels, gallery).
by system
Create src/components/HeaderBar.tsx with app title plus play/pause, tempo, and grid size controls.
by system
Create src/components/TimelineGrid.tsx to render the editable timeline cells with rows by instrument.
by system
Create src/components/GridCell.tsx to display one cell with intensity styling and hover/active states.
by system
Add click/drag handlers in TimelineGrid to add/remove notes and adjust intensity per cell.
by system
Create src/lib/useComposerState.ts as a lightweight hook managing current score, selection, and settings.
by system
Create src/components/InstrumentPalette.tsx to pick active instrument and intensity brush.
by system
Create src/components/IntensityControl.tsx using shadcn Slider to set brush intensity.
by system
Create src/lib/useLoopTransport.ts to manage playhead position, tempo, and looping animation timing.
by system
Create src/components/Playhead.tsx to draw the moving playhead aligned to TimelineGrid columns.
by system
Create src/components/LoopPreview.tsx to show animated visual notes firing as playhead crosses them.
by system
Create src/components/PresetPanel.tsx to browse and load preset scores from presets.ts.
by system
Create src/components/RandomPanel.tsx with seed input and generate/apply random motif actions.
by system
Create src/components/ScoreTitle.tsx to edit the current score title with inline input.
by system
Add a Save button component that persists current score to localStorage via storage.ts.
by system
Create src/components/Gallery.tsx to list saved scores from localStorage as cards.
by system
Create src/components/GalleryCard.tsx showing score title, mini preview, and load/delete buttons.
by system
Create src/components/ScoreThumbnail.tsx to render a compact non-interactive grid preview.
by system
Create src/components/ExportDialog.tsx to generate a PNG share card and provide download/copy actions.
by system
Create src/components/JsonExport.tsx to show compact score JSON and copy-to-clipboard.
by system
Add empty/loading/error UI states plus toasts for save/export actions using shadcn toast.
by system