From a0e6b0f9d7f1cdff542fbbf7f6d4031b2d702088 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2026 20:11:45 +0000 Subject: [PATCH] [jules] style: Add consistent theme-aware hover/focus states to buttons - Implemented dynamic focus rings to improve keyboard navigation accessibility. - Supported both Glassmorphism and Neobrutalism across light and dark modes via `useTheme()`. - Added generic `focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2`. - Updated `.Jules/todo.md` and `.Jules/changelog.md`. Co-authored-by: Devasy23 <110348311+Devasy23@users.noreply.github.com> --- .Jules/changelog.md | 8 ++++++++ .Jules/todo.md | 9 +++++---- web/components/ui/Button.tsx | 10 ++++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.Jules/changelog.md b/.Jules/changelog.md index 11fc864e..ab03cc4b 100644 --- a/.Jules/changelog.md +++ b/.Jules/changelog.md @@ -7,6 +7,14 @@ ## [Unreleased] ### Added +- **Button Focus States:** Implemented consistent, theme-aware hover and focus states across all buttons globally. + - **Features:** + - Distinct focus rings for keyboard navigation (`focus-visible`). + - Full support for Glassmorphism (e.g., `ring-white`, `ring-blue-500`) and Neobrutalism (e.g., `ring-black`, `ring-white`). + - Adjusts correctly based on light and dark mode variations. + - Added base semantic `focus:outline-none` style and offsets. + - **Technical:** Modified `web/components/ui/Button.tsx` and leveraged the `useTheme` hook to dynamically set `focus-visible` ring classes based on the active theme mode and style. + - **Password Strength Meter:** Added a visual password strength indicator to the signup form. - **Features:** - Real-time strength calculation (Length, Uppercase, Lowercase, Number, Symbol). diff --git a/.Jules/todo.md b/.Jules/todo.md index ebb0c7a5..ab0d9ffd 100644 --- a/.Jules/todo.md +++ b/.Jules/todo.md @@ -78,10 +78,11 @@ ### Web -- [ ] **[style]** Consistent hover/focus states across all buttons - - Files: `web/components/ui/Button.tsx`, usage across pages - - Context: Ensure all buttons have proper hover + focus-visible styles - - Impact: Professional feel, keyboard users know where they are +- [x] **[style]** Consistent hover/focus states across all buttons + - Completed: 2026-03-17 + - Files: `web/components/ui/Button.tsx` + - Context: Added dynamic, theme-aware focus rings for both Glassmorphism and Neobrutalism (light/dark) + - Impact: Professional feel, precise keyboard navigation cues - Size: ~35 lines - Added: 2026-01-01 diff --git a/web/components/ui/Button.tsx b/web/components/ui/Button.tsx index f80c514c..a2bb7586 100644 --- a/web/components/ui/Button.tsx +++ b/web/components/ui/Button.tsx @@ -18,9 +18,9 @@ export const Button: React.FC = ({ disabled, ...props }) => { - const { style } = useTheme(); + const { style, mode } = useTheme(); - const baseStyles = "transition-all duration-200 font-bold flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed"; + const baseStyles = "transition-all duration-200 font-bold flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"; const sizeStyles = { sm: "px-3 py-1.5 text-sm", @@ -31,7 +31,8 @@ export const Button: React.FC = ({ let themeStyles = ""; if (style === THEMES.NEOBRUTALISM) { - themeStyles = "border-2 border-black shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] active:translate-x-[4px] active:translate-y-[4px] active:shadow-none rounded-none uppercase tracking-wider font-mono"; + const focusStyles = mode === 'dark' ? "focus-visible:ring-white focus-visible:ring-offset-black" : "focus-visible:ring-black focus-visible:ring-offset-white"; + themeStyles = `border-2 border-black shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:translate-x-[2px] hover:translate-y-[2px] hover:shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] active:translate-x-[4px] active:translate-y-[4px] active:shadow-none rounded-none uppercase tracking-wider font-mono ${focusStyles}`; if (variant === 'primary') themeStyles += " bg-neo-main text-white"; if (variant === 'secondary') themeStyles += " bg-neo-second text-black"; @@ -40,7 +41,8 @@ export const Button: React.FC = ({ } else { // Glassmorphism - themeStyles = "rounded-xl backdrop-blur-md border border-white/20 shadow-lg hover:shadow-xl active:scale-95"; + const focusStyles = mode === 'dark' ? "focus-visible:ring-white focus-visible:ring-offset-transparent" : "focus-visible:ring-blue-500 focus-visible:ring-offset-transparent"; + themeStyles = `rounded-xl backdrop-blur-md border border-white/20 shadow-lg hover:shadow-xl active:scale-95 ${focusStyles}`; if (variant === 'primary') themeStyles += " bg-gradient-to-r from-blue-500 to-purple-600 text-white shadow-blue-500/30"; if (variant === 'secondary') themeStyles += " bg-white/10 text-white hover:bg-white/20";