Fix Card selection layout shift and add transitions

- Reserve 2px border on all cards (transparent for elevated, coloured
  for outlined) so selected state only changes colour, not width
- Add 150ms ease-in-out transitions for border-color and background-color
  consistent with Button/Input interactive timing
- Remove borderWidth/borderStyle from selected sx (now handled by theme)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 15:49:38 +11:00
parent a899c9a376
commit d3bfa2dd6a
2 changed files with 5 additions and 3 deletions

View File

@@ -63,10 +63,9 @@ export const Card = React.forwardRef<HTMLDivElement, CardProps>(
elevation={0} elevation={0}
sx={[ sx={[
// Selected state: brand border + warm background // Selected state: brand border + warm background
// Border width is always 2px (set in theme) — only colour changes here
selected && { selected && {
borderColor: 'var(--fa-card-border-selected)', borderColor: 'var(--fa-card-border-selected)',
borderWidth: '2px',
borderStyle: 'solid',
backgroundColor: 'var(--fa-card-background-selected)', backgroundColor: 'var(--fa-card-background-selected)',
}, },
// Interactive: hover fill + shadow lift + pointer // Interactive: hover fill + shadow lift + pointer

View File

@@ -479,7 +479,10 @@ export const theme = createTheme({
borderRadius: parseInt(t.CardBorderRadiusDefault, 10), borderRadius: parseInt(t.CardBorderRadiusDefault, 10),
backgroundColor: t.CardBackgroundDefault, backgroundColor: t.CardBackgroundDefault,
boxShadow: t.CardShadowDefault, boxShadow: t.CardShadowDefault,
transition: 'box-shadow 150ms ease-in-out', // Reserve 2px border on ALL cards (transparent for elevated, coloured for outlined).
// Prevents layout shift when toggling selected state.
border: '2px solid transparent',
transition: 'box-shadow 150ms ease-in-out, border-color 150ms ease-in-out, background-color 150ms ease-in-out',
}, },
}, },
variants: [ variants: [