# RehearsalHub — Project Context for Claude Code RehearsalHub is a web platform that lets bands relisten to recorded rehearsals, comment at specific timestamps, annotate moments, and collaborate asynchronously. This file is the single source of truth for design decisions, component inventory, UX principles, and open questions. Read it at the start of every session. --- ## Product Summary - Bands record rehearsals and upload the audio files (or connect cloud storage) - Files are organised by rehearsal session (date-based, read from filesystem or timestamp) - Band members can listen, drop timestamped comments with avatar pins directly on the waveform, tag moments (suggestion / issue / keeper), and reply to each other - Multiple bands per user — band switching works like a tenant switch (scoped sidebar) - Storage is always the user's own (Google Drive, OneDrive, Nextcloud, S3, local) — files are never copied to RehearsalHub servers --- ## Design System ### Palette Dark/grey interface throughout. No light mode in v1. ``` Background base: #0f0f12 (app shell, player) Background deep: #0b0b0e (sidebar, comment strip) Background raised: rgba(255,255,255,0.025) (cards, list items) Border subtle: rgba(255,255,255,0.05) Border default: rgba(255,255,255,0.08) Border hover: rgba(255,255,255,0.12) Text primary: #eeeef2 Text secondary: rgba(255,255,255,0.68) Text muted: rgba(255,255,255,0.35) Text hint: rgba(255,255,255,0.22) Accent (amber): #e8a22a — primary action, playhead, active states Accent hover: #f0b740 Member colours (avatar, pin, tag): Alex → #7aabf0 bg rgba(91,156,240,0.18) Maya → #d070c0 bg rgba(200,90,180,0.18) Jordan → #4dba85 bg rgba(61,200,120,0.18) Sam → #e8a22a bg rgba(232,162,42,0.18) Kim → #a878e8 bg rgba(140,90,220,0.18) Tag colours: suggestion → #7aabf0 bg rgba(91,156,240,0.1) issue → #e07070 bg rgba(220,80,80,0.1) keeper → #4dba85 bg rgba(61,200,120,0.1) Instrument tags: Full band → #a878e8 bg rgba(140,90,220,0.1) Guitar → #4dba85 bg rgba(61,200,120,0.1) Drums → #7aabf0 bg rgba(91,156,240,0.1) Vocals → #d070c0 bg rgba(200,90,180,0.1) Keys → #e8a22a bg rgba(232,162,42,0.1) Status: Connected / success → #4dba85 Error / danger → #e07070 ``` ### Typography ``` Font stack: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', sans-serif Mono stack: 'SF Mono', 'Fira Code', monospace (filenames, timestamps, codes) Sizes: Page title 17px / weight 500 Section title 11px / weight 500 / uppercase / letter-spacing 0.7px / muted Body 13px / weight 400 Secondary 12px Hint / meta 11px Micro 10px ``` ### Spacing & Radius ``` App chrome padding: 20–26px Card padding: 10–14px Component gap: 8–12px Border radius lg: 12–14px (app shell, modals) Border radius md: 8–10px (cards, inputs) Border radius sm: 6–7px (buttons, tags) Border radius pill: 20px (filter chips, timestamp pills) ``` ### Buttons ``` Default: transparent bg, 1px rgba(255,255,255,0.09) border, muted text hover → bg rgba(255,255,255,0.06) Primary: rgba(232,162,42,0.14) bg, rgba(232,162,42,0.28) border, #e8a22a text hover → rgba(232,162,42,0.22) Danger: rgba(220,80,80,0.08) bg, rgba(220,80,80,0.2) border, #e07070 text Icon btn: 32–34px circle, same default/hover pattern Play btn: 46px circle, solid #e8a22a bg, white icon ``` --- ## Data Model ``` User id, email, displayName, avatarUrl, instrument, bio → member of many Bands (via BandMember) Band id, name, initials, color, genre, description settings: { membersCanInvite, publicPage, recordingsPrivate } → has many BandMembers → has many StorageLocations → has many Sessions BandMember userId, bandId, role (admin | member | listener) joinedAt StorageLocation id, bandId, provider (gdrive | onedrive | dropbox | nextcloud | s3 | local) config: { rootPath, credentials… } defaultForUpload: boolean Session id, bandId, date (YYYY-MM-DD), title, notes → has many Recordings Recording id, sessionId, filename, durationSeconds storageLocationId, storagePath instrument (fullband | guitar | bass | drums | vocals | keys | other) uploadedBy (userId), uploadedAt Comment id, recordingId, userId timestampSeconds (float — pinned to waveform position) text, tag (suggestion | issue | keeper | '') parentId (for replies) createdAt ``` --- ## Application Shell ``` ┌─────────────────────────────────────────────────────┐ │ Sidebar (210px) │ Main content area (flex 1) │ │ ─────────────────│──────────────────────────────────│ │ [Band switcher] │ Active view based on nav │ │ Nav items │ │ │ ─────────────────│ │ │ [User avatar] │ │ └─────────────────────────────────────────────────────┘ ``` ### Sidebar structure 1. **Band switcher** (top) — shows active band initials + name + chevron. Click opens a dropdown listing all the user's bands with their role. Bottom item is "Create new band". Switching band re-scopes the band-specific nav section label and all band settings views. 2. **Nav sections** - *Account*: Profile, Notifications, Audio & Playback - *Band — [Name]*: Members, Storage, Band Settings 3. **User row** (bottom) — avatar + display name + gear icon → opens Profile --- ## Views ### 1. Library The main landing view. Shows all recordings grouped by session date. **Filter pills narrow within the date structure — they do NOT replace it.** Key behaviours: - Date groups always visible as headers with recording count - Filter pills: All / instrument tags / Commented - Search input searches filenames AND comment text - Sort toggle: Date (default) / Duration / Most commented - Each recording row shows: play button, filename (mono font), duration, instrument tag, comment count, mini waveform bars - Currently playing row highlighted with amber border + "Playing" badge - Click anywhere on a row → opens Player view for that recording - "+ Upload" button → file picker or drag-and-drop ### 2. Player The core experience. Split layout: waveform + queue on left, comment panel on right. **Waveform area:** - Canvas-rendered waveform, 104px tall - Played portion renders in amber (#c8861a slightly darker), unplayed in rgba(255,255,255,0.09) - Avatar pins float above the waveform at exact timestamp positions - Each pin is the member's initials in a circle, coloured by member - 1.5px stem connects pin to waveform - Hover pin → tooltip with member name, timestamp, comment preview - Click pin → jumps playhead to that timestamp AND highlights + scrolls to comment in the panel - Playhead: 2px amber vertical line + 10px amber dot on top - Scrubber bar below waveform (3px, click to seek) - Time display: current time (amber) / midpoint / total **Transport bar:** - Speed selector (0.5× 0.75× 1× 1.25× 1.5× 2×) — left - Skip −30s / Skip +30s - Play/pause (46px amber circle) — centre - Volume slider — right **Comment compose (bottom of panel):** - User avatar + textarea - Timestamp pill (amber, live-updating, blinks dot while recording plays) - Textarea expands on focus from ~42px to ~72px - On focus: tag buttons appear (suggestion / issue / keeper) + Post button - Post disabled until text entered - On post: comment added to list, avatar pin added to waveform immediately **Comment list:** - Scrollable, max-height ~248px - Each item: member avatar, member name, amber timestamp chip (click → seek), tag badge, comment text, Reply link - Highlighted (amber tint) when playhead is within ~5s of that comment's timestamp **Queue panel (below waveform, left side):** - "Up next in session" label - Remaining recordings in the session with index, filename, instrument tag, duration **Breadcrumb header:** Library › [Date] › [filename] with Share button ### 3. Discover (Search / Filter) Global search across all sessions. Results are **always grouped by session** to preserve date context — filters narrow results, they don't destroy the grouping. Key elements: - Prominent search input - Filter groups: Instrument / Member / Date range (independent pill groups) - Results header: "N results across M sessions" - Result groups: session date + name header, then result rows - Each row: icon (comment vs filename match), filename, match type badge, timestamp + member attribution, instrument tag - Click row → opens Player at that timestamp ### 4. Settings — Profile User-level, not band-specific. Fields: Avatar (upload / remove), Display name, Instrument/role, Bio, Email, Change password Danger zone: Delete account (removes from all bands, deletes comments — does NOT touch storage files) ### 5. Settings — Notifications Toggles (on/off) for: - Email: new comment on a recording I've interacted with, @mentions, new recording uploaded, band invite - In-app: replies to my comments, daily activity digest, nearby comment placed (within 5s of mine) ### 6. Settings — Audio & Playback - Default playback speed (select) - Skip interval: 10s / 30s / 60s (select) - Toggles: auto-advance to next track, show waveform avatar pins, pause when adding a comment - Waveform colour picker (amber default, 3 alternatives) ### 7. Settings — Members (band-scoped) - Member list: avatar, name, email + instrument, role badge (Admin / Member), "···" action menu for non-self - Roles explained in a 2-column card: Admin (full access) vs Member (listen + comment only) - Invite form: email input + role select + Send invite button - Hint: "No account needed to accept" Role definitions: ``` Admin → upload, delete recordings, manage members, change settings, manage storage Member → listen, comment, annotate — cannot upload or manage others Listener → listen and comment only (no upload, no annotations) [planned] ``` ### 8. Settings — Storage (band-scoped) - Connected locations list: provider icon, name, path + usage stats, connected dot (green/grey), Manage / Connect button - Disconnected providers shown as grey rows with Connect button - "Add storage location" chip grid: Google Drive, OneDrive, Dropbox, Nextcloud, S3/Compatible, Local folder - Important copy: *"RehearsalHub reads recordings directly from your storage — files are never copied to our servers"* - Upload behaviour section: default upload destination (select among connected), auto-organise by date toggle ### 9. Settings — Band Settings (band-scoped, admin only) - Band logo: upload / use initials - Band name, Genre/description - Privacy toggles: recordings visible to members only, allow members to invite others, public band page (shows name + session count only) - Danger zone: Delete band (removes members, deletes comments/annotations — storage files NOT deleted) --- ## Key UX Principles 1. **Date structure is always the primary axis.** Filtering narrows within it; it never replaces it. Users should always know *when* something was recorded. 2. **Commenting must be frictionless.** Click waveform → playhead jumps + comment input focuses + timestamp pre-filled. One action to start a thought. 3. **Avatar pins are the engagement hook.** Seeing where bandmates commented draws you into the recording spatially. Dense pin clusters signal interesting moments. 4. **Filenames are a known pain point.** `full_rehearsal_take2.wav` means nothing in 3 weeks. Prompt for a human title on upload (but don't block without one). 5. **Storage is the user's, not ours.** Never frame RehearsalHub as a host. The platform is a viewer + collaboration layer on top of the user's existing files. 6. **Band switching is tenant-level.** Switching band re-scopes the entire band section of settings, the library, and the active session context. Account settings (profile, notifications, audio) are always global. --- ## Open Design Decisions These are intentionally unresolved and should be discussed before building those features: - **Range annotations** — users want to mark a *section* not just a point (e.g. "this whole chorus"). Drag-to-select on waveform creating a highlighted region with its own comment thread. - **Comment clustering** — two pins at the same timestamp overlap. Stack vertically, offset horizontally, or show a count badge? - **Invite link** — shareable URL with optional expiry, in addition to email invites. Much faster for band onboarding. - **Listener role** — a third role (hear + comment, no upload) for producers, sound engineers, guests. - **Session-level sharing** — share a single session externally (e.g. with a producer), scoped to that session only, without giving full band access. - **Waveform range annotations** — tap-drag on waveform to create a region comment (different from point comment). - **Mobile layout** — the player split layout (waveform left, comments right) must reflow. Comments panel becomes a bottom drawer. This is a significant layout rethink. - **Keyboard shortcuts** — Space (play/pause), C (drop comment at playhead), ←/→ (seek by skip interval), J/L (half speed / normal speed). - **Notification delivery** — in-app vs email is designed; push (mobile) and Slack/Discord webhooks are not yet specced. --- ## Mockups (Self-Contained HTML) The following sections contain complete, runnable HTML mockups produced during design. Paste any section into an `.html` file and open in a browser to see the live UI. Use these as pixel-accurate references during implementation. --- ### Mockup A — Library + Player + Discover (App Shell) ```html RehearsalHub — Library / Player / Discover
Library
Player
Discover
Recent Sessions
2026-03-31
Late Night Jam
3 new comments
2026-03-28
Song A Deep Dive
5 tracks
2026-03-21
Setlist Run
4 tracks
2026-03-14
New Material
3 tracks
Library
Today — Mar 31
3 recordings
full_rehearsal_take2.wav
28:14Full bandPlaying
7
song_a_guitar_take3.wav
4:52Guitar
2
drums_only_warmup.wav
7:33Drums
1
Mar 28
5 recordings
song_a_full_run_take1.wav
5:18Full band
4
vocals_bridge_isolated.wav
1:47Vocals
6
LibraryMar 31full_rehearsal_take2.wav
Full band
09:52 / 28:14
Up next in session
2song_a_guitar_take3.wavGuitar4:52
3drums_only_warmup.wavDrums7:33
Comments7
AL
Alex2:18
Transition into the chorus feels rushed — could we hold the pre-chorus a beat longer?
↩ Reply
MJ
Maya4:41
Guitar tone has that warmth we were looking for. Keeping this patch.
↩ Reply
JD
Jordan9:52
Tempo drift starts here — check against click. Gets worse through the bridge.
↩ Reply
SR
Sam13:20
The keys fill in bar 48 is perfect — keep for the studio recording.
↩ Reply
KL
Kim20:18
Something clips here on the room mic. @Jordan check gain staging?
↩ Reply
AT9:52
Instrument
Member
Date range
14 results across 4 sessions
grouped by session
2026-03-31Late Night Jam5 results
full_rehearsal_take2.wav
comment match@2:18 · AlexFull band
full_rehearsal_take2.wav
comment match@9:52 · JordanFull band
2026-03-28Song A Deep Dive4 results
song_a_full_run_take1.wav
filename matchFull band
``` --- ### Mockup B — Player (Focused, with Avatar Waveform Pins) Save as `mockup-player.html`. Full interactive player with live avatar pins on waveform, comment compose flow, and playback. ```html RehearsalHub — Player
full_rehearsal_take2.wav
Mar 31, 2026Full band· 28:14
0:0014:0728:14
ST
0:00
· comment pins to playhead
``` --- ### Mockup C — Settings (All Panels) Save as `mockup-settings.html`. Includes band switcher, Profile, Notifications, Audio & Playback, Members, Storage, and Band Settings panels. ```html RehearsalHub — Settings
Active Band
LH
Loud Hands
LH
Loud HandsAdmin
SM
Static MoonMember
TH
The HazeMember
+Create new band
ST
Steffen
Profile
How you appear to your bandmates across all bands
ST
Display
Display name
Shown to all bands you're in
Instrument / role
Shown on your comments and pins
Bio
Account
Email
Password
Danger zone
Delete account
Removes you from all bands and permanently deletes your comments. Storage files are NOT deleted.
Notifications
Choose what pulls you back into the app
Email
New comment on a recording
Someone comments on a recording you've interacted with
Mentions
Someone @mentions you in a comment
New recording uploaded
A bandmate uploads to a shared session
Band invite
In-app
Replies to my comments
Daily session activity digest
Nearby comment placed
When someone comments within 5s of your timestamp
Audio & Playback
Defaults for how recordings play back
Playback
Default playback speed
Skip interval
Amount skipped with ±30s buttons
Auto-advance to next track
Show waveform avatar pins
Pause when adding a comment
Waveform colour
Members · Loud Hands
Manage who has access to this band's recordings
ST
Steffen (you)
Admin
AL
Alex
Admin
MJ
Maya
Member
JD
Jordan
Member
KL
Kim
Member
Invite someone
No account needed to accept the invite.
Admin
Upload, delete, manage members and storage
Member
Listen, comment, annotate — no upload or management
Storage · Loud Hands
RehearsalHub reads your recordings directly — files are never copied to our servers.
Connected locations
📁
Google Drive
loud-hands-rehearsals/ · 14.2 GB · steffen@gmail.com
☁️
Nextcloud
rehearsals.loudhandsnc.de/Music/Sessions · 8.1 GB
🔷
OneDrive
Not connected
Add storage location
📁 Google Drive
🔷 OneDrive
📦 Dropbox
☁️ Nextcloud
🪣 S3 / Compatible
📂 Local folder
Upload behaviour
Default upload destination
Auto-organise by date
Group files into YYYY-MM-DD folders
Band Settings · Loud Hands
Only admins can change these.
LH
Identity
Privacy
Recordings visible to members only
Shared links require login
Allow members to invite others
Public band page
Shows band name and session count only
Delete this band
Removes members, deletes comments. Storage files are NOT deleted.
``` --- ## Component Checklist for Implementation Use this to track what has been designed vs what needs building: | Component | Designed | Notes | |---|---|---| | App shell (sidebar + main) | ✅ | See Mockup A | | Band switcher dropdown | ✅ | See Mockup C | | Library view | ✅ | Date-grouped, filter pills | | Player — waveform | ✅ | Canvas-rendered, amber playhead | | Player — avatar pins | ✅ | Per-member colour, hover tooltips | | Player — comment compose | ✅ | Auto-timestamp pill, tag buttons | | Player — comment list | ✅ | Click timestamp to seek | | Player — transport | ✅ | Speed selector, skip, volume | | Discover / search | ✅ | Results grouped by session | | Settings — Profile | ✅ | Avatar, name, instrument, email | | Settings — Notifications | ✅ | Email + in-app toggles | | Settings — Audio & Playback | ✅ | Speed, skip interval, toggles | | Settings — Members | ✅ | List, invite form, role cards | | Settings — Storage | ✅ | Provider cards, add chips | | Settings — Band Settings | ✅ | Identity, privacy, danger zone | | Range annotations (waveform drag) | ⬜ | See Open Design Decisions | | Comment clustering / overlap | ⬜ | See Open Design Decisions | | Mobile layout | ⬜ | Major rethink needed | | Keyboard shortcuts | ⬜ | See Open Design Decisions | | Session rename flow | ⬜ | Trigger on upload | | Invite link (vs email) | ⬜ | See Open Design Decisions |