Dark Mode Hover Fix — Design Spec
Date: 2026-04-25Problem
In dark mode, virtually all hover states across the app are invisible or broken. The root cause is that--muted (dark: hsl(240 6% 14%)) and --accent (dark: hsl(250 60% 18%)) are both near-black. Every component using hover:bg-muted/* or hover:bg-accent produces a hover color nearly identical to the dark card/background, making rows, buttons, and interactive elements appear to not respond to hover at all. The existing partial fix in index.css (.dark table tr:hover { ... !important }) uses the same near-black accent variable and is equally broken.
Affected scope: 168 files with hover:bg-* classes; ~30+ components across every module (patients, appointments, staff, inventory, billing, doctor, settings, notifications, dashboard-widgets) using hover:bg-muted/* variants.
Approach: CSS Variable Redesign
Add one canonical--hover-overlay dark-mode token, then use a @layer utilities CSS override to remap all existing hover:bg-muted/* variants to it. Zero individual component file changes required.
Changes
1. ui/src/index.css — Three changes
Add --hover-overlay to .dark block:
.dark table tr:hover rule:
Replace color-mix(in srgb, var(--accent) 40%, transparent) with var(--hover-overlay). Remove the !important (no longer needed once the layer override is in place).
Add @layer utilities override block:
.dark class + hover class + :hover pseudo) vs Tailwind’s generated 0,1,1. Same layer, higher specificity wins — no !important needed.
2. ui/src/components/shared/GlobalError.tsx line 35
Add dark:hover:bg-neutral-700 to the white button that currently has only hover:bg-neutral-200.
3. ui/src/components/chat/ChatWindow.tsx line 305
Add dark:hover:bg-zinc-800 to the mobile back button that currently has only hover:bg-gray-100.
What is NOT changed
- Individual module components (patients, appointments, staff, etc.) — the layer override handles all of them globally
- Light mode hover behavior — all changes are scoped to
.dark - The sidebar hover — already uses
hover:bg-sidebar-accent(CSS var, correct) - Button component — already uses CSS-var-based variants
- Landing page / auth pages — intentionally dark-background components with
hover:bg-white/5,hover:bg-neutral-800etc. are fine as-is
Visual Result
Before: hover on table rows, notification toggles, patient cards, appointment list items — near-invisible, same color as background. After: all hover states show a subtlehsl(250 85% 65% / 0.1) purple overlay — clearly visible, consistent with the primary color, not harsh.
Files Changed
| File | Change |
|---|---|
ui/src/index.css | Add --hover-overlay var, update table rule, add @layer utilities override block |
ui/src/components/shared/GlobalError.tsx | Add dark:hover:bg-neutral-700 |
ui/src/components/chat/ChatWindow.tsx | Add dark:hover:bg-zinc-800 |

