diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor
index 2660b15..8ef4b53 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor
@@ -1,63 +1,42 @@
@if (_isMinimized)
{
-
+
-
-
+
+
@if (_isDesktop)
{
@* Desktop Layout *@
-
-
-
-
- @if (IsLoading && !IsStreaming)
- {
-
- }
-
-
-
+
+
-
-
OnSeekEnd(_seekPosition))"
- @onpointerleave="@(async () => { if (_isSeeking) await OnSeekEnd(_seekPosition); })">
-
-
-
-
+
-
-
-
-
+
+
}
else
{
@@ -100,18 +79,9 @@ else
}
- @* Control Buttons - positioned absolutely like original *@
-
-
-
-
-
+ @* Minimize / close — positioned absolutely top-right *@
+
+
@if (!string.IsNullOrEmpty(ErrorMessage))
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor.css b/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor.css
index 7978858..7c071c7 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor.css
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor.css
@@ -1,7 +1,8 @@
-/* Preserve key visual styles while simplifying layout */
+/* Geometry, positioning, and animation only.
+ Colour, surface, and elevation come from MudBlazor theme props. */
-/* Player outer container - fixed positioning */
-.player-outer-container {
+/* Fixed dock to the viewport bottom */
+.player-dock {
position: fixed;
bottom: 0;
left: 0;
@@ -11,115 +12,39 @@
margin: 0;
}
-/* Player inner container */
.player-inner-container {
padding: 1rem;
padding-bottom: 1.5rem;
}
-/* Custom backdrop blur container */
-.player-backdrop {
+/* The visible surface is a MudPaper; scoped CSS only sets geometry + a hairline accent */
+.player-surface {
position: relative;
- background: var(--deepdrft-theme-background-gray);
- backdrop-filter: blur(15px);
- -webkit-backdrop-filter: blur(15px);
- border-radius: 1rem;
- border: 2px solid var(--deepdrft-theme-primary);
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
- color: inherit;
- transition: all 0.3s ease;
+ border-radius: 16px;
+ border: 1px solid var(--mud-palette-primary);
overflow: hidden;
margin-bottom: 1rem;
}
-/* Charleston (Light Mode) - Iron frame effect */
-:global(.deepdrft-theme-light) .player-backdrop {
- background: color-mix(in srgb, var(--charleston-cream) 92%, transparent);
- border: 2px solid var(--charleston-iron);
- box-shadow: 0 4px 20px color-mix(in srgb, var(--charleston-iron) 20%, transparent),
- inset 0 0 0 1px color-mix(in srgb, var(--charleston-iron) 5%, transparent);
- color: var(--charleston-iron);
-}
-
-/* Lowcountry (Dark Mode) - Warm sunset glow effect */
-:global(.deepdrft-theme-dark) .player-backdrop {
- background: color-mix(in srgb, var(--lowcountry-night) 88%, transparent);
- border: 1px solid color-mix(in srgb, var(--lowcountry-coral) 50%, transparent);
- box-shadow: 0 0 20px color-mix(in srgb, var(--lowcountry-coral) 25%, transparent),
- 0 0 40px color-mix(in srgb, var(--lowcountry-twilight) 15%, transparent),
- 0 4px 20px rgba(0, 0, 0, 0.4);
- color: var(--lowcountry-moonlight);
-}
-
-/* Control buttons positioning */
-.player-controls {
+/* Minimize / close cluster, pinned top-right of the surface */
+.player-surface ::deep .player-window-controls {
position: absolute;
top: 0.5rem;
right: 0.5rem;
}
-/* Minimized floating dock with gradient */
+/* Minimized floating dock — positioning + hover only; colour from MudFab */
.minimized-dock {
position: fixed;
bottom: 60px;
right: 60px;
z-index: 1300;
- width: 60px;
- height: 60px;
- border-radius: 50%;
- cursor: pointer;
- background: linear-gradient(135deg,
- var(--deepdrft-theme-primary) 0%,
- var(--deepdrft-theme-secondary) 50%,
- var(--deepdrft-theme-tertiary) 100%
- );
- backdrop-filter: blur(15px);
- -webkit-backdrop-filter: blur(15px);
- border: 2px solid var(--deepdrft-theme-secondary);
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
- transition: all 0.3s ease;
-}
-
-/* Charleston (Light Mode) - Iron dock */
-:global(.deepdrft-theme-light) .minimized-dock {
- background: linear-gradient(135deg, var(--charleston-iron) 0%, var(--charleston-rose) 50%, var(--charleston-gold) 100%);
- border: 2px solid var(--charleston-iron);
- box-shadow: 0 4px 15px color-mix(in srgb, var(--charleston-iron) 40%, transparent);
-}
-
-/* Lowcountry (Dark Mode) - Warm sunset dock */
-:global(.deepdrft-theme-dark) .minimized-dock {
- background: linear-gradient(135deg, var(--lowcountry-coral) 0%, var(--lowcountry-twilight) 50%, var(--lowcountry-gold) 100%);
- border: 2px solid color-mix(in srgb, var(--lowcountry-coral) 60%, transparent);
- box-shadow: 0 0 20px color-mix(in srgb, var(--lowcountry-coral) 40%, transparent),
- 0 0 40px color-mix(in srgb, var(--lowcountry-twilight) 20%, transparent);
}
.minimized-dock:hover {
transform: scale(1.1);
}
-:global(.deepdrft-theme-light) .minimized-dock:hover {
- box-shadow: 0 6px 20px color-mix(in srgb, var(--charleston-iron) 50%, transparent);
-}
-
-:global(.deepdrft-theme-dark) .minimized-dock:hover {
- box-shadow: 0 0 30px color-mix(in srgb, var(--lowcountry-coral) 50%, transparent),
- 0 0 50px color-mix(in srgb, var(--lowcountry-twilight) 30%, transparent);
-}
-
-/* Minimized button styles */
-.minimized-button {
- border-radius: 50% !important;
- background: transparent !important;
- color: white !important;
- transition: all 0.3s ease !important;
- box-shadow: none !important;
- border: none !important;
- width: 48px !important;
- height: 48px !important;
-}
-
/* Spacer to prevent content overlap */
.player-spacer {
height: 140px;
@@ -127,50 +52,22 @@
flex-shrink: 0;
}
-/* Essential layout adjustments only */
-.controls-left {
- min-width: 200px;
-}
-
-.seekbar-visualizer-container {
- flex: 1;
- display: flex;
- flex-direction: column;
-}
-
-.seekbar-flex {
- flex: 1;
-}
-
-.volume-right {
- /*min-width: 140px;*/
-}
-
-/* Mobile responsive adjustments */
@media (max-width: 768px) {
.minimized-dock {
bottom: 15px;
right: 15px;
- width: 56px;
- height: 56px;
}
-
- .minimized-button {
- width: 44px !important;
- height: 44px !important;
- }
-
+
.player-inner-container {
padding: 0.75rem;
padding-bottom: 1.25rem;
}
-
- .player-backdrop {
- border-radius: 1rem;
+
+ .player-surface {
margin-bottom: 1.25rem;
}
-
+
.player-spacer {
height: 160px;
}
-}
\ No newline at end of file
+}
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor
index 8c841ce..b091987 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor
@@ -1,4 +1,4 @@
-
+
-
\ No newline at end of file
+
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor.css b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor.css
deleted file mode 100644
index 70a2300..0000000
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerControls.razor.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/* PlayerControls Component Styles */
-
-/* Button spacing and alignment */
-.player-buttons {
- display: flex;
- align-items: center;
- gap: 0.5rem;
-}
\ No newline at end of file
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerSeekZone.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerSeekZone.razor
new file mode 100644
index 0000000..c74ecb0
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerSeekZone.razor
@@ -0,0 +1,18 @@
+@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
+
+
+
+
+
+
+
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerSeekZone.razor.cs b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerSeekZone.razor.cs
new file mode 100644
index 0000000..89c7958
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerSeekZone.razor.cs
@@ -0,0 +1,43 @@
+using Microsoft.AspNetCore.Components;
+
+namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
+
+///
+/// Centre zone of the player: seek slider over the spectrum visualizer.
+/// Owns the pointer-gesture seek logic (drag-to-seek) in one place so it is no
+/// longer duplicated inline between the desktop and mobile branches of the parent.
+///
+public partial class PlayerSeekZone : ComponentBase
+{
+ private double _seekPosition;
+
+ [Parameter] public double DisplayTime { get; set; }
+ [Parameter] public double? Duration { get; set; }
+ [Parameter] public bool CanSeek { get; set; }
+ [Parameter] public EventCallback OnSeekStart { get; set; }
+ [Parameter] public EventCallback
OnSeekEnd { get; set; }
+ [Parameter] public EventCallback OnSeekChange { get; set; }
+ [Parameter] public string? Class { get; set; }
+
+ private async Task HandlePointerDown()
+ {
+ _seekPosition = DisplayTime;
+ await OnSeekStart.InvokeAsync();
+ }
+
+ private async Task HandlePointerUp()
+ {
+ await OnSeekEnd.InvokeAsync(_seekPosition);
+ }
+
+ private async Task HandlePointerLeave()
+ {
+ await OnSeekEnd.InvokeAsync(_seekPosition);
+ }
+
+ private async Task HandleValueChanged(double value)
+ {
+ _seekPosition = value;
+ await OnSeekChange.InvokeAsync(value);
+ }
+}
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor
new file mode 100644
index 0000000..25a4fd6
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor
@@ -0,0 +1,19 @@
+@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
+
+
+
+
+ @if (IsLoading && !IsStreaming)
+ {
+
+ }
+
+
+
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor.cs b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor.cs
new file mode 100644
index 0000000..9990a2d
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Components;
+
+namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
+
+public partial class PlayerTransportZone : ComponentBase
+{
+ [Parameter] public bool IsPlaying { get; set; }
+ [Parameter] public bool IsLoaded { get; set; }
+ [Parameter] public bool IsLoading { get; set; }
+ [Parameter] public bool IsStreaming { get; set; }
+ [Parameter] public double LoadProgress { get; set; }
+ [Parameter] public double DisplayTime { get; set; }
+ [Parameter] public double? Duration { get; set; }
+ [Parameter] public EventCallback TogglePlayPause { get; set; }
+ [Parameter] public EventCallback Stop { get; set; }
+ [Parameter] public string? Class { get; set; }
+}
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor.css b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor.css
new file mode 100644
index 0000000..32d89a0
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerTransportZone.razor.css
@@ -0,0 +1,4 @@
+/* Stable minimum width so the transport cluster doesn't reflow */
+.controls-left {
+ min-width: 200px;
+}
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerWindowControls.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerWindowControls.razor
new file mode 100644
index 0000000..8f13f81
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerWindowControls.razor
@@ -0,0 +1,12 @@
+@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
+
+
+
+
+
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerWindowControls.razor.cs b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerWindowControls.razor.cs
new file mode 100644
index 0000000..de84f7c
--- /dev/null
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/PlayerWindowControls.razor.cs
@@ -0,0 +1,9 @@
+using Microsoft.AspNetCore.Components;
+
+namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
+
+public partial class PlayerWindowControls : ComponentBase
+{
+ [Parameter] public EventCallback OnMinimize { get; set; }
+ [Parameter] public EventCallback OnClose { get; set; }
+}
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/SpectrumVisualizer.razor.css b/DeepDrftPublic.Client/Controls/AudioPlayerBar/SpectrumVisualizer.razor.css
index 64dbbd2..b366fd9 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/SpectrumVisualizer.razor.css
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/SpectrumVisualizer.razor.css
@@ -26,22 +26,11 @@
min-width: 4px;
height: var(--bar-height, 2%);
min-height: 2px;
- background: var(--deepdrft-theme-secondary);
+ background: var(--mud-palette-primary);
border-radius: 2px 2px 0 0;
transition: height 0.05s ease-out;
}
-/* Charleston (Light Mode) - Iron to gold colored bars */
-:global(.deepdrft-theme-light) .spectrum-bar {
- background: linear-gradient(to top, var(--charleston-iron) 0%, var(--charleston-rose) 50%, var(--charleston-gold) 100%);
-}
-
-/* Lowcountry (Dark Mode) - Coral to gold bars with warm glow */
-:global(.deepdrft-theme-dark) .spectrum-bar {
- background: linear-gradient(to top, var(--lowcountry-coral) 0%, var(--lowcountry-gold) 100%);
- box-shadow: 0 0 4px color-mix(in srgb, var(--lowcountry-gold) 40%, transparent);
-}
-
/* Responsive adjustments */
@media (max-width: 768px) {
.spectrum-container {
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor
index 23e4fe8..7a3e522 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor
@@ -1,5 +1,5 @@
-
-
+
+
@FormatTime(CurrentTime) / @(Duration.HasValue ? FormatTime(Duration.Value) : "--:--")
-
\ No newline at end of file
+
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor.css b/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor.css
index 5c39ee9..4b1cea6 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor.css
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/TimestampLabel.razor.css
@@ -1,12 +1,5 @@
-/* TimestampLabel Component Styles */
-
-/* Timestamp display */
+/* Layout stability so the timestamp doesn't reflow as digits change */
.timestamp-display {
min-width: 120px;
text-align: center;
}
-
-/* Time text styling */
-.time-text {
- font-family: monospace;
-}
\ No newline at end of file
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor
index c2066d6..94be941 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor
@@ -1,5 +1,5 @@
-
-
+
+
-
\ No newline at end of file
+
diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor.css b/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor.css
index 7c41b24..c31db9b 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor.css
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/VolumeControls.razor.css
@@ -1,19 +1,8 @@
-/* VolumeControls Component Styles */
-
-/* Volume control container */
+/* Width caps only — layout/colour come from MudStack + theme */
.volume-controls {
- display: flex;
- align-items: center;
- gap: 0.25rem;
width: 140px;
}
-/* Volume icon styling */
-.volume-icon {
- margin-right: 4px;
-}
-
-/* Volume slider styling */
.volume-slider {
width: 100px;
-}
\ No newline at end of file
+}