feat(ui): portable, resizable rail panels for CCTV

A drag spec can now be `portable`: dragging the panel by its header lifts
it out of the right rail into a fixed window, resizable from all four
edges and corners, that remembers its place and size under the existing
godsEyeView.v8.panelPos.<id> key ({ left, top, width?, height?, floating })
and snaps back on a header double-click. Only CCTV opts in here; the rail
skips .panel-floating panels when measuring and allocating, and its
placement rules in layers.css are guarded so no !important is needed.
PanelPositionControls gains an optional onPanelResized hook, threaded
through PanelChrome to a no-op on the application shell.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Fable 5.1 committed 2026-09-23 15:21:21 +01:00
1 parent 317c0a7e0c
commit 96a1e710ea
9 files changed
+525 -26

No files matched your search

+12 -8
View File
@@ -161,7 +161,7 @@
max-height var(--transition-fast);
}
#right-context-rail > #pp-toggles,
#right-context-rail > #cctv-panel,
#right-context-rail > #cctv-panel:not(.panel-floating),
#right-context-rail > #global-context-panel {
position: relative;
inset: auto;
@@ -173,12 +173,12 @@
max-height: 100%;
pointer-events: auto;
}
#right-context-rail #cctv-panel {
#right-context-rail #cctv-panel:not(.panel-floating) {
width: 100%;
max-height: 100%;
pointer-events: auto;
}
#right-context-rail #cctv-panel.collapsed {
#right-context-rail #cctv-panel.collapsed:not(.panel-floating) {
width: var(--right-display-collapsed-width);
margin-left: auto;
}
@@ -234,18 +234,22 @@
#right-context-rail.layout-focus {
height: var(--right-stack-max-height);
}
#right-context-rail.layout-exclusive > [data-panel-id].collapsed {
#right-context-rail.layout-exclusive
> [data-panel-id].collapsed:not(.panel-floating) {
display: none;
}
#right-context-rail.layout-focus > [data-panel-id].collapsed {
#right-context-rail.layout-focus
> [data-panel-id].collapsed:not(.panel-floating) {
display: block;
flex: 0 0 auto;
}
#right-context-rail.layout-focus.layout-exclusive > [data-panel-id].collapsed {
#right-context-rail.layout-focus.layout-exclusive
> [data-panel-id].collapsed:not(.panel-floating) {
display: none;
}
#right-context-rail.layout-focus > #pp-toggles:not(.collapsed),
#right-context-rail.layout-focus > #cctv-panel:not(.collapsed),
#right-context-rail.layout-focus
> #cctv-panel:not(.collapsed):not(.panel-floating),
#right-context-rail.layout-focus > #global-context-panel:not(.collapsed) {
flex: 0 1 var(--right-panel-allocated-height);
height: var(--right-panel-allocated-height);
@@ -259,7 +263,7 @@
scrollbar-color: rgba(0, 212, 255, 0.4) transparent;
}
#right-context-rail.layout-focus
> #cctv-panel:not(.collapsed)
> #cctv-panel:not(.collapsed):not(.panel-floating)
.cctv-panel-inner,
#right-context-rail.layout-focus
> #global-context-panel:not(.collapsed)