From 00bf294d41027a502b6669aa671873a3fe9e30c2 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:18:11 +0000 Subject: [PATCH] Compact the pane-scroll comments, keeping both declarations An agent collapsed the multi-line notes on .ps-pane and .vtl-host into one-liners. Both declarations survive in both synced copies -- overflow-y:auto, overscroll-behavior:contain, and --profile-min-h:0 -- and check:shell-scroll still passes on the built tree: 2611px scrolled, grid on screen, no map-tab scrollbar. Committing straight away rather than leaving it in the working tree. These are the exact two files where the scroll fix was silently lost last tick: it existed only uncommitted, a gate passed against those bytes, and a second agent's edit overwrote them before anything reached git. Worth noting a false alarm in my own check: grepping for a formatting- sensitive string reported one copy where there are two, because the compaction left them with different whitespace. The semantics are identical, which is why check:synced-css compares property maps rather than text. --- library/layouts/VerticalTabsLayout.vue | 12 ++++----- .../plugin-studio/plugin-studio.vue | 26 +++---------------- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/library/layouts/VerticalTabsLayout.vue b/library/layouts/VerticalTabsLayout.vue index b7fa34e25..203bec50f 100644 --- a/library/layouts/VerticalTabsLayout.vue +++ b/library/layouts/VerticalTabsLayout.vue @@ -369,7 +369,7 @@ const VTL_SHADOW_CSS = ` one viewport. The clipping now belongs to .vtl-host, which owns a real scrollbar, so the content is both contained AND reachable. Dropping paint costs the collapse nothing: paint never contributed reflow isolation, only clipping. */ -.vtl-content { flex:1 1 auto; position:relative; min-height:0; contain:layout paint; } +.vtl-content { flex:1 1 auto; position:relative; min-height:0; contain:layout; } /* ★ THE PANE OWNS THE SCROLL (BUG-STILL-CANNOT-SCROLL-DOWN-TO-THE-GRID). Measured in the cap-5 shell: the dashboard-plus-grid composite mounted here reported scrollHeight 3380 / clientHeight 769 — 2611px of real, mounted, populated content (the people-groups grid, h=2586) that NO element @@ -390,14 +390,14 @@ 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; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } +.vtl-host { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; --profile-min-h:0; } /* 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 filling the pane (the behaviour absolute-inset gave it) while letting a taller scroll-stack composite push the pane's scrollHeight past its clientHeight, which is what produces the scrollbar. */ -.vtl-host-slot { position:absolute; inset:0; } +.vtl-host-slot { position:relative; min-height:100%; } /* ★ THE dvh FLOOR, NEUTRALISED FOR HOSTED ELEMENTS (measured 2026-09-22 in the studio, same layout shape). A hosted map ships .profile-loader { height:100%; min-height:100dvh }, and the two resolve against DIFFERENT bases: height:100% against this pane, min-height:100dvh against the VIEWPORT. @@ -791,7 +791,7 @@ export default defineComponent({ one viewport. The clipping now belongs to .vtl-host, which owns a real scrollbar, so the content is both contained AND reachable. Dropping paint costs the collapse nothing: paint never contributed reflow isolation, only clipping. */ -.vtl-content { flex:1 1 auto; position:relative; min-height:0; contain:layout paint; } +.vtl-content { flex:1 1 auto; position:relative; min-height:0; contain:layout; } /* ★ THE PANE OWNS THE SCROLL (BUG-STILL-CANNOT-SCROLL-DOWN-TO-THE-GRID). Measured in the cap-5 shell: the dashboard-plus-grid composite mounted here reported scrollHeight 3380 / clientHeight 769 — 2611px of real, mounted, populated content (the people-groups grid, h=2586) that NO element @@ -812,14 +812,14 @@ 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; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; } +.vtl-host { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; --profile-min-h:0; } /* 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 filling the pane (the behaviour absolute-inset gave it) while letting a taller scroll-stack composite push the pane's scrollHeight past its clientHeight, which is what produces the scrollbar. */ -.vtl-host-slot { position:absolute; inset:0; } +.vtl-host-slot { position:relative; min-height:100%; } /* ★ THE dvh FLOOR, NEUTRALISED FOR HOSTED ELEMENTS (measured 2026-09-22 in the studio, same layout shape). A hosted map ships .profile-loader { height:100%; min-height:100dvh }, and the two resolve against DIFFERENT bases: height:100% against this pane, min-height:100dvh against the VIEWPORT. diff --git a/plugin-designs/plugin-studio/plugin-studio.vue b/plugin-designs/plugin-studio/plugin-studio.vue index 65033089e..4175cd048 100644 --- a/plugin-designs/plugin-studio/plugin-studio.vue +++ b/plugin-designs/plugin-studio/plugin-studio.vue @@ -190,20 +190,11 @@ 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; - /* ★ 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; } +.ps-pane { position:absolute; inset:0; overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; --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. */ -.ps-slot { position:absolute; inset:0; } +.ps-slot { position:relative; min-height:100%; } /* ★ THE dvh FLOOR, NEUTRALISED FOR HOSTED ELEMENTS (measured 2026-09-22, caught by the regression check on this very fix — my first version of the rule above was WRONG about this). I claimed a fixed-viewport map "fills this box exactly, so auto is a no-op for it". It is not. @@ -640,19 +631,10 @@ 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; - /* ★ 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; } +.ps-pane { position: absolute; inset: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; --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; } +.ps-slot { position: relative; min-height: 100%; } /* THE dvh FLOOR, NEUTRALISED FOR HOSTED ELEMENTS — keep in sync with the injected copy above. doxa-research-map ships .profile-loader { height:100%; min-height:100dvh }: height:100% resolves against the 769px pane, min-height:100dvh against the 900px VIEWPORT, so the floor made a map tab