diff --git a/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor b/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor
index eb568cf..50b380a 100644
--- a/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor
+++ b/DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor
@@ -20,7 +20,9 @@ else
{
var nowShowing = VisualizerControlState.TheaterMode;
+
@* Header split: meta + Play/Share on the LEFT, bordered cover on the RIGHT (spec §3.1). *@
+
+
@* Cover-as-background hero with all metadata overlaid, square `mix-hero` sizing. The
cover art IS the background, so no separate cover thumbnail (CoverThumbKey defaults
to null). Share and play ride in as slots, matching Sessions. *@
@@ -99,12 +100,15 @@ else
+
+
@* The overlay shows the cover thumbnail only when it differs from the resolved hero image —
when there is no dedicated hero, heroImage already falls back to release.ImagePath, so the
thumb would duplicate the background. That logic lives in ReleaseHeroOverlay. *@
@@ -98,6 +99,7 @@ else
+
}
diff --git a/DeepDrftPublic/wwwroot/styles/deepdrft-styles.css b/DeepDrftPublic/wwwroot/styles/deepdrft-styles.css
index 9b487be..02894bd 100644
--- a/DeepDrftPublic/wwwroot/styles/deepdrft-styles.css
+++ b/DeepDrftPublic/wwwroot/styles/deepdrft-styles.css
@@ -370,21 +370,44 @@ h2, h3, h4, h5, h6,
}
/* Eased content collapse for Theater Mode (Phase 20 Wave 2 §2). The detail content stays mounted and
- collapses to zero height (and fades) when .dd-theater-collapsed is applied, so toggling Theater eases
- both directions instead of popping — when collapsed the content is fully out of the way and the
- visualizer is unobstructed. overflow:hidden clips the content during the transition; the large open
- max-height accommodates any realistic content height (it is a ceiling, not a fixed size). The same
- pattern drives the player-bar "now showing" band so the bar grows/shrinks smoothly too. */
+ collapses smoothly when .dd-theater-collapsed is applied, so toggling Theater eases both directions
+ instead of popping — when collapsed the content is fully out of the way and the visualizer is
+ unobstructed. The same pattern drives the player-bar "now showing" band so the bar grows/shrinks
+ smoothly too.
+
+ Technique: grid-template-rows 1fr → 0fr interpolates the REAL content height (no 400vh ceiling
+ artifact / delayed-start that the old max-height approach had). The direct child receives
+ overflow:hidden + min-height:0 so it actually clips during the transition (the grid child is the
+ collapsing unit). visibility:hidden removes all descendants from the tab order and from pointer/
+ keyboard interaction once collapsed — this fixes the Major accessibility defect where Tab could
+ reach hidden controls. transition-behavior:allow-discrete makes visibility flip discretely: it
+ flips to hidden AFTER the ease-out finishes (so the animation plays fully), and flips back to
+ visible BEFORE the ease-in starts (so content is immediately interactive on the way back in).
+ The visibility transition is listed as 0s so it is instant when it fires; the allow-discrete
+ behaviour determines which end of the transition that instant flip occurs on. */
.dd-theater-collapsible {
- overflow: hidden;
- max-height: 400vh;
+ display: grid;
+ grid-template-rows: 1fr;
opacity: 1;
- transition: max-height 0.45s ease, opacity 0.3s ease;
+ visibility: visible;
+ transition: grid-template-rows 0.45s ease, opacity 0.3s ease, visibility 0s;
+ transition-behavior: allow-discrete;
+}
+
+/* The single direct child clips itself during the grid-row collapse. min-height:0 overrides the
+ implicit min-height:auto that would prevent the row from shrinking past the content's intrinsic
+ height. overflow:hidden clips painted content when the row is partially collapsed. */
+.dd-theater-collapsible > * {
+ overflow: hidden;
+ min-height: 0;
}
.dd-theater-collapsed {
- max-height: 0;
+ grid-template-rows: 0fr;
opacity: 0;
+ /* visibility flips to hidden instantly, but allow-discrete defers it to AFTER the ease-out
+ completes (at the end of the 0.45s transition), so the animation still plays in full. */
+ visibility: hidden;
}
/* Honor reduced-motion: collapse still happens (it is layout, not decoration) but instantly, matching