diff --git a/.changeset/tablet-floating-window-right-inset-and-drag.md b/.changeset/tablet-floating-window-right-inset-and-drag.md index 26ac25c4f5..ad34d04ab5 100644 --- a/.changeset/tablet-floating-window-right-inset-and-drag.md +++ b/.changeset/tablet-floating-window-right-inset-and-drag.md @@ -4,4 +4,4 @@ summary: Fix uneven right padding on tablet task/terminal popups; drag the terminal from anywhere in its toolbar. category: fix -dev: Tablet-mode FloatingWindows (`.floating-window--tablet`) zero the FN-8015 scrollbar gutter; GitHub-import detail compensates locally. Terminal tab-strip empty space now bubbles to the `.terminal-header` drag handle (`touch-action: none` on the tablet floating header supersedes the FN-8633 pan-x contract). +dev: Tablet-mode FloatingWindows (`.floating-window--tablet-viewport`) zero the FN-8015 scrollbar gutter; GitHub-import detail compensates locally. Terminal tab-strip empty space now bubbles to the `.terminal-header` drag handle (`touch-action: none` on the tablet floating header supersedes the FN-8633 pan-x contract). diff --git a/packages/dashboard/app/components/FloatingWindow.css b/packages/dashboard/app/components/FloatingWindow.css index 60d5f60766..1d54a6f0ce 100644 --- a/packages/dashboard/app/components/FloatingWindow.css +++ b/packages/dashboard/app/components/FloatingWindow.css @@ -545,13 +545,13 @@ Tablet windows drop FN-8015's inline-end scrollbar gutter. On tablet the gutter too-big, uneven right border inside Task Detail popups and the floating terminal (the inner surfaces already carry their own symmetric padding), and the mouse conflict FN-8015 solves — grabbing a hosted scrollbar thumb versus the east resize hot zone — does not apply to touch -input, which never grabs scrollbar thumbs. This keys on tablet MODE (`.floating-window--tablet`, +input, which never grabs scrollbar thumbs. This keys on tablet MODE (`.floating-window--tablet-viewport`, set from `useViewportMode()`), not `--touch-geometry`, so a non-touch window at tablet widths gets the same symmetric inset the operator sees on an iPad. Desktop keeps the FN-8015 gutter. Callers that relied on the gutter as their right inset must compensate under the same class (see `.github-import-detail-panel`). */ -.floating-window--tablet .floating-window__body { +.floating-window--tablet-viewport .floating-window__body { margin-inline-end: 0; } diff --git a/packages/dashboard/app/components/FloatingWindow.tsx b/packages/dashboard/app/components/FloatingWindow.tsx index 1431181356..034921bf33 100644 --- a/packages/dashboard/app/components/FloatingWindow.tsx +++ b/packages/dashboard/app/components/FloatingWindow.tsx @@ -233,15 +233,19 @@ export function FloatingWindow({ */ const hasTabletTouchGeometry = isTabletTouchViewport(viewportMode); /* - FNXC:ModalTouchGeometry 2026-08-01-03:48: - Tablet MODE (touch or not) is a distinct styling surface from touch geometry: a 900px - non-touch window classifies tablet without `--touch-geometry`, yet operators still see the - FN-8015 scrollbar gutter as an uneven right inset there (third recurrence of the Task Detail - right-padding bug — FN-8630/FN-8634 fixed only the `.modal-overlay` shells, while every - tablet task popup and floating terminal renders through THIS host). Expose the mode as a - class so FloatingWindow.css can zero the gutter for all tablet windows. + FNXC:ModalTouchGeometry 2026-08-01-04:23: + NAMING CONTRACT — FloatingWindow has two distinct tablet markers; do not conflate them: + - `floating-window--tablet-viewport`: the viewport MODE classifies as tablet (769-1024px + width OR a known 768px touch tablet), touch or not. Pure styling surface — currently the + FN-8015 gutter zeroing lives here. + - `floating-window--touch-geometry`: tablet AND touch-capable (`isTabletTouchViewport`) — + enlarged 44px drag/resize targets only. + A 900px non-touch window is `--tablet-viewport` but NOT `--touch-geometry`, and operators + still see the FN-8015 scrollbar gutter as an uneven right inset there (third recurrence of + the Task Detail right-padding bug — FN-8630/FN-8634 fixed only the `.modal-overlay` shells, + while every tablet task popup and floating terminal renders through THIS host). */ - const isTabletMode = viewportMode === "tablet"; + const isTabletViewportMode = viewportMode === "tablet"; const initialGeometry = useRef<{ size: FloatingWindowSize; position: FloatingWindowPosition } | null>(null); /* FNXC:ModalGeometryPersistence 2026-07-16-00:40: @@ -648,7 +652,7 @@ export function FloatingWindow({ >
{ */ const tabletBody = cssRuleContaining( floatingWindowCss, - ".floating-window--tablet .floating-window__body", + ".floating-window--tablet-viewport .floating-window__body", "margin-inline-end", ); expect(tabletBody).toContain("margin-inline-end: 0;"); const tabletGitHubImportPanel = cssRuleContaining( allAppCss, - ".floating-window--tablet .github-import-detail-panel", + ".floating-window--tablet-viewport .github-import-detail-panel", "padding-inline-end", ); expect(tabletGitHubImportPanel).toContain("padding-inline-end: var(--space-lg);"); @@ -251,10 +251,10 @@ describe("FloatingWindow", () => { /* FNXC:ModalTouchGeometry 2026-08-01-03:48: Tablet MODE is its own styling marker, distinct from `--touch-geometry`: a non-touch window - at tablet widths must still receive `floating-window--tablet` so the FN-8015 gutter zeroing + at tablet widths must still receive `floating-window--tablet-viewport` so the FN-8015 gutter zeroing applies everywhere the app classifies the viewport as tablet. */ - it("marks tablet-mode windows with floating-window--tablet even without touch", () => { + it("marks tablet-mode windows with floating-window--tablet-viewport even without touch", () => { vi.stubGlobal("matchMedia", vi.fn((query: string) => ({ matches: query === "(min-width: 769px) and (max-width: 1024px)", media: query, @@ -271,7 +271,7 @@ describe("FloatingWindow", () => { ); const panel = screen.getByTestId("floating-window-tablet-mode"); - expect(panel.className).toContain("floating-window--tablet"); + expect(panel.className).toContain("floating-window--tablet-viewport"); }); it("keeps task-detail long content clear of right handles while preserving short-content right-edge resize", () => {