fix(client): right-align the card header action

The reorder controls sit in the header beside the action, and while
hidden they were still reserving their own width plus a gap. That pushed
"2 open" and every other header action left of the card's right edge, out
of line with the values in the rows beneath.

The controls are now taken out of flow and overlaid on the right, so the
action sits flush right whenever they are not showing. Because they then
occupy the same space, the action fades out as the controls fade in
rather than the two rendering on top of each other.

The card body needed no change: CardRow's negative margin, which lets the
hover highlight bleed to the card edges, is already cancelled by its own
inner padding, so row values were correctly at 16px from the edge all
along. The header slot was the only cause.

Claude-Session: https://claude.ai/code/session_01AbYLvwpEaZFXktHVcqrFRd
This commit is contained in:
gorkem-bwl committed 2026-08-29 10:43:24 -04:00
1 parent 8398a0300d
commit 729c2cb049
1 file changed
+20 -1
@@ -64,6 +64,11 @@ export const DashboardCard = ({
opacity: 1,
pointerEvents: "auto",
},
// The controls are overlaid on the action, so the action fades out as
// they fade in rather than the two rendering on top of each other.
"&:hover .dashboard-card-action, &:has(:focus-visible) .dashboard-card-action": {
opacity: 0,
},
}}
>
<Stack
@@ -95,6 +100,7 @@ export const DashboardCard = ({
alignItems="center"
gap={theme.spacing(LAYOUT.SM)}
flexShrink={0}
position="relative"
>
{isStale && (
<CircularProgress
@@ -102,10 +108,23 @@ export const DashboardCard = ({
color="primary"
/>
)}
{action}
{action && (
<Box
className="dashboard-card-action"
sx={{ transition: "opacity 0.15s ease" }}
>
{action}
</Box>
)}
{slot && (
<Box
className="dashboard-card-slot"
// Taken out of flow and overlaid on the right: while hidden it
// would otherwise reserve its own width and push `action` away
// from the card's right edge, leaving it visibly un-aligned
// with the values in the rows beneath.
position="absolute"
right={0}
sx={{
opacity: 0,
pointerEvents: "none",