fix(ui): #542 landing fixes

Follow the keyboard: the menu's cap now uses var(--app-height, 100dvh)
instead of 100dvh. The viewport meta has no interactive-widget, so dvh does
not shrink for an on-screen keyboard, while MobileDetection always sets
--app-height to the visual viewport height and KeyboardHandler keeps it there
while the keyboard is up (body and .app already size the same way).

Subtract both safe areas from the cap: in the iPhone home-screen app the
phone header grows by the top inset and the toolbar sits above the bottom
inset, so without them the top of a full menu slid under the fixed header.

Add overflow-x: hidden. overflow-y: auto computes overflow-x to auto, so a
long nowrap custom-endpoint label showed a horizontal scrollbar that
touch-action: pan-y cannot pan (the same trap the file documents for
.run-mode-history).

Raise the toolbar while the Run menu is open, by adding
.toolbar:has(.run-mode-menu.active) to the existing popover raise rule. The
menu is trapped in the toolbar's stacking context, so on a touch device the
keyboard accessory bar (z 51) and the visible CJK input (z 52) covered its
last rows even when scrolled to the end. This follows the rule the case
settings popover and case combobox already use.

Reword the rule's comment: it claimed dvh follows the keyboard and that the
vh line is a fallback, and neither is true (a declaration carrying var() is
never dropped at parse time). The new text has no braces and no max-height
text, which the gate test's rule() slicer depends on.

Pin the fixes in the gate test (the --app-height and safe-area terms,
overflow-x: hidden, the toolbar raise) and retitle the cap test so it no
longer names dvh as the mechanism. The test now strips CSS comments before
reading the rule, since the rule's own comment names overflow-y: auto and
touch-action: pan-y and would otherwise keep those assertions green after the
declarations were deleted (checked by deleting them: the test now fails).

Drop .changeset/run-menu-scroll.md: it repeated the false dvh claim, and the
release writes one consolidated changeset at COM.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-10-09 05:02:27 +02:00
parent e5417310f8
commit ce6e4cc6e6
3 changed files with 36 additions and 12 deletions
+14 -5
View File
@@ -5355,7 +5355,8 @@ html[data-skin="og"] .welcome-primary:hover {
z-index inside the toolbar. When the popover is open, raise the toolbar
above the CJK input (z-index 52) so the popover is interactable. */
.toolbar:has(.case-settings-popover:not(.hidden)),
.toolbar:has(.case-combobox-list:not(.hidden)) {
.toolbar:has(.case-combobox-list:not(.hidden)),
.toolbar:has(.run-mode-menu.active) {
z-index: 100;
}
@@ -5651,11 +5652,19 @@ html[data-skin="og"] .welcome-primary:hover {
endpoint entries, Terminal and the saved URLs it can be taller than the room above the
toolbar: its top then sits off-screen with nothing to scroll, and the entries up there
cannot be reached (worst on a phone). Cap it to the space between the header and the
toolbar and scroll inside it. `dvh` so an on-screen keyboard or a collapsing browser bar
shrinks the cap with it; the `vh` line is the fallback for browsers without it. */
max-height: calc(100vh - var(--header-height) - var(--toolbar-height) - 16px);
max-height: calc(100dvh - var(--header-height) - var(--toolbar-height) - 16px);
toolbar and scroll inside it. The cap follows --app-height, not `dvh`: the viewport meta
has no interactive-widget, so `dvh` does not shrink for an on-screen keyboard, while
MobileDetection always sets --app-height to the visual viewport height and KeyboardHandler
keeps it there while the keyboard is up. Both safe areas come off too, because the phone
header and toolbar grow by them in the iPhone home-screen app. The second line is the one
that applies (a declaration carrying var() is never dropped at parse time, so the first
line is not a working fallback for it; it stays only as the plain-viewport form). */
max-height: calc(100vh - var(--header-height) - var(--safe-area-top) - var(--toolbar-height) - var(--safe-area-bottom) - 16px);
max-height: calc(var(--app-height, 100dvh) - var(--header-height) - var(--safe-area-top) - var(--toolbar-height) - var(--safe-area-bottom) - 16px);
overflow-y: auto;
/* overflow-y: auto computes overflow-x to auto as well, so a long nowrap custom-endpoint
label would show a horizontal scrollbar that touch-action: pan-y cannot pan. */
overflow-x: hidden;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
touch-action: pan-y;