# 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