diff --git a/Controls/AudioDock.xaml b/Controls/AudioDock.xaml
new file mode 100644
index 0000000..561d92b
--- /dev/null
+++ b/Controls/AudioDock.xaml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Controls/AudioDock.xaml.cs b/Controls/AudioDock.xaml.cs
new file mode 100644
index 0000000..d998688
--- /dev/null
+++ b/Controls/AudioDock.xaml.cs
@@ -0,0 +1,55 @@
+using System.Windows;
+using System.Windows.Controls;
+using ytLive.Models;
+
+namespace ytLive.Controls;
+
+/// The sound bars (creator ruling 2026-10-30). This unit owns the SHELL: the piece of the
+/// window it occupies and the collapse behaviour. The bays and the master readouts fill in over
+/// the following units, so nothing here pretends to be a working meter.
+///
+/// Collapse is driven by the window height, not a user setting: at 1366×768 a full dock
+/// squeezes the preview, and the creator should not have to manage that.
+public partial class AudioDock : UserControl
+{
+ private Window? _window;
+
+ public AudioDock()
+ {
+ InitializeComponent();
+ Loaded += OnLoaded;
+ Unloaded += OnUnloaded;
+ }
+
+ /// Is the dock showing only the telemetry strip?
+ internal bool IsCollapsed { get; private set; }
+
+ /// Test seam: the same code the window's SizeChanged runs, without a window.
+ internal void ApplyWindowHeight(double windowHeight)
+ {
+ var collapsed = AudioDockLayout.IsCollapsed(windowHeight);
+ IsCollapsed = collapsed;
+ Height = AudioDockLayout.HeightFor(windowHeight);
+ Bays.Visibility = collapsed ? Visibility.Collapsed : Visibility.Visible;
+ }
+
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ _window = Window.GetWindow(this);
+ if (_window == null)
+ {
+ ApplyWindowHeight(AudioDockLayout.CollapseBelowHeight); // no host: show the dock
+ return;
+ }
+ _window.SizeChanged += OnWindowSizeChanged;
+ ApplyWindowHeight(_window.ActualHeight > 0 ? _window.ActualHeight : _window.Height);
+ }
+
+ private void OnUnloaded(object sender, RoutedEventArgs e)
+ {
+ if (_window != null) _window.SizeChanged -= OnWindowSizeChanged;
+ _window = null;
+ }
+
+ private void OnWindowSizeChanged(object sender, SizeChangedEventArgs e) => ApplyWindowHeight(e.NewSize.Height);
+}
diff --git a/Controls/BottomBar.xaml b/Controls/BottomBar.xaml
deleted file mode 100644
index 6a233db..0000000
--- a/Controls/BottomBar.xaml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/Controls/BottomBar.xaml.cs b/Controls/BottomBar.xaml.cs
deleted file mode 100644
index 36e5aa6..0000000
--- a/Controls/BottomBar.xaml.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Windows.Controls;
-
-namespace ytLive.Controls;
-
-public partial class BottomBar : UserControl
-{
- public BottomBar()
- {
- InitializeComponent();
- }
-}
\ No newline at end of file
diff --git a/MainWindow.xaml b/MainWindow.xaml
index a5959a7..137b8bd 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -148,7 +148,7 @@
-
+
diff --git a/Models/AudioDockLayout.cs b/Models/AudioDockLayout.cs
new file mode 100644
index 0000000..3e71d9a
--- /dev/null
+++ b/Models/AudioDockLayout.cs
@@ -0,0 +1,23 @@
+namespace ytLive.Models;
+
+/// How tall the audio dock should be for a given window height.
+///
+/// Creator ruling (2026-10-30): the dock is 168px on a normal window and collapses to a 36px
+/// telemetry strip when the window is short, because at 1366×768 a full dock leaves ~398px for the
+/// preview and the composition starts letterboxing into a postage stamp.
+///
+/// Pure, so the switch is testable without a window.
+public static class AudioDockLayout
+{
+ /// Below this window height the dock collapses. The app's minimum is 768; the
+ /// default window is 1040, so a normal launch shows the full dock.
+ public const double CollapseBelowHeight = 900;
+
+ public const double ExpandedHeight = 168;
+ public const double CollapsedHeight = 36;
+
+ public static bool IsCollapsed(double windowHeight) => windowHeight < CollapseBelowHeight;
+
+ public static double HeightFor(double windowHeight)
+ => IsCollapsed(windowHeight) ? CollapsedHeight : ExpandedHeight;
+}
diff --git a/ytLive.Tests/AudioDockLayoutTests.cs b/ytLive.Tests/AudioDockLayoutTests.cs
new file mode 100644
index 0000000..144d611
--- /dev/null
+++ b/ytLive.Tests/AudioDockLayoutTests.cs
@@ -0,0 +1,32 @@
+using Xunit;
+using ytLive.Models;
+
+namespace ytLive.Tests;
+
+/// The dock's height is the whole reason it is allowed to take 168px: on a short window it
+/// must get out of the way instead of squeezing the preview. The threshold is the creator's
+/// minimum (768) and default (1040) — both sides are pinned here so a future "tidy" cannot leave a
+/// 768px window with a full dock.
+///
+public class AudioDockLayoutTests
+{
+ [Fact]
+ public void The_dock_collapses_on_short_windows_and_expands_on_normal_ones()
+ {
+ // Minimum window: collapsed, so the preview keeps its room.
+ Assert.True(AudioDockLayout.IsCollapsed(768));
+ Assert.Equal(AudioDockLayout.CollapsedHeight, AudioDockLayout.HeightFor(768));
+
+ // Default window: the full dock.
+ Assert.False(AudioDockLayout.IsCollapsed(1040));
+ Assert.Equal(AudioDockLayout.ExpandedHeight, AudioDockLayout.HeightFor(1040));
+
+ // The boundary itself belongs to the expanded side (>= is the friendlier read).
+ Assert.False(AudioDockLayout.IsCollapsed(AudioDockLayout.CollapseBelowHeight));
+ Assert.True(AudioDockLayout.IsCollapsed(AudioDockLayout.CollapseBelowHeight - 1));
+
+ // The two heights are the design's numbers, not whatever looked fine.
+ Assert.Equal(168, AudioDockLayout.ExpandedHeight);
+ Assert.Equal(36, AudioDockLayout.CollapsedHeight);
+ }
+}