From 8b9cf3d4e877ec2fd77467b6b69e9e76f20d9f0d Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sun, 26 Jul 2026 00:00:19 -0700 Subject: [PATCH] fix(dashboard): remove right-edge dead space on landscape-tablet task pop-ups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `.floating-window__body` resize-handle clearance gutter (FN-8015) was carved out only for 769-1024px, so landscape iPads (1180-1366 CSS px) fell through to the desktop contract and kept it — content stopped ~17px short of the right edge while the left edge stayed flush. Gate the carve-out on the input device instead of viewport width: the gutter only protects resize hot zones a pointer can actually grab. `(pointer: coarse)` is primary-input only, so a touchscreen laptop on a trackpad still reports `fine` and keeps desktop clearance. Measured at 1180px: header inset went from 1px/17px to 1px/1px. Co-Authored-By: Claude Opus 5 (1M context) --- .changeset/tablet-task-popup-right-inset.md | 7 ++++ .../app/components/FloatingWindow.css | 16 +++++++++ .../__tests__/FloatingWindow.test.tsx | 33 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 .changeset/tablet-task-popup-right-inset.md diff --git a/.changeset/tablet-task-popup-right-inset.md b/.changeset/tablet-task-popup-right-inset.md new file mode 100644 index 0000000000..e5cc204945 --- /dev/null +++ b/.changeset/tablet-task-popup-right-inset.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Remove the dead space on the right edge of the task pop-up on landscape tablets. +category: fix +dev: The `.floating-window__body` resize-handle clearance gutter was width-gated to 769-1024px; a new `@media (pointer: coarse)` block zeroes it (and hides the resize handles) for `.floating-window--task-detail` at any width, covering iPad Air/Pro landscape at 1180-1366 CSS px. diff --git a/packages/dashboard/app/components/FloatingWindow.css b/packages/dashboard/app/components/FloatingWindow.css index a812a8012d..55e1d2086c 100644 --- a/packages/dashboard/app/components/FloatingWindow.css +++ b/packages/dashboard/app/components/FloatingWindow.css @@ -120,6 +120,22 @@ Tablet task-detail popups prioritize symmetric content insets over desktop resiz } } +/* +FNXC:FloatingWindow 2026-07-25-00:00: +The tablet carve-out above is width-gated at 1024px, so a landscape tablet (iPad Air/Pro report 1180-1366 CSS px) fell back to the desktop contract and kept FN-8015's `margin-inline-end: var(--space-lg)` body gutter — content stopped ~17px short of the right edge while the left edge stayed flush, reading as unexplained dead space on the right of the task pop-up. +Width cannot answer this: the gutter exists to keep a hosted scrollbar out of the east/north-east/south-east resize hot zones, which only matters when a pointer can actually grab them. Gate the carve-out on the input device instead, so every touch-primary tablet gets symmetric insets at any width. `(pointer: coarse)` is primary-input only, so a touchscreen laptop driven by a trackpad still reports `fine` and keeps desktop resize clearance. +Kept as a separate block rather than folded into the width query so the existing 769-1024px contract stays independently addressable. +*/ +@media (pointer: coarse) { + .floating-window--task-detail .floating-window__body { + margin-inline-end: 0; + } + + .floating-window--task-detail .floating-window__resize-handle { + display: none; + } +} + /* FNXC:ChatModal 2026-06-22-14:49: On mobile/narrow app viewports, opening Quick Chat should present the full Chat modal as a full-screen sheet instead of a small draggable desktop window. Scope this to the chat FloatingWindow and override the inline desktop geometry only at the mobile breakpoint; desktop pop-out behavior remains movable/resizable. diff --git a/packages/dashboard/app/components/__tests__/FloatingWindow.test.tsx b/packages/dashboard/app/components/__tests__/FloatingWindow.test.tsx index a7f3cb4cd1..2a333b73ed 100644 --- a/packages/dashboard/app/components/__tests__/FloatingWindow.test.tsx +++ b/packages/dashboard/app/components/__tests__/FloatingWindow.test.tsx @@ -198,6 +198,39 @@ describe("FloatingWindow", () => { expect(cssRuleFor(floatingWindowCss, ".floating-window--chat.floating-window--headerless .floating-window__body")).toContain("overflow: hidden;"); }); + /* + FNXC:FloatingWindow 2026-07-25-00:00: + Regression guard for the landscape-tablet right-inset gap: the width-gated + 769-1024px carve-out let iPad Air/Pro landscape (1180-1366 CSS px) fall back to + the desktop contract and keep FN-8015's body gutter, so the task pop-up's + content stopped short of the right edge while the left edge stayed flush. + Assert the input-device-gated block covers the same two declarations at ANY + width, and that it stays scoped to task-detail so other floating-window callers + (whose right resize handles remain live) keep their scrollbar clearance. + */ + it("removes task-detail resize clearance on touch-primary pointers at any width", () => { + const coarseBlock = mediaBlockFor(floatingWindowCss, "(pointer: coarse)"); + + expect(coarseBlock).not.toBe(""); + expect(cssRuleFor(coarseBlock, ".floating-window--task-detail .floating-window__body")).toContain("margin-inline-end: 0;"); + expect(cssRuleFor(coarseBlock, ".floating-window--task-detail .floating-window__resize-handle")).toContain("display: none;"); + + // The carve-out is task-detail only: every other shared caller keeps the gutter. + for (const callerClass of [ + "floating-window--automation", + "floating-window--mission-interview", + "floating-window--pr-create", + "floating-window--file-browser", + "floating-window--workflow-editor", + "artifacts-gallery-window", + ]) { + expect(cssRulesForClass(coarseBlock, callerClass), callerClass).toHaveLength(0); + } + + // No width bound may creep back into the coarse-pointer query. + expect(floatingWindowCss).toContain("@media (pointer: coarse) {"); + }); + it("removes only tablet task-detail resize clearance and handles for empty and populated popups", () => { const tabletBlock = mediaBlockFor(floatingWindowCss, "(min-width: 769px) and (max-width: 1024px)"); const mobileBlock = mediaBlockFor(floatingWindowCss, "(max-width: 768px)");