feat: streamline track and master controls layout consistency

- 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>
This commit is contained in:
2025-11-19 16:32:49 +01:00
parent 854e64b4ec
commit 5d9e02fe95
9 changed files with 457 additions and 214 deletions

View File

@@ -69,10 +69,13 @@ export function AutomationHeader({
return (
<div
className={cn(
'relative flex items-center gap-2 px-2 py-1 bg-muted/50 border-b border-border/30 flex-shrink-0',
'flex items-center gap-2 px-3 py-1.5 bg-muted border-t border-b border-border/30 flex-shrink-0',
className
)}
>
{/* Automation label - always visible */}
<span className="text-xs font-medium flex-shrink-0">Automation</span>
{/* Color indicator */}
{color && (
<div

View File

@@ -38,9 +38,9 @@ export function AutomationLane({
(time: number): number => {
if (!containerRef.current) return 0;
const width = containerRef.current.clientWidth;
return (time / duration) * width * zoom;
return (time / duration) * width;
},
[duration, zoom]
[duration]
);
// Convert value (0-1) to Y pixel position (inverted: 0 at bottom, 1 at top)
@@ -58,9 +58,9 @@ export function AutomationLane({
(x: number): number => {
if (!containerRef.current) return 0;
const width = containerRef.current.clientWidth;
return (x / (width * zoom)) * duration;
return (x / width) * duration;
},
[duration, zoom]
[duration]
);
// Convert Y pixel position to value (0-1)
@@ -209,7 +209,7 @@ export function AutomationLane({
const width = rect.width;
// Calculate new time and value
const timePerPixel = duration / (width * zoom);
const timePerPixel = duration / width;
const valuePerPixel = 1 / lane.height;
const newTime = Math.max(0, Math.min(duration, point.time + deltaX * timePerPixel));
@@ -217,7 +217,7 @@ export function AutomationLane({
onUpdatePoint(pointId, { time: newTime, value: newValue });
},
[lane.points, lane.height, duration, zoom, onUpdatePoint]
[lane.points, lane.height, duration, onUpdatePoint]
);
const handlePointDragEnd = React.useCallback(() => {