diff --git a/lab/control/ui/app.js b/lab/control/ui/app.js index 49d2f1e..74d4a59 100644 --- a/lab/control/ui/app.js +++ b/lab/control/ui/app.js @@ -391,6 +391,24 @@ root.setProperty("--pad-t", Math.round(covered.top) + "px"); /* The floating panels clear the ladder; the camera, above, does not. */ root.setProperty("--pad-b", Math.round(padBottom) + "px"); + /* The bottom edge is the only one that needs saying twice. --pad-l, -r + and -t are the same number against either rectangle, because the + viewport starts at the top-left corner of the window and the rails are + drawn over it. The bottom is where the two part company, and which one + a rule wants depends on what it is positioned inside: + + --pad-b against the window. The page verdict and anything + else that sits in .app, which the ladder is in. + --pad-b-canvas against the board. The HUD overlay is laid out + inside .viewport, whose bottom edge is already above + the ladder — so clearing the ladder a second time + lifts the verdict a whole ladder higher than the card + it only had to clear by a gap. + + Same number the camera is handed, for the same reason: it is what + covers the board rather than what is occupied at the foot of the + window. */ + root.setProperty("--pad-b-canvas", Math.round(covered.bottom) + "px"); if (board && board.setViewInset) board.setViewInset(covered); } diff --git a/lab/control/ui/replay-app.js b/lab/control/ui/replay-app.js index d9715da..e763e9b 100644 --- a/lab/control/ui/replay-app.js +++ b/lab/control/ui/replay-app.js @@ -218,6 +218,11 @@ root.setProperty("--pad-r", Math.round(covered.right) + "px"); root.setProperty("--pad-t", Math.round(covered.top) + "px"); root.setProperty("--pad-b", Math.round(padBottom) + "px"); + /* The camera's answer, published, because the HUD overlay is laid out + inside the viewport and so wants the same one: what covers the *board* + — here the transport and whatever the docks hide — and not the ladder + below it. Why only this edge needs a second token is in app.js. */ + root.setProperty("--pad-b-canvas", Math.round(covered.bottom) + "px"); if (board && board.setViewInset) board.setViewInset(covered); } diff --git a/lab/control/ui/style.css b/lab/control/ui/style.css index 26eed98..d49745d 100644 --- a/lab/control/ui/style.css +++ b/lab/control/ui/style.css @@ -613,6 +613,16 @@ pre.out.live { max-height: 38vh; overflow-y: auto; } position: absolute; inset: 0; pointer-events: none; padding: 12px calc(var(--pad-r, 0px) + 12px) 12px calc(var(--pad-l, 0px) + 12px); padding-top: calc(var(--pad-t, 0px) + 12px); + /* The fourth side, and it reads a different token from the other three. + Those are the same number against the window or against the board; this + one is not, because the rung ladder is below the viewport rather than + over it. --pad-b clears the ladder — right for .verdict, which is in + .app — and this box is inside .viewport, whose bottom edge is already + above the ladder. --pad-b-canvas is the number measured there, so the + verdict and the transcript stop on top of a bottom-docked card rather + than under it, and without a whole ladder of dead air when nothing is + docked at all. */ + padding-bottom: calc(var(--pad-b-canvas, 0px) + 12px); display: grid; grid-template-rows: auto 1fr auto; gap: 8px; transition: padding .18s ease; }