@@ -2955,3 +2955,148 @@ details[open] .pba-step-chev { transform: rotate(90deg); }
29552955 /* The stale dimming the other widgets get would double up on a frame that is
29562956 already empty, so the camera says it once. */
29572957 .printers-grid--plan .cam-card .is-stale { opacity : 1 ; }
2958+
2959+ /* ── The camera wall as a PLAN ───────────────────────────────────────────
2960+ Same surface as the storage and printer boards: cards placed by hand, a
2961+ scroller that pans over them, a zoom that scales the whole thing from its
2962+ top-left. The grid, the flow order and the ½×/1×/2× presets are gone — a
2963+ grip answers the size question exactly instead of in three steps. */
2964+ .cam-scroll { position : relative; overflow : auto; height : 100% ; }
2965+ .cam-wall--plan {
2966+ position : relative;
2967+ display : block; /* not a grid any more — cards are placed */
2968+ transform-origin : 0 0 ;
2969+ min-height : 240px ;
2970+ }
2971+ .cam-wall--plan .cam-wall-card {
2972+ position : absolute;
2973+ grid-column : auto; /* neutralise the old span rules */
2974+ margin : 0 ;
2975+ /* The card is only as tall as its head plus a 16:9 picture, so ONE number —
2976+ the width — describes it. */
2977+ height : auto;
2978+ }
2979+ /* No z-index here: the layout writes each card's depth inline, which this
2980+ could never outrank. The lift is done in the drag itself, on the element. */
2981+ .cam-wall--plan .cam-wall-card .is-plan-dragging { cursor : grabbing; }
2982+ .cam-wall--plan .cam-wall-card .is-plan-selected ,
2983+ .cam-wall--plan .cam-wall-card .is-resizing {
2984+ outline : 2px solid var (--primary );
2985+ outline-offset : 2px ;
2986+ }
2987+ /* The move handle sits in the head, first, exactly like a rack's and a
2988+ machine's — the card itself cannot be the handle here, because it is a video
2989+ the user will click, drag across and put fullscreen. */
2990+ /* The grip. Bottom-right, quiet until the card is hovered — a permanent
2991+ handle on every camera would read as clutter on a wall of ten. */
2992+ .cam-resize {
2993+ position : absolute; right : 0 ; bottom : 0 ;
2994+ width : 18px ; height : 18px ;
2995+ cursor : nwse-resize;
2996+ opacity : 0 ; transition : opacity .15s ;
2997+ z-index : 3 ;
2998+ }
2999+ .cam-resize ::after {
3000+ content : "" ; position : absolute; right : 3px ; bottom : 3px ;
3001+ width : 9px ; height : 9px ;
3002+ border-right : 2px solid var (--on-dark ); border-bottom : 2px solid var (--on-dark );
3003+ border-bottom-right-radius : 3px ; opacity : .75 ;
3004+ }
3005+ .cam-wall--plan .cam-wall-card : hover .cam-resize ,
3006+ .cam-wall--plan .cam-wall-card .is-resizing .cam-resize { opacity : 1 ; }
3007+ /* Fullscreen leaves the plan entirely — pinned to the window, not placed on
3008+ the surface beneath it. The layout stops writing inline geometry on this
3009+ card while it is up, which is what lets these rules apply at all. */
3010+ .cam-wall--plan .cam-wall-card--fs {
3011+ position : fixed; inset : 0 ; width : auto; height : auto;
3012+ outline : none; z-index : 2000 ;
3013+ }
3014+
3015+ /* ── Arranging the camera wall ───────────────────────────────────────────
3016+ The same mesh the storage plan draws, at the same 24 px step, scaled by the
3017+ zoom so it keeps matching the snap. Only while arranging: a wall you are
3018+ watching should show pictures, not graph paper. */
3019+ # invPrinterView .is-plan-edit .cam-scroll ,
3020+ # invPrinterView .is-plan-moving .cam-scroll {
3021+ background-attachment : local;
3022+ background-image :
3023+ linear-gradient (var (--grid-major ) 1px , transparent 1px ),
3024+ linear-gradient (90deg , var (--grid-major ) 1px , transparent 1px ),
3025+ linear-gradient (var (--grid-line ) 1px , transparent 1px ),
3026+ linear-gradient (90deg , var (--grid-line ) 1px , transparent 1px );
3027+ background-size :
3028+ calc (120px * var (--plan-z , 1 )) calc (120px * var (--plan-z , 1 )),
3029+ calc (120px * var (--plan-z , 1 )) calc (120px * var (--plan-z , 1 )),
3030+ calc (24px * var (--plan-z , 1 )) calc (24px * var (--plan-z , 1 )),
3031+ calc (24px * var (--plan-z , 1 )) calc (24px * var (--plan-z , 1 ));
3032+ }
3033+ /* Zoomed well out the fine mesh is graph paper rather than a guide. */
3034+ # invPrinterView .is-plan-coarse .is-plan-edit .cam-scroll ,
3035+ # invPrinterView .is-plan-coarse .is-plan-moving .cam-scroll {
3036+ background-image :
3037+ linear-gradient (var (--grid-major ) 1px , transparent 1px ),
3038+ linear-gradient (90deg , var (--grid-major ) 1px , transparent 1px );
3039+ background-size :
3040+ calc (120px * var (--plan-z , 1 )) calc (120px * var (--plan-z , 1 )),
3041+ calc (120px * var (--plan-z , 1 )) calc (120px * var (--plan-z , 1 ));
3042+ }
3043+ /* While arranging the card is a thing you move, so it says so — and its head
3044+ stops hiding, because that is where its name and its controls live and you
3045+ are now working with the cards rather than watching them. */
3046+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card { cursor : grab; outline : 1px solid var (--border ); }
3047+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card : hover { outline-color : var (--border-strong ); }
3048+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card-head { opacity : 1 ; }
3049+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-resize { opacity : 1 ; }
3050+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card .is-plan-dragging { cursor : grabbing; }
3051+ /* The head offers the grab, in both modes — it is the part of the card that is
3052+ not the picture, so taking hold of it is never ambiguous. */
3053+ .cam-wall--plan .cam-wall-card-head { cursor : grab; }
3054+ .cam-wall--plan .cam-wall-card-head .cam-size-btns { cursor : default; }
3055+ .cam-wall--plan .cam-wall-card .is-plan-dragging .cam-wall-card-head { cursor : grabbing; }
3056+
3057+ /* A placed camera whose machine is quiet keeps its place and its size, drawn
3058+ empty and set back. Dimmed rather than hidden: the arrangement is the point
3059+ of this view, and a card that vanished when a printer slept would take a
3060+ piece of it with it — while a solid black rectangle would read as a feed
3061+ that had failed. Its head stays reachable, so it can still be moved and
3062+ resized while the machine is off. */
3063+ .cam-wall-card--offline { opacity : .5 ; }
3064+ .cam-wall-card--offline : hover { opacity : .8 ; }
3065+ .cam-wall-offline {
3066+ width : 100% ; aspect-ratio : 16 / 9 ;
3067+ display : flex; align-items : center; justify-content : center;
3068+ background : var (--surface-2 );
3069+ border : 1px dashed var (--border-strong );
3070+ border-radius : 10px ;
3071+ }
3072+ .cam-wall-offline .icon { background : var (--muted ); opacity : .6 ; }
3073+
3074+ /* ── The states of a camera card, in the order they must win ─────────────
3075+ Arranging draws a plain border on every card, and that rule carries the
3076+ view's id — so at lower specificity a SELECTION was silently overruled by
3077+ it, and hovering a selected card overruled it again. Written here at the
3078+ same weight and after it, so the outcome is decided by this order rather
3079+ than by which selector happens to carry an extra class. Same accent, same
3080+ 2px, same offset as the storage and printer boards: a selection has to look
3081+ identical wherever it is made. */
3082+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card .is-plan-selected ,
3083+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card .is-plan-selected : hover ,
3084+ # invPrinterView .cam-wall--plan .cam-wall-card .is-plan-selected ,
3085+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card .is-resizing ,
3086+ # invPrinterView .cam-wall--plan .cam-wall-card .is-resizing {
3087+ outline : 2px solid var (--primary ); outline-offset : 2px ;
3088+ }
3089+ /* Held beats selected: while a set is moving, what is in the hand is what you
3090+ need to see. */
3091+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card .is-plan-dragging ,
3092+ # invPrinterView .is-plan-edit .cam-wall--plan .cam-wall-card .is-plan-dragging : hover ,
3093+ # invPrinterView .cam-wall--plan .cam-wall-card .is-plan-dragging {
3094+ outline : 2px solid var (--primary ); outline-offset : 2px ;
3095+ box-shadow : 0 14px 34px rgba (0 , 0 , 0 , .5 );
3096+ }
3097+
3098+ /* The alignment guides must sit above the card being dragged. On the storage
3099+ plan its cards live at a low depth, so the shared 1001 clears them; here a
3100+ held card is lifted to the front deliberately, and the guides have to clear
3101+ THAT — a guide hidden behind the thing it is guiding explains nothing. */
3102+ .cam-wall--plan .rp-plan-guides { z-index : 9500 ; }
0 commit comments