fix: Engine Control popover collapsed to ~trigger width (FN-8802 .card clamp) (#3363)

## What & why

RUFU-042. The open **Engine Controls** popover (footer status bar,
bottom-right) carries the shared `.card` class. Since FN-8802, `.card`
bases set `min-width: 0; max-width: 100%` (TaskCard.css). The popover's
containing block (`.engine-control-menu`) sizes to the narrow trigger
button, so `.card`'s `max-width: 100%` clamped the intended `24rem` grid
down to ~the trigger's width — a **~5mm-wide invisible popover**.

## Fix (CSS only, `EngineControlMenu.css`)

- Footer-scoped desktop rule (`0,3,0`) re-asserts
`min-width`/`max-width` clamped to the **viewport** (not the trigger
wrapper), deterministically beating the shared `.card` (`0,1,0`) by
specificity — same pattern as `.selection-comment-panel.card`.
- Mobile `@media (max-width:1024px)` resets `min-width:0;
max-width:none` so the full-width gutter panel cannot overflow nor be
re-clamped by `.card`.
- No `className="card"` removal; shared `.card` base untouched.

## Regression tests

Two new tests in `EngineControlMenu.test.tsx` assert the desktop min/max
guard and the mobile reset, so the collapse cannot silently return.
**17/17 tests pass.**

No changeset (`@fusion/dashboard` is a private package).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved engine control popovers so they size correctly without
collapsing or overflowing.
* Enhanced mobile layouts to maintain full-width display with
appropriate screen gutters.

* **Tests**
* Added regression coverage for desktop width limits and narrow-screen
popover behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Fusion <noreply@runfusion.ai>
Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>
This commit is contained in:
ischindl
2026-08-10 01:49:56 +02:00
committed by GitHub
parent 50311a88d6
commit 3766dfc2a7
2 changed files with 55 additions and 0 deletions

View File

@@ -2,8 +2,24 @@
position: relative;
display: inline-flex;
align-items: center;
width: max-content;
}
/*
FNXC:EngineControls 2026-08-08-15:40 (FN-8802 width-collapse regression, RUFU-042):
The open popover carries the shared `.card` class, whose base now sets `min-width: 0` and
`max-width: 100%` (FN-8802, TaskCard.css). Its containing block is this `.engine-control-menu`
wrapper, which sizes to the narrow trigger button; `.card`'s `max-width: 100%` therefore
clamped the intended grid width down to ~the trigger's width (~5mm), hiding all content.
The selected text (width/min-width/max-width) below must beat `.card` deterministically, so it
targets the popover in its only real mount context (the ExecutorStatusBar footer segment) with
higher specificity — the same pattern used by `.selection-comment-panel.card`. `max-width` is
clamped to the VIEWPORT (not the trigger wrapper), `min-width` sets the floor so it can never
collapse to a sliver, and the footer-scoped overrides re-assert the width so later `.card` rules
cannot win by load order.
*/
.engine-control-menu__trigger {
color: var(--text-muted);
}
@@ -186,9 +202,15 @@ FN-8007 defines both desktop pseudo-thumbs locally with the marker's shared size
}
.executor-status-bar__segment--engine-controls .engine-control-menu > .engine-control-menu__popover.card {
/* RUFU-042 (FN-8802 regression): this footer-scoped rule (0,3,0) out-specifies the shared
`.card` base (0,1,0), which sets `min-width: 0; max-width: 100%` (TaskCard.css). Without
these re-assertions `.card` could clamp the popover to its narrow trigger wrapper (~5mm).
`max-width` is clamped to the VIEWPORT, not the trigger, so the grid width survives. */
position: absolute;
right: 0;
bottom: calc(100% + var(--space-xs));
min-width: min(24rem, calc(100vw - (var(--space-lg) * 2)));
max-width: calc(100vw - (var(--space-lg) * 2));
}
@media (max-width: 768px) {
@@ -232,6 +254,9 @@ FN-8007 defines both desktop pseudo-thumbs locally with the marker's shared size
right: var(--space-sm);
bottom: var(--engine-control-mobile-bottom-stack);
width: auto;
/* RUFU-042 (FN-8802 regression): reset the desktop viewport min/max floor so the phone-width gutter panel never overflows; `.card`'s max-width:100% cannot clamp the left/right-stretched panel. */
min-width: 0;
max-width: none;
max-height: min(28rem, calc(100dvh - var(--engine-control-mobile-bottom-stack) - (var(--space-md) * 2)));
overflow: auto;
}
@@ -243,6 +268,8 @@ FN-8007 defines both desktop pseudo-thumbs locally with the marker's shared size
right: var(--space-sm);
bottom: var(--engine-control-mobile-bottom-stack);
width: auto;
min-width: 0;
max-width: none;
max-height: min(28rem, calc(100dvh - var(--engine-control-mobile-bottom-stack) - (var(--space-md) * 2)));
overflow: auto;
}

View File

@@ -427,4 +427,32 @@ describe("EngineControlMenu", () => {
expect(await screen.findByRole("alert")).toHaveTextContent("settings unavailable");
});
// FNXC:EngineControls 2026-08-08-15:40 (FN-8802 width-collapse regression, RUFU-042):
// The open popover carries the shared `.card` class, whose base now sets `min-width: 0` and
// `max-width: 100%` (TaskCard.css). Its containing block is `.engine-control-menu` which sizes
// to the narrow trigger button, so `.card`'s `max-width: 100%` clamped the popover's intended
// grid width down to ~the trigger's width (~5mm). The footer-scoped rule (0,3,0) must re-assert
// a VIEWPORT-clamped min/max width that beats `.card` (0,1,0), so the menu can never collapse
// to a sliver. Keep this guard asserted so the fix cannot silently regress.
it("keeps the footer-scoped popover width immune to the shared `.card` clamp on desktop", () => {
const footerPopover = cssRule(engineControlMenuCss, ".executor-status-bar__segment--engine-controls .engine-control-menu > .engine-control-menu__popover.card");
expect(footerPopover).toContain("position: absolute;");
expect(footerPopover).toContain("min-width: min(24rem, calc(100vw - (var(--space-lg) * 2)));");
expect(footerPopover).toContain("max-width: calc(100vw - (var(--space-lg) * 2));");
});
// FNXC:EngineControls 2026-08-08-15:40 (FN-8802 width-collapse regression, RUFU-042):
// On narrow/tablet widths the popover becomes a full-width gutter panel (`left/right: var(--space-sm)`).
// It must reset the desktop min/max floor and defeat `.card`'s `max-width: 100%` so the phone panel
// stays full-width without overflowing. Assert the media-query rules only (cssRule grabs the first
// selector match, which is the desktop base rule, so match the @media block explicitly).
it("keeps the mobile popover full-width and never overflowed by the desktop min-width floor", () => {
const mobileBlock = engineControlMenuCss.match(/@media \(max-width: 1024px\) \{([\s\S]*?)\}/)?.[1] ?? "";
expect(mobileBlock).toContain("left: var(--space-sm);");
expect(mobileBlock).toContain("right: var(--space-sm);");
expect(mobileBlock).toContain("max-width: none;");
expect(mobileBlock).toContain("min-width: 0;");
expect(mobileBlock).toContain("width: auto;");
});
});