From dab39bd5709fc6aaffd9086e50cef4370f40b595 Mon Sep 17 00:00:00 2001 From: cesnimda Date: Mon, 13 Jul 2026 15:07:11 +0200 Subject: [PATCH] feat(ui): add reduced-motion floor and tasteful hover micro-interactions Global @media (prefers-reduced-motion: reduce) rule in MuiCssBaseline collapses every animation/transition duration to near-zero at once -- covers MUI's own Dialog/Menu/Collapse/ripple transitions and every hover-lift added below, so accessibility doesn't need re-checking per-component as more motion gets added later. Dashboard stat tiles and Kanban cards get a subtle hover lift (shadow deepens, translateY(-2px)/-1px), matching the hover pattern the landing page's feature cards already had -- these are the two places a small lift reads as an affordance rather than noise: stat tiles are dashboard-customization-adjacent, and kanban cards are literally draggable, so the lift reinforces the existing grab-cursor signal instead of competing with it. Left everything else alone -- most cards on this app hold passive content, not something to invite a hover response. --- job-tracker-ui/src/components/DashboardView.tsx | 8 +++++++- job-tracker-ui/src/components/KanbanBoard.tsx | 3 +++ job-tracker-ui/src/theme.ts | 12 ++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/job-tracker-ui/src/components/DashboardView.tsx b/job-tracker-ui/src/components/DashboardView.tsx index 47128ed..d09d333 100644 --- a/job-tracker-ui/src/components/DashboardView.tsx +++ b/job-tracker-ui/src/components/DashboardView.tsx @@ -359,7 +359,13 @@ export default function DashboardView() { {!summaryResource.loading && !summaryResource.error && prefs.cards ? ( {metricCards.map((card) => ( - + {card.label} {card.value} {card.trend || card.caption ? ( diff --git a/job-tracker-ui/src/components/KanbanBoard.tsx b/job-tracker-ui/src/components/KanbanBoard.tsx index 03e5141..b06fa1d 100644 --- a/job-tracker-ui/src/components/KanbanBoard.tsx +++ b/job-tracker-ui/src/components/KanbanBoard.tsx @@ -199,6 +199,9 @@ export default function KanbanBoard() { cursor: "grab", borderRadius: 2.5, borderLeft: `4px solid ${c}`, + transition: "box-shadow .15s, transform .15s", + "&:hover": { boxShadow: 4, transform: "translateY(-1px)" }, + "&:active": { cursor: "grabbing" }, }} > diff --git a/job-tracker-ui/src/theme.ts b/job-tracker-ui/src/theme.ts index e8d143f..68d03f2 100644 --- a/job-tracker-ui/src/theme.ts +++ b/job-tracker-ui/src/theme.ts @@ -254,6 +254,18 @@ export const getTheme = (_mode: "light" | "dark") => { WebkitFontSmoothing: "antialiased", MozOsxFontSmoothing: "grayscale", }, + // A global floor under every animation added this session (card hover-lift, + // MUI's own Dialog/Menu/Collapse transitions, ripple) -- users who set this OS/ + // browser preference get near-instant, non-animated interactions everywhere at + // once, rather than each component needing its own reduced-motion check. + "@media (prefers-reduced-motion: reduce)": { + "*, *::before, *::after": { + animationDuration: "0.01ms !important", + animationIterationCount: "1 !important", + transitionDuration: "0.01ms !important", + scrollBehavior: "auto !important", + }, + }, }, }, MuiPaper: {