diff --git a/plugin-designs/plugin-studio/plugin-studio.vue b/plugin-designs/plugin-studio/plugin-studio.vue index c4b7937d3..65033089e 100644 --- a/plugin-designs/plugin-studio/plugin-studio.vue +++ b/plugin-designs/plugin-studio/plugin-studio.vue @@ -190,7 +190,16 @@ const PS_SHADOW_CSS = ` to own that scroll itself. auto, not scroll: only a pane whose content really exceeds its box gets a scrollbar, so the map tabs stay scrollbar-free (see the dvh floor note below, which is what makes that true). */ -.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } +.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; + /* ★ THE OTHER HALF of the dvh neutraliser, and the half that actually works. Sizing the host + is not enough: .profile-loader lives inside the map's SHADOW ROOT at min-height:100dvh, and + a host-page selector cannot reach into a shadow tree. INHERITED properties can, so + ProfileLoader.vue reads min-height:var(--profile-min-h, 100dvh) and the pane sets it to 0. + The floor keeps its default everywhere else, including every standalone leaf where it still + fixes BUG-UPG100-NESTED-ELEMENTS-ZERO-HEIGHT. Without this line a MAP tab is 131px taller + than its pane (900 viewport vs 769 pane) and overflow-y:auto correctly grows a scrollbar on + a tab that should never have one. Measured; check:shell-scroll asserts it. */ + --profile-min-h: 0; } /* NOT absolute-inset: that pinned the mount point to the pane's height and re-created the same trap one level down (an absolutely positioned child cannot grow a scroll container). min-height:100% keeps a fixed-viewport map filling the pane while letting a taller composite grow it. */ @@ -631,7 +640,16 @@ export default defineComponent({ position:absolute; inset:0 with the default overflow:visible inside an overflow:hidden stage. auto, not scroll: a fixed-viewport map fills the box exactly and gets NO scrollbar, so the map tabs are untouched. */ -.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } +.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; + /* ★ THE OTHER HALF of the dvh neutraliser, and the half that actually works. Sizing the host + is not enough: .profile-loader lives inside the map's SHADOW ROOT at min-height:100dvh, and + a host-page selector cannot reach into a shadow tree. INHERITED properties can, so + ProfileLoader.vue reads min-height:var(--profile-min-h, 100dvh) and the pane sets it to 0. + The floor keeps its default everywhere else, including every standalone leaf where it still + fixes BUG-UPG100-NESTED-ELEMENTS-ZERO-HEIGHT. Without this line a MAP tab is 131px taller + than its pane (900 viewport vs 769 pane) and overflow-y:auto correctly grows a scrollbar on + a tab that should never have one. Measured; check:shell-scroll asserts it. */ + --profile-min-h: 0; } /* NOT absolute-inset: that pinned the mount point to the pane's height and re-created the trap one level down. min-height:100% keeps a map filling the pane while letting a taller composite grow it. */ .ps-slot { position: absolute; inset: 0; }