feat: refine UI with effects panel improvements and visual polish

Major improvements:
- Fixed multi-file import (FileList to Array conversion)
- Auto-select first track when adding to empty project
- Global effects panel folding state (independent of track selection)
- Effects panel collapsed/disabled when no track selected
- Effect device expansion state persisted per-device
- Effect browser with searchable descriptions

Visual refinements:
- Removed center dot from pan knob for cleaner look
- Simplified fader: removed volume fill overlay, dynamic level meter visible through semi-transparent handle
- Level meter capped at fader position (realistic mixer behavior)
- Solid background instead of gradient for fader track
- Subtle volume overlay up to fader handle
- Fixed track control width flickering (consistent 4px border)
- Effect devices: removed shadows/rounded corners for flatter DAW-style look, added consistent border-radius
- Added border between track control and waveform area

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-18 18:13:38 +01:00
parent 839128a93f
commit 17381221d8
10 changed files with 570 additions and 283 deletions

View File

@@ -167,11 +167,6 @@ export function CircularKnob({
{/* Indicator line */}
<div className="absolute top-1 left-1/2 w-0.5 h-2 bg-primary rounded-full -translate-x-1/2" />
</div>
{/* Center dot (for zero position) */}
{value === 0 && (
<div className="absolute top-1/2 left-1/2 w-1 h-1 bg-primary rounded-full -translate-x-1/2 -translate-y-1/2" />
)}
</div>
{/* Value Display */}

View File

@@ -107,35 +107,29 @@ export function VerticalFader({
<div
ref={trackRef}
onMouseDown={handleMouseDown}
className="relative w-8 flex-1 min-h-[80px] max-h-[140px] bg-muted rounded cursor-pointer select-none overflow-hidden"
className="relative w-8 flex-1 min-h-[80px] max-h-[140px] bg-background/50 border border-border rounded cursor-pointer select-none overflow-hidden"
>
{/* Level Meter Background (green/yellow/red gradient) */}
{/* Volume Level Overlay - subtle fill up to fader handle */}
<div
className="absolute inset-0 opacity-40"
style={{
background: 'linear-gradient(to top, rgb(34, 197, 94) 0%, rgb(34, 197, 94) 70%, rgb(234, 179, 8) 85%, rgb(239, 68, 68) 100%)',
}}
className="absolute bottom-0 left-0 right-0 bg-primary/10"
style={{ height: `${valuePercentage}%` }}
/>
{/* Level Meter (actual level) */}
{/* Level Meter (actual level) - capped at fader handle position */}
<div
className="absolute bottom-0 left-0 right-0 transition-all duration-75"
style={{
height: `${level * 100}%`,
height: `${Math.min(level * 100, valuePercentage)}%`,
background: 'linear-gradient(to top, rgb(34, 197, 94) 0%, rgb(34, 197, 94) 70%, rgb(234, 179, 8) 85%, rgb(239, 68, 68) 100%)',
opacity: 0.6,
}}
/>
{/* Volume Value Fill */}
<div
className="absolute bottom-0 left-0 right-0 bg-primary/30 border-t-2 border-primary"
style={{ height: `${valuePercentage}%` }}
/>
{/* Volume Value Fill - Removed to show gradient spectrum */}
{/* Fader Handle */}
<div
className="absolute left-0 right-0 h-3 -ml-1 -mr-1 bg-primary rounded-sm shadow-lg cursor-grab active:cursor-grabbing"
className="absolute left-0 right-0 h-3 -ml-1 -mr-1 bg-primary/70 border-2 border-primary rounded-sm shadow-lg cursor-grab active:cursor-grabbing backdrop-blur-sm"
style={{
bottom: `calc(${valuePercentage}% - 6px)`,
width: 'calc(100% + 8px)',