FN-7585: unify border, radius, and height across task-detail Priority/Execution-mode/Oversight controls

Unifies the visual styling of the task-detail modal's Priority, Execution-mode, and Oversight quick-control chips so the cluster reads as one consistent control group.

- Add a shared --detail-control-border-radius token (resolving to --radius-md) alongside the existing --detail-priority-control-min-height token
- Override .detail-priority-chip's inherited transparent border with a visible --btn-border-width/--border pairing so the "normal" priority level renders as a bordered box instead of borderless text
- Pin the same border-width/color/radius trio on .detail-execution-mode-toggle so a future change to .btn defaults can't desync the cluster
- Apply the same trio to .detail-oversight-chip, overriding .card-oversight-badge's transparent border (covers the neutral "off" tint too)
- Apply the same trio to the mobile .detail-oversight-menu-trigger swap-in so the mobile overflow-trigger variant matches the desktop chip
- Add a changeset (patch) documenting the fix for @runfusion/fusion
- Extend TaskDetailModal.responsive-and-dependencies.test.tsx coverage for the unified styling

Files changed:
 .changeset/FN-7585-unify-task-detail-quick-control-styling.md                         |  7 +++
 packages/dashboard/app/components/TaskDetailModal.css                                 | 55 ++++++++++++++++++++++
 packages/dashboard/app/components/__tests__/TaskDetailModal.responsive-and-dependencies.test.tsx | 27 +++++++++++
 3 files changed, 89 insertions(+)

Fusion-Task-Id: FN-7585

Fusion-Task-Lineage: 0cca8c82-c9fb-4410-af48-51861a743f96

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
gsxdsm
2026-07-05 11:49:42 -07:00
parent 72b77bf621
commit 0f1cd0a36a
3 changed files with 89 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Unify border, radius, and height of the task-detail Priority/Execution/Oversight controls.
category: fix
dev: Adds a shared --detail-control-border-radius token alongside --detail-priority-control-min-height so .detail-priority-chip, .detail-execution-mode-toggle, .detail-oversight-chip, and .detail-oversight-menu-trigger all resolve the same border-width/color/radius/height.

View File

@@ -370,8 +370,23 @@ The task-detail modal metadata must keep priority, execution mode, provenance, P
/* /*
FNXC:TaskDetail 2026-06-22-20:00: FNXC:TaskDetail 2026-06-22-20:00:
Priority chip and speed (execution-mode) toggle share one min-height token so they render at identical, equal height. Reduced from the old calc(space-2xl + space-xs) (~too tall) to a compact 30px that stays legible and tappable. Both controls also get trimmed vertical padding to match. Priority chip and speed (execution-mode) toggle share one min-height token so they render at identical, equal height. Reduced from the old calc(space-2xl + space-xs) (~too tall) to a compact 30px that stays legible and tappable. Both controls also get trimmed vertical padding to match.
FNXC:TaskDetail 2026-07-05-00:00:
FN-7585 — Priority, Execution-mode, and Oversight (both the desktop chip and
the mobile overflow-trigger variant) previously diverged: Priority inherited
`.card-priority-badge`'s pill radius with a *transparent* border (so the
common `normal` level rendered as borderless text), while Execution-mode and
the Oversight mobile trigger are `.btn.btn-sm` pills with `--radius-md` and a
visible `--border` color. Add one shared `--detail-control-border-radius`
token here so all four controls resolve the same border-radius from a single
source; each control below also pins the same `--btn-border-width` width and
`--border` color so the cluster reads as one uniform control group. Only the
border/radius/size are unified — per-level tint backgrounds (priority
low/high/urgent, oversight observe/steer/autonomous/off, execution-mode
fast) are untouched.
*/ */
--detail-priority-control-min-height: 30px; --detail-priority-control-min-height: 30px;
--detail-control-border-radius: var(--radius-md);
display: flex; display: flex;
align-items: stretch; align-items: stretch;
@@ -384,6 +399,16 @@ The task-detail modal metadata must keep priority, execution mode, provenance, P
min-height: var(--detail-priority-control-min-height); min-height: var(--detail-priority-control-min-height);
padding-block: var(--space-xs); padding-block: var(--space-xs);
box-sizing: border-box; box-sizing: border-box;
/*
FNXC:TaskDetail 2026-07-05-00:00:
FN-7585 — override `.card-priority-badge`'s transparent border with a real,
visible border so the `normal` level (no `--low/--high/--urgent` tint) still
renders as a bordered box instead of borderless text, matching the
Execution-mode toggle and Oversight chip/trigger.
*/
border-width: var(--btn-border-width);
border-color: var(--border);
border-radius: var(--detail-control-border-radius);
} }
.detail-priority-chip--saving { .detail-priority-chip--saving {
@@ -425,6 +450,15 @@ The task-detail modal metadata must keep priority, execution mode, provenance, P
min-height: var(--detail-priority-control-min-height); min-height: var(--detail-priority-control-min-height);
padding-block: var(--space-xs); padding-block: var(--space-xs);
box-sizing: border-box; box-sizing: border-box;
/*
FNXC:TaskDetail 2026-07-05-00:00:
FN-7585 — pin the same shared border/radius token set as the Priority and
Oversight controls even though `.btn` already applies a border, so a future
change to `.btn`'s defaults cannot silently desync this cluster.
*/
border-width: var(--btn-border-width);
border-color: var(--border);
border-radius: var(--detail-control-border-radius);
} }
.detail-execution-mode-toggle svg { .detail-execution-mode-toggle svg {
@@ -461,12 +495,23 @@ already declares (see TaskCard.css) so oversight-level color stays a single
semantic source, and the same `--detail-priority-control-min-height` chip semantic source, and the same `--detail-priority-control-min-height` chip
height token as the priority/execution-mode controls above so the cluster height token as the priority/execution-mode controls above so the cluster
renders at a uniform height. renders at a uniform height.
FNXC:TaskDetail 2026-07-05-00:00:
FN-7585 — like `.detail-priority-chip`, override `.card-oversight-badge`'s
transparent border with the shared `--btn-border-width`/`--border`/
`--detail-control-border-radius` trio so every oversight level (including
`--off`, which has a neutral tint) renders the same bordered box as Priority
and Execution-mode. The mobile `.detail-oversight-menu-trigger` swap below
gets the identical trio so both oversight variants match.
*/ */
.detail-oversight-chip { .detail-oversight-chip {
gap: var(--space-xs); gap: var(--space-xs);
min-height: var(--detail-priority-control-min-height); min-height: var(--detail-priority-control-min-height);
padding-block: var(--space-xs); padding-block: var(--space-xs);
box-sizing: border-box; box-sizing: border-box;
border-width: var(--btn-border-width);
border-color: var(--border);
border-radius: var(--detail-control-border-radius);
} }
.detail-oversight-chip--saving { .detail-oversight-chip--saving {
@@ -613,6 +658,16 @@ since the trigger lives in the header cluster rather than the footer, unlike
min-height: var(--detail-priority-control-min-height); min-height: var(--detail-priority-control-min-height);
padding-block: var(--space-xs); padding-block: var(--space-xs);
box-sizing: border-box; box-sizing: border-box;
/*
FNXC:TaskDetail 2026-07-05-00:00:
FN-7585 — mobile swap-in for `.detail-oversight-chip` (JS `isOversightMenuMobile`
swap in TaskDetailModal.tsx). Pin the same shared border/radius trio so the
mobile overflow-trigger variant matches the desktop chip and the
Priority/Execution-mode controls, per the FN-7585 surface enumeration.
*/
border-width: var(--btn-border-width);
border-color: var(--border);
border-radius: var(--detail-control-border-radius);
} }
.detail-oversight-menu-trigger svg { .detail-oversight-menu-trigger svg {

View File

@@ -226,6 +226,33 @@ describe("TaskDetailModal", () => {
expect(css).not.toMatch(/@media \(max-width: 640px\)\s*\{[^}]*\.detail-meta-inline-controls\s*\{[^}]*flex-direction:\s*column;/); expect(css).not.toMatch(/@media \(max-width: 640px\)\s*\{[^}]*\.detail-meta-inline-controls\s*\{[^}]*flex-direction:\s*column;/);
}); });
it("unifies border/radius/height across the Priority, Execution-mode, and Oversight quick controls (FN-7585)", () => {
const css = readDashboardStylesSource();
const inlineControlsBlock = getStandaloneCssRuleBlock(css, ".detail-meta-inline-controls");
const priorityChipBlock = getExactCssRuleBlock(css, ".detail-priority-chip");
const executionToggleBlock = getExactCssRuleBlock(css, ".detail-execution-mode-toggle");
const oversightChipBlock = getExactCssRuleBlock(css, ".detail-oversight-chip");
const oversightTriggerBlock = getExactCssRuleBlock(css, ".detail-oversight-menu-trigger");
// The cluster declares one shared border-radius token; all four controls
// must reference it rather than four independent literal radii.
expect(inlineControlsBlock).toContain("--detail-control-border-radius: var(--radius-md);");
for (const block of [priorityChipBlock, executionToggleBlock, oversightChipBlock, oversightTriggerBlock]) {
expect(block).toContain("border-radius: var(--detail-control-border-radius);");
expect(block).toContain("border-width: var(--btn-border-width);");
expect(block).toContain("border-color: var(--border);");
// Same height token as the rest of the invariant.
expect(block).toContain("min-height: var(--detail-priority-control-min-height);");
expect(block).toContain("box-sizing: border-box;");
}
// Guard against regressing back to four independent literal radius values
// (e.g. reintroducing a bare `var(--radius-pill)` on only the chips).
expect(priorityChipBlock).not.toMatch(/border-radius:\s*var\(--radius-pill\)/);
expect(oversightChipBlock).not.toMatch(/border-radius:\s*var\(--radius-pill\)/);
});
it("keeps grouped timestamp metadata inline on desktop and mobile", () => { it("keeps grouped timestamp metadata inline on desktop and mobile", () => {
const css = readDashboardStylesSource(); const css = readDashboardStylesSource();