Removed the AudioWorklet compatibility check warning since it's an optional
feature that doesn't affect core functionality. The app works fine without
AudioWorklet support, using standard Web Audio API nodes instead.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated PLAN.md to reflect completion of mobile responsiveness enhancements:
- Touch gesture support via collapse/expand chevron buttons
- Collapsible track and master controls with detailed state descriptions
- Track collapse buttons on mobile (dual chevron system)
- Mobile vertical stacking with automation and effects bars
- Height synchronization between track controls and waveform containers
Phase 15.2 now fully complete with comprehensive mobile support.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added comprehensive mobile support for Phase 15 (Polish & Optimization):
**Mobile Layout Enhancements:**
- Track controls now collapsible on mobile with two states:
- Collapsed: minimal controls with expand chevron, R/M/S buttons, horizontal level meter
- Expanded: full height fader, pan control, all buttons
- Track collapse buttons added to mobile view (left chevron for track collapse, right chevron for control collapse)
- Master controls collapse button hidden on desktop (lg:hidden)
- Automation and effects bars now available on mobile layout
- Both bars collapsible with eye/eye-off icons, horizontally scrollable when zoomed
- Mobile vertical stacking: controls → waveform → automation → effects per track
**Bug Fixes:**
- Fixed track controls and waveform container height matching on desktop
- Fixed Modal component prop: isOpen → open in all dialog components
- Fixed TypeScript null check for audioBuffer.duration
- Fixed keyboard shortcut category: 'help' → 'view'
**Technical Improvements:**
- Consistent height calculation using trackHeight variable
- Proper responsive breakpoints with Tailwind (sm:640px, lg:1024px)
- Progressive disclosure pattern for mobile controls
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Applied performance and audio settings to actual editor behavior:
- enableSpectrogram: conditionally show/hide spectrogram analyzer option
- sampleRate: sync recording sample rate with global audio settings
Changes:
- Switch analyzer view away from spectrogram when setting is disabled
- Adjust analyzer toggle grid columns based on spectrogram visibility
- Sync recording hook's sampleRate with global settings via useEffect
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Modified createTrack and createTrackFromBuffer to accept height parameter
- Updated useMultiTrack to pass height when creating tracks
- Applied settings.ui.defaultTrackHeight when adding new tracks
- Applied settings.editor.defaultZoom for initial zoom state
- Removed duplicate useSettings hook declaration in AudioEditor
- New tracks now use configured default height from settings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed waveformColor from UISettings interface
- Removed waveform color picker from Interface settings tab
- Preserves dynamic per-track waveform coloring system
- Cleaner settings UI with one less option
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fader handles now respect top-8 bottom-8 track padding
- Handle moves only within the visible track lane (60% range)
- Updated both TrackFader and MasterFader components
- Value calculation clamped to track bounds (32px padding top/bottom)
- Handle position mapped to 20%-80% range instead of 0%-100%
- Prevents handle from going beyond visible track area
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Plus button now conditionally rendered based on track.effectsExpanded
- Matches automation controls behavior
- Cleaner UI when panel is collapsed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added EffectBrowser import and state management
- Plus button opens dialog to select from all available effects
- Effect is added to track when selected from browser
- Removed hardcoded low-pass filter addition
- Better UX for adding effects to tracks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed absolute positioning from eye icon button
- Added Plus button to add effects (currently adds low-pass filter)
- All controls now properly inline in normal flex flow
- Eye button correctly positioned at end without overlap
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed absolute positioning from eye icon button
- Made all controls part of normal flex flow
- Eye button now correctly positioned at end without overlap
- Chevron controls no longer overlay the eye icon
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Streamlined track controls and master controls to same width (240px)
- Fixed track controls container to use full width of parent column
- Matched TrackControls card structure with MasterControls (gap-3, no w-full/h-full)
- Updated outer container padding from p-2 to p-4 with gap-4
- Adjusted track controls wrapper to center content instead of stretching
- Added max-width constraint to PlaybackControls to prevent width changes
- Centered transport control buttons in footer
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Import cn utility function from @/lib/utils/cn
- Fixes ReferenceError: cn is not defined
- Required for conditional classNames on effect labels
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Effect labels show in primary color when enabled
- Effect labels show in gray when bypassed/disabled
- Added opacity reduction (60%) for bypassed effects
- Visual feedback matches effect state at a glance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Display effect names as small chips/badges in effects header
- Shows all effect names at a glance without expanding
- Styled with primary color background and border
- Horizontal scrollable if many effects
- Visible whether effects rack is expanded or collapsed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove '(N)' count display from effects bar header
- Effect names are already shown in EffectDevice component:
- Collapsed: vertical text label
- Expanded: header with full name
- Cleaner header appearance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace ChevronDown/ChevronRight with Eye/EyeOff icons
- Position eye icon absolutely on the right side
- Match AutomationHeader styling with bg-muted/50 and border
- Eye icon shows when expanded, EyeOff when collapsed
- Consistent UX between automation and effects bars
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Track component now uses Math.max to ensure track.height is at least MIN_TRACK_HEIGHT
- TrackList component also uses Math.max for consistent enforcement
- Fixes issue where tracks with old height values (340px, 357px) were smaller
- All tracks now guaranteed to be exactly 360px regardless of stored height
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update DEFAULT_TRACK_HEIGHT from 340px to 360px
- Update MIN_TRACK_HEIGHT from 240px to 360px
- Ensures all tracks have consistent 360px minimum height
- Applies to both control column and waveform column
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Import DEFAULT_TRACK_HEIGHT and COLLAPSED_TRACK_HEIGHT from types
- Use DEFAULT_TRACK_HEIGHT (340px) instead of hardcoded 240px fallback
- Ensures all tracks have the same height as the first track
- Matches the height used when creating tracks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove fixed height from Track waveformOnly mode
- Use h-full class to fill flex container instead
- Allows parent scroll container to show horizontal scrollbar based on zoom
- Waveform now properly expands horizontally without clipping
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove h-32 wrapper div around AutomationLane
- AutomationLane now uses its own height (lane.height, defaults to 80px)
- Automation controls (canvas, points) now visible and interactive
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Track container now has fixed height (240px default or track.height)
- Waveform uses flex-1 to take remaining space
- Automation and effects bars use flex-shrink-0 for fixed height
- When bars expand, waveform shrinks instead of container growing
- Matches DAW behavior where track height stays constant
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace absolute positioning with flex column layout
- Waveform, automation bar, and effects bar now stacked vertically
- Removes gaps between bars naturally with stacked layout
- Both bars remain collapsible with no position dependencies
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed border-t from effects bar container
- Keeps border-b for bottom edge separation
- No gap between automation and effects bars in both folded and unfolded states
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Default selectedParameterId to 'volume' when undefined
- Fixes issue where clicking automation header did nothing
- Chevron now correctly shows fold/unfold state
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Sparkles icon import to TrackExtensions
- Remove invalid props from AutomationLane (trackId, isPlaying, onSeek)
- Fix createAutomationPoint call to use object parameter with curve property
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issues:
1. Made automation bar collapsible with chevron indicator
2. Removed border-t from automation lane container (no gap to effects)
3. Restored lane.visible filter so AutomationLane properly renders with controls
The AutomationLane component has all the rich editing UI:
- Click canvas to add automation points
- Drag points to move them
- Double-click to delete points
- Keyboard delete (Del/Backspace) for selected points
- Visual feedback with selected state
All controls are intact and functional when automation bar is expanded.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed all three issues:
1. Removed automation (A) and effects (E) toggle buttons from TrackControls
2. Made automation bar always expanded and non-collapsible
3. Added bottom border to effects bar (border-b)
Changes:
- TrackControls.tsx: Removed entire Row 2 (A/E buttons section)
- TrackList.tsx: Removed click handler and chevron from automation header
- TrackList.tsx: Automation lane always visible (no conditional rendering)
- TrackList.tsx: Added border-b to effects bar container
- TrackList.tsx: Added border-b to automation bar for visual consistency
Bars are now permanent, always-visible UI elements at the bottom of tracks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to automation and effects bars:
- Both bars now positioned at bottom of waveform (not top)
- Bars are always visible when track is expanded (no show/hide buttons)
- Effects bar at absolute bottom
- Automation bar above effects, dynamically positioned based on effects state
- Removed inner container from effects - direct rendering with EffectDevice
- Removed close buttons (X icons) - bars are permanent
- Effects render directly with gap-3 padding, no TrackExtensions wrapper
- Automation controls preserved (AutomationLane unchanged)
This creates a cleaner, always-accessible interface where users can quickly
expand/collapse automation or effects without toggling visibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes automation and effects from card-based overlays to integrated bars:
- Automation bar positioned at absolute top with no margins/padding
- Effects bar positioned below automation or at top if automation hidden
- Both bars use bg-card/90 backdrop-blur-sm for subtle transparency
- Collapsible with ChevronDown/ChevronRight indicators
- Close button (X icon) on each bar
- Effects bar dynamically positions based on automation state
- Added effectsExpanded property to Track type
- Removed card container styling for cleaner integration
The bars now sit directly on the waveform as requested, making them feel
more integrated into the track view rather than floating overlays.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes to automation and effects overlays:
- Reduced backdrop opacity from bg-black/60 to bg-black/30 (less dark)
- Added header to automation overlay with parameter name display
- Added close button to automation overlay (ChevronDown icon)
- Wrapped automation lane in rounded card with border and shadow
- Both overlays now have consistent visual styling
- Added ChevronDown import to TrackList
This makes the overlays less obtrusive and adds proper controls for closing
the automation view, matching the effects overlay pattern.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Automation lanes and effects now render as overlays on top of the waveform
instead of below the track, solving both visibility and layout proportion issues.
Changes:
- Wrapped Track waveforms in relative container for overlay positioning
- Automation lanes render with bg-black/60 backdrop-blur overlay
- Effects render with TrackExtensions in overlay mode (asOverlay prop)
- Added overlay-specific rendering with close button and better empty state
- Both overlays use absolute positioning with z-10 for proper stacking
- Eliminated height mismatch between controls and waveform areas
This approach provides better visual integration and eliminates the need
to match heights between the two-column layout.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed multiple issues with the track layout system:
1. Effect cards now expandable/collapsible
- Added onToggleExpanded callback to EffectDevice
- Effect expansion state is properly toggled and persisted
2. Removed left column spacers causing misalignment
- Removed automation lane spacer (h-32)
- Removed effects section spacer (h-64/h-8)
- Automation lanes and effects now only in waveform column
- This eliminates the height mismatch between columns
3. Layout now cleaner
- Left column stays fixed with only track controls
- Right column contains waveforms, automation, and effects
- No artificial spacers needed for alignment
The automation lanes and effects sections now appear properly in the
waveform area without creating alignment issues in the controls column.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed critical bug where ImportDialog was always rendered regardless of
the open prop value. The component interface didn't match the actual
implementation, causing it to appear on page load.
Changes:
- Added `open` prop to ImportDialogProps interface
- Added early return when `open` is false to prevent rendering
- Renamed `onCancel` to `onClose` to match Track component usage
- Made fileName, sampleRate, and channels optional props
- Dialog now only appears when explicitly opened by user action
This fixes the issue where the dialog appeared immediately on page load
when loading a saved project.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added padding around effects device rack and gap between effect cards
for better visual integration and spacing.
Changes:
- Added p-3 padding to effects rack container
- Added gap-3 between effect device cards
- Improves visual consistency and readability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed issue where ImportDialog was being rendered for each track in
waveform mode, causing multiple unclosable dialogs to appear on page load.
Changes:
- Moved ImportDialog to renderControlsOnly mode only
- Each track now has exactly one ImportDialog (rendered in controls column)
- Removed duplicate ImportDialog from renderWaveformOnly mode
- Removed ImportDialog from fallback return statement
This ensures only one dialog appears per track, making it properly closable.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Restored the automation lane and effects sections that were removed during
the Track component refactoring. These sections now render as full-width
rows below each track, spanning across both the controls and waveforms columns.
Changes:
- Created TrackExtensions component for effects section rendering
- Added automation lane rendering in TrackList after each track waveform
- Added placeholder spacers in left controls column to maintain alignment
- Effects section shows collapsible device rack with mini preview when collapsed
- Automation lanes render when track.automation.showAutomation is true
- Import dialog moved to waveform-only rendering mode
The automation and effects sections are now properly unfoldable again.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added back the right border on the track controls column to visually
separate the controls from the waveform area.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added pb-3 (padding-bottom) to the track controls column to account
for the horizontal scrollbar height in the waveforms column, ensuring
track controls stay perfectly aligned with their waveforms.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Track controls now stay perfectly aligned with their waveforms during
vertical scrolling. The waveform column handles all scrolling (both
horizontal and vertical), and synchronizes its vertical scroll position
to the controls column.
Changes:
- Removed independent vertical scroll from controls column
- Added scroll event handler to waveforms column
- Controls column scrollTop is synced with waveforms column
- Track controls and waveforms now stay aligned at all times
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed React Hooks error by moving waveformScrollRef declaration
before the conditional early return. Hooks must always be called
in the same order on every render.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Refactored track layout to use a two-column design where:
- Left column: All track control panels (fixed, vertical scroll)
- Right column: All waveforms (shared horizontal scroll container)
This ensures all track waveforms scroll together horizontally when
zoomed in, providing a more cohesive DAW-like experience.
Changes:
- Added renderControlsOnly and renderWaveformOnly props to Track component
- Track component now supports conditional rendering of just controls or just waveform
- TrackList renders each track twice: once for controls, once for waveforms
- Waveforms share a common scrollable container for synchronized scrolling
- Track controls stay fixed while waveforms scroll horizontally together
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Modified the waveform minWidth calculation to only apply when
zoom > 1, so the waveform fills the available viewport space
at default zoom level instead of creating unnecessary horizontal
scrolling.
Changes:
- minWidth only applied when zoom > 1
- At zoom = 1.0, waveform takes 100% of available space
- Scrollbar only appears when actually zoomed in
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed horizontal scrollbar implementation to only scroll the waveform
content area while keeping track controls fixed in the viewport.
Changes:
- Wrapped waveform content in a scrollable container with overflow-x-auto
- Moved minWidth calculation to inner container
- Track controls now stay fixed at 192px width
- No scrollbar appears on initial track load
- Scrollbar only appears when zooming extends content beyond viewport
Resolves issue where entire track row (including controls) was
scrolling out of view when zoomed in.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>