From 043b40ddbd65783d1ee477b28d812c9ddf8ba719 Mon Sep 17 00:00:00 2001 From: doxa-maps-88655c70 <88627970+doxa-maps-88655c70@users.noreply.github.com> Date: Tue, 22 Sep 2026 19:04:21 +0000 Subject: [PATCH] Give the shell pane its scrollport back check:shell-scroll went back to "wheel moved 0px, grid UNREACHABLE" with 2586px of grid mounted. The cause is not a later edit undoing a committed fix: git history shows .vtl-host never had overflow-y:auto in any commit. Seven commits, all `position:absolute; inset:0`. The fix only ever existed in a working tree. An agent edited the file live, the gate passed against those uncommitted bytes, and a second agent editing the same file overwrote them before anything was committed. Every observation was true and none of it was durable. Worse, 762953a was committed while the tree was in the reverted state and described as landing the scroll fix. Restored on .vtl-host and .ps-pane, both synced copies of each, and the reason is now in the file rather than in a session transcript: the composite reports scrollHeight 2838 against clientHeight 769 here, 2069px of mounted grid with nowhere to go, while the document measures 900 === 900 so a wheel anywhere has nothing to move. It is a host gap, not a plugin bug -- the same composite is perfect standalone because its generated leaf gives the document the scroll. The comment says the line has been lost once and points at the gate, because `inset:0` looks like the simpler form and someone will reach for it again. Committing before re-verifying, deliberately. A gate result is only as durable as the bytes it ran against, and this bug is the proof. --- library/layouts/VerticalTabsLayout.vue | 4 ++-- plugin-designs/plugin-studio/plugin-studio.vue | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/layouts/VerticalTabsLayout.vue b/library/layouts/VerticalTabsLayout.vue index 7db421ffa..b7fa34e25 100644 --- a/library/layouts/VerticalTabsLayout.vue +++ b/library/layouts/VerticalTabsLayout.vue @@ -390,7 +390,7 @@ const VTL_SHADOW_CSS = ` composite that is meant to scroll — gets one. auto is load-bearing; scroll would paint a dead scrollbar on all 19 map tabs. overscroll-behavior:contain stops a wheel that bottoms out here from chaining to the document. */ -.vtl-host { position:absolute; inset:0; } +.vtl-host { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } /* The slot is the element's mount point. It must NOT be position:absolute; inset:0 any more: that pinned it to the pane's height and re-created the exact trap one level down — an absolutely positioned child cannot grow a scroll container. min-height:100% keeps a fixed-viewport map @@ -812,7 +812,7 @@ export default defineComponent({ composite that is meant to scroll — gets one. auto is load-bearing; scroll would paint a dead scrollbar on all 19 map tabs. overscroll-behavior:contain stops a wheel that bottoms out here from chaining to the document. */ -.vtl-host { position:absolute; inset:0; } +.vtl-host { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } /* The slot is the element's mount point. It must NOT be position:absolute; inset:0 any more: that pinned it to the pane's height and re-created the exact trap one level down — an absolutely positioned child cannot grow a scroll container. min-height:100% keeps a fixed-viewport map diff --git a/plugin-designs/plugin-studio/plugin-studio.vue b/plugin-designs/plugin-studio/plugin-studio.vue index a00be034c..c4b7937d3 100644 --- a/plugin-designs/plugin-studio/plugin-studio.vue +++ b/plugin-designs/plugin-studio/plugin-studio.vue @@ -190,7 +190,7 @@ 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; } +.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } /* 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 +631,7 @@ 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; } +.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } /* 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; }