diff --git a/.Jules/changelog.md b/.Jules/changelog.md index 11fc864..08c5e90 100644 --- a/.Jules/changelog.md +++ b/.Jules/changelog.md @@ -123,3 +123,4 @@ - `.jules/todo.md` - `.jules/knowledge.md` - `.jules/changelog.md` +\n- **2026-02-12:** `[style]` Added consistent focus-visible states to all buttons across web app, supporting NEOBRUTALISM, GLASSMORPHISM, and dark mode. Modified `Button.tsx` and raw button elements. diff --git a/.Jules/todo.md b/.Jules/todo.md index ebb0c7a..33fd7a2 100644 --- a/.Jules/todo.md +++ b/.Jules/todo.md @@ -78,11 +78,12 @@ ### 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 - - Size: ~35 lines +- [x] **[style]** Consistent hover/focus states across all buttons + - Completed: 2026-02-12 + - Files: `web/components/ui/Button.tsx`, usage across pages (`web/pages/Dashboard.tsx`, `web/pages/Friends.tsx`, `web/pages/GroupDetails.tsx`, `web/pages/Profile.tsx`, `web/pages/Auth.tsx`, etc) + - Context: Added focus-visible styles (ring and ring-offset) supporting both NEOBRUTALISM and GLASSMORPHISM themes, including dark mode support. + - Impact: Professional feel, clear visual feedback for keyboard users making the app more accessible. + - Size: ~35 lines modified across multiple files. - Added: 2026-01-01 ### Mobile diff --git a/web/components/ui/Button.tsx b/web/components/ui/Button.tsx index f80c514..d795d6d 100644 --- a/web/components/ui/Button.tsx +++ b/web/components/ui/Button.tsx @@ -31,7 +31,7 @@ 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"; + 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 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-black dark:focus-visible:ring-white focus-visible:ring-offset-2 dark:focus-visible:ring-offset-zinc-900"; if (variant === 'primary') themeStyles += " bg-neo-main text-white"; if (variant === 'secondary') themeStyles += " bg-neo-second text-black"; @@ -40,12 +40,12 @@ 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"; + themeStyles = "rounded-xl backdrop-blur-md border border-white/20 shadow-lg hover:shadow-xl active:scale-95 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"; - 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"; - if (variant === 'danger') themeStyles += " bg-gradient-to-r from-red-500 to-pink-600 text-white shadow-red-500/30"; - if (variant === 'ghost') themeStyles += " bg-transparent border-none shadow-none hover:bg-white/10 text-current"; + if (variant === 'primary') themeStyles += " bg-gradient-to-r from-blue-500 to-purple-600 text-white shadow-blue-500/30 focus-visible:ring-blue-500"; + if (variant === 'secondary') themeStyles += " bg-white/10 text-white hover:bg-white/20 focus-visible:ring-white/50"; + if (variant === 'danger') themeStyles += " bg-gradient-to-r from-red-500 to-pink-600 text-white shadow-red-500/30 focus-visible:ring-red-500"; + if (variant === 'ghost') themeStyles += " bg-transparent border-none shadow-none hover:bg-white/10 text-current focus-visible:ring-white/50"; } return ( diff --git a/web/components/ui/Modal.tsx b/web/components/ui/Modal.tsx index b7d8fcb..1d319e1 100644 --- a/web/components/ui/Modal.tsx +++ b/web/components/ui/Modal.tsx @@ -66,7 +66,7 @@ export const Modal: React.FC = ({ isOpen, onClose, title, children, {/* Header */}

{title}

-
diff --git a/web/pages/Auth.tsx b/web/pages/Auth.tsx index 5f0efbe..3c7cc33 100644 --- a/web/pages/Auth.tsx +++ b/web/pages/Auth.tsx @@ -211,7 +211,7 @@ export const Auth = () => { type="button" onClick={handleGoogleSignIn} disabled={googleLoading} - className={`w-full flex items-center justify-center gap-3 p-3 font-bold transition-all ${isNeo + className={`w-full flex items-center justify-center gap-3 p-3 font-bold transition-all focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-offset-2 ${isNeo ? "focus-visible:ring-black dark:focus-visible:ring-white dark:focus-visible:ring-offset-zinc-900" : "focus-visible:ring-blue-500 focus-visible:ring-offset-transparent"} ${isNeo ? 'bg-white 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)] rounded-none' : 'bg-white text-black hover:bg-gray-50 border border-gray-200 shadow-sm rounded-xl' }`} @@ -330,7 +330,7 @@ export const Auth = () => { setFieldErrors({}); setError(''); }} - className="text-sm font-bold hover:underline opacity-70 hover:opacity-100 transition-opacity" + className="text-sm font-bold hover:underline opacity-70 hover:opacity-100 transition-opacity focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500" > {isLogin ? "Don't have an account? Sign Up" diff --git a/web/pages/Dashboard.tsx b/web/pages/Dashboard.tsx index 7670c75..0a8e7b4 100644 --- a/web/pages/Dashboard.tsx +++ b/web/pages/Dashboard.tsx @@ -297,9 +297,9 @@ export const Dashboard = () => { key={group._id} type="button" onClick={() => navigate(`/groups/${group._id}`)} - className={`w-full p-4 flex items-center justify-between transition-all ${style === THEMES.NEOBRUTALISM - ? 'bg-white border-2 border-black hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-1' - : 'bg-white/50 backdrop-blur-sm rounded-lg hover:bg-white/80' + className={`w-full p-4 flex items-center justify-between transition-all focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-offset-2 ${style === THEMES.NEOBRUTALISM + ? 'bg-white border-2 border-black hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-1 focus-visible:ring-black dark:focus-visible:ring-white dark:focus-visible:ring-offset-zinc-900' + : 'bg-white/50 backdrop-blur-sm rounded-lg hover:bg-white/80 focus-visible:ring-blue-500 focus-visible:ring-offset-transparent' }`} >
@@ -338,9 +338,9 @@ export const Dashboard = () => { key={groupSum.group_id} type="button" onClick={() => navigate(`/groups/${groupSum.group_id}`)} - className={`p-4 text-left transition-all ${style === THEMES.NEOBRUTALISM - ? 'bg-white border-2 border-black hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-1' - : 'bg-white/50 backdrop-blur-sm rounded-lg hover:bg-white/80' + className={`p-4 text-left transition-all focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-offset-2 ${style === THEMES.NEOBRUTALISM + ? 'bg-white border-2 border-black hover:shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-1 focus-visible:ring-black dark:focus-visible:ring-white dark:focus-visible:ring-offset-zinc-900' + : 'bg-white/50 backdrop-blur-sm rounded-lg hover:bg-white/80 focus-visible:ring-blue-500 focus-visible:ring-offset-transparent' }`} >

{groupSum.group_name}

diff --git a/web/pages/Friends.tsx b/web/pages/Friends.tsx index 039eb5d..f81a6d5 100644 --- a/web/pages/Friends.tsx +++ b/web/pages/Friends.tsx @@ -211,9 +211,9 @@ export const Friends = () => { diff --git a/web/pages/GroupDetails.tsx b/web/pages/GroupDetails.tsx index b2b76c2..3d96452 100644 --- a/web/pages/GroupDetails.tsx +++ b/web/pages/GroupDetails.tsx @@ -704,7 +704,7 @@ export const GroupDetails = () => { @@ -936,7 +936,7 @@ export const GroupDetails = () => { diff --git a/web/pages/Profile.tsx b/web/pages/Profile.tsx index ff19489..b6797c4 100644 --- a/web/pages/Profile.tsx +++ b/web/pages/Profile.tsx @@ -214,7 +214,7 @@ export const Profile = () => { type="button" key={item.label} onClick={item.onClick} - className={`w-full flex items-center gap-4 p-4 transition-all hover:bg-black/5 dark:hover:bg-white/5 ${itemIdx !== section.items.length - 1 ? 'border-b border-gray-200/50 dark:border-gray-700/50' : '' + className={`w-full flex items-center gap-4 p-4 transition-all hover:bg-black/5 dark:hover:bg-white/5 focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-offset-2 ${isNeo ? "focus-visible:ring-black dark:focus-visible:ring-white dark:focus-visible:ring-offset-zinc-900" : "focus-visible:ring-blue-500 focus-visible:ring-offset-transparent"} ${itemIdx !== section.items.length - 1 ? 'border-b border-gray-200/50 dark:border-gray-700/50' : '' }`} >
{