diff options
author | 2025-05-29 01:50:36 +0530 | |
---|---|---|
committer | 2025-05-29 01:50:36 +0530 | |
commit | 1cf89bacba59c1edbc5a65d3f6e3ea2b575b89c4 (patch) | |
tree | 48fc5b6d674ffa4132a290d52679898057508d04 /frontend | |
parent | 2fb1e6b1004480700c35c8dd7e42f999eb8bb7bc (diff) | |
download | blcklst-1cf89bacba59c1edbc5a65d3f6e3ea2b575b89c4.tar.gz blcklst-1cf89bacba59c1edbc5a65d3f6e3ea2b575b89c4.tar.bz2 blcklst-1cf89bacba59c1edbc5a65d3f6e3ea2b575b89c4.zip |
fix: Improved UI and NavBar Menu
- Fixed alignment issues in the frontend
- Fixed the box border hover selection in the menu bar (mobile)
- Changed the theme toggle button color to standard frontend theme
- Enhanced UI components
Diffstat (limited to 'frontend')
-rw-r--r-- | frontend/src/app/globals.css | 63 | ||||
-rw-r--r-- | frontend/src/components/header.tsx | 421 | ||||
-rw-r--r-- | frontend/src/components/theme-toggle.tsx | 35 |
3 files changed, 340 insertions, 179 deletions
diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 5210ba7..0b2a4b4 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -708,6 +708,55 @@ a.nav-button-transparent:not(:hover):not(:focus):not(:active) { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; } + + /* Hide scrollbar in mobile menu while maintaining scroll functionality */ + [data-radix-dialog-content] { + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* Internet Explorer and Edge */ + } + + [data-radix-dialog-content]::-webkit-scrollbar { + display: none; /* Chrome, Safari, Opera */ + width: 0; + height: 0; + } + + /* Specifically target Sheet content scrolling areas */ + [data-radix-dialog-content] .overflow-y-auto, + [data-radix-dialog-content] .overflow-auto { + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* Internet Explorer and Edge */ + } + + [data-radix-dialog-content] .overflow-y-auto::-webkit-scrollbar, + [data-radix-dialog-content] .overflow-auto::-webkit-scrollbar { + display: none; /* Chrome, Safari, Opera */ + width: 0; + height: 0; + } + + /* Mobile navigation specific scrollbar hiding */ + .mobile-nav-scroll { + scrollbar-width: none !important; /* Firefox */ + -ms-overflow-style: none !important; /* Internet Explorer and Edge */ + } + + .mobile-nav-scroll::-webkit-scrollbar { + display: none !important; /* Chrome, Safari, Opera */ + width: 0 !important; + height: 0 !important; + background: transparent !important; + } + + /* Additional scrollbar hiding for all mobile menu elements */ + [data-radix-dialog-content] *, + [data-radix-dialog-content] *::-webkit-scrollbar { + scrollbar-width: none !important; + -ms-overflow-style: none !important; + display: none !important; + width: 0 !important; + height: 0 !important; + } } /* Small mobile optimizations */ @@ -756,3 +805,17 @@ a.nav-button-transparent:not(:hover):not(:focus):not(:active) { outline: 2px solid var(--ring) !important; outline-offset: 2px !important; } + +/* Mobile menu icon stroke uniformity */ +.mobile-nav-scroll svg, +[data-radix-dialog-content] svg { + stroke-linecap: round !important; + stroke-linejoin: round !important; +} + +/* Force consistent stroke width for mobile quick action icons */ +@media (max-width: 768px) { + [data-radix-dialog-content] button svg { + stroke-width: inherit !important; + } +} diff --git a/frontend/src/components/header.tsx b/frontend/src/components/header.tsx index a8ddadc..b792767 100644 --- a/frontend/src/components/header.tsx +++ b/frontend/src/components/header.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, useRef } from "react"; import Link from "next/link"; import Image from "next/image"; +import { useTheme } from "next-themes"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; @@ -34,13 +35,17 @@ import { RefreshCw, Shield, Globe, + Sun, + Moon, } from "lucide-react"; export function Header() { const [cartItems] = useState(3); const [wishlistItems] = useState(5); const [isMounted, setIsMounted] = useState(false); + const [sheetError, setSheetError] = useState(false); const sheetRef = useRef<HTMLDivElement>(null); + const { setTheme, theme } = useTheme(); const categories = [ { @@ -81,14 +86,31 @@ export function Header() { // Add global error handler for scroll-related errors const handleError = (event: ErrorEvent) => { if (event.error?.message?.includes('parameter 1 is not of type \'Node\'') || - event.error?.message?.includes('handleScroll')) { + event.error?.message?.includes('handleScroll') || + event.error?.message?.includes('RemoveScrollSideCar') || + event.error?.message?.includes('shouldCancelEvent') || + event.error?.message?.includes('shouldPrevent')) { console.warn('Scroll handling error caught and suppressed:', event.error); event.preventDefault(); + setSheetError(true); + return false; + } + }; + + // Also add an unhandled rejection handler for async scroll errors + const handleUnhandledRejection = (event: PromiseRejectionEvent) => { + if (event.reason?.message?.includes('handleScroll') || + event.reason?.message?.includes('RemoveScrollSideCar') || + event.reason?.message?.includes('parameter 1 is not of type \'Node\'')) { + console.warn('Scroll promise rejection caught and suppressed:', event.reason); + event.preventDefault(); + setSheetError(true); return false; } }; window.addEventListener('error', handleError); + window.addEventListener('unhandledrejection', handleUnhandledRejection); const preloadLogos = () => { if (typeof window !== 'undefined') { @@ -103,9 +125,31 @@ export function Header() { return () => { window.removeEventListener('error', handleError); + window.removeEventListener('unhandledrejection', handleUnhandledRejection); }; }, []); + // Add scroll error prevention + useEffect(() => { + const sheetElement = sheetRef.current; + if (sheetElement) { + const handleScroll = (event: Event) => { + try { + // Allow default scroll behavior but catch any errors + } catch (error) { + console.warn('Sheet scroll error caught:', error); + event.preventDefault(); + } + }; + + sheetElement.addEventListener('scroll', handleScroll, { passive: false }); + + return () => { + sheetElement.removeEventListener('scroll', handleScroll); + }; + } + }, [isMounted]); + // Prevent hydration issues with Sheet component if (!isMounted) { return ( @@ -127,7 +171,7 @@ export function Header() { {/* Main header */} <div className="border-b dark:border-neutral-800"> <div className="container mx-auto px-3 sm:px-4 lg:px-6"> - <div className="flex h-14 sm:h-16 items-center justify-between gap-2 sm:gap-4"> + <div className="flex h-14 sm:h-16 items-center justify-between gap-2 sm:gap-4 md:justify-between"> {/* Mobile menu placeholder */} <Button variant="ghost" @@ -139,8 +183,8 @@ export function Header() { </Button> {/* Logo */} - <div className="flex items-center"> - <Link href="/" className="flex items-center space-x-2"> + <div className="flex items-center flex-1 md:flex-initial justify-center md:justify-start"> + <Link href="/" className="flex items-center space-x-2 ml-8 md:ml-0"> <Image src="/black-logo.png" alt="blcklst" @@ -177,7 +221,7 @@ export function Header() { className="relative nav-button-transparent backdrop-blur-sm min-w-[44px] min-h-[44px]" disabled > - <ShoppingBag className="h-5 w-5" /> + <ShoppingBag className="h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground flex-shrink-0" /> </Button> </div> </div> @@ -206,173 +250,231 @@ export function Header() { {/* Main header */} <div className="border-b dark:border-neutral-800"> <div className="container mx-auto px-3 sm:px-4 lg:px-6"> - <div className="flex h-14 sm:h-16 items-center justify-between gap-2 sm:gap-4"> + <div className="flex h-14 sm:h-16 items-center justify-between gap-2 sm:gap-4 md:justify-between"> {/* Mobile menu */} - <Sheet> - <SheetTrigger asChild> - <Button - variant="ghost" - size="icon" - className="md:hidden nav-button-transparent backdrop-blur-sm" - > - <Menu className="h-5 w-5" /> - </Button> - </SheetTrigger> - <SheetContent - ref={sheetRef} - side="left" - className="w-[280px] xs:w-[320px] sm:w-[380px] p-0 border-r dark:border-neutral-800" - onOpenAutoFocus={(event) => { - // Prevent auto focus to avoid scroll handling issues - event.preventDefault(); - }} - onCloseAutoFocus={(event) => { - // Prevent auto focus to avoid scroll handling issues - event.preventDefault(); - }} - onEscapeKeyDown={(event) => { - // Handle escape key gracefully - try { - // Default behavior - } catch (error) { - console.warn('Escape key handling error:', error); + {!sheetError ? ( + <Sheet> + <SheetTrigger asChild> + <Button + variant="ghost" + size="icon" + className="md:hidden nav-button-transparent backdrop-blur-sm" + > + <Menu className="h-5 w-5" /> + </Button> + </SheetTrigger> + <SheetContent + ref={sheetRef} + side="left" + className="w-[280px] xs:w-[320px] sm:w-[380px] p-0 border-r dark:border-neutral-800" + onOpenAutoFocus={(event) => { + // Prevent auto focus to avoid scroll handling issues event.preventDefault(); - } - }} - onPointerDownOutside={(event) => { - // Handle pointer events gracefully - try { - // Default behavior - } catch (error) { - console.warn('Pointer down outside error:', error); + }} + onCloseAutoFocus={(event) => { + // Prevent auto focus to avoid scroll handling issues event.preventDefault(); - } - }} - > - <div className="flex flex-col h-full"> - {/* Header Section */} - <SheetHeader className="px-6 py-4 border-b dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900"> - <SheetTitle className="text-left text-lg font-semibold"> - Menu - </SheetTitle> - </SheetHeader> + }} + onEscapeKeyDown={(event) => { + // Handle escape key gracefully + try { + // Default behavior + } catch (error) { + console.warn('Escape key handling error:', error); + event.preventDefault(); + setSheetError(true); + } + }} + onPointerDownOutside={(event) => { + // Handle pointer events gracefully + try { + // Default behavior + } catch (error) { + console.warn('Pointer down outside error:', error); + event.preventDefault(); + setSheetError(true); + } + }} + onInteractOutside={(event) => { + // Additional interaction handler + try { + // Default behavior + } catch (error) { + console.warn('Interact outside error:', error); + event.preventDefault(); + setSheetError(true); + } + }} + onFocusOutside={(event) => { + // Additional focus handler + try { + // Default behavior + } catch (error) { + console.warn('Focus outside error:', error); + event.preventDefault(); + setSheetError(true); + } + }} + > + <div className="flex flex-col h-full"> + {/* Header Section */} + <SheetHeader className="px-6 py-4 border-b dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900"> + <SheetTitle className="text-left text-lg font-semibold"> + Menu + </SheetTitle> + </SheetHeader> - {/* Navigation Section */} - <div className="flex-1 overflow-y-auto"> - <nav className="px-4 py-6 space-y-6"> - {categories.map((category) => ( - <div key={category.title} className="space-y-3"> - {/* Category Header */} - <h3 className="px-2 text-sm font-semibold text-foreground uppercase tracking-wider border-b border-neutral-200 dark:border-neutral-700 pb-2"> - {category.title} - </h3> - - {/* Category Items */} - <div className="space-y-1"> - {category.items.map((item) => ( - <Link - key={item.name} - href={item.href} - className="flex items-center px-3 py-3 text-sm text-muted-foreground hover:text-foreground hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-all duration-200 touch-manipulation min-h-[44px]" - > - <span className="flex-1">{item.name}</span> - <svg - className="w-4 h-4 opacity-40" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" + {/* Navigation Section */} + <div className="flex-1 overflow-y-auto mobile-nav-scroll"> + <nav className="px-4 py-6 space-y-6"> + {categories.map((category) => ( + <div key={category.title} className="space-y-3"> + {/* Category Header */} + <h3 className="px-2 text-sm font-semibold text-foreground uppercase tracking-wider border-b border-neutral-200 dark:border-neutral-700 pb-2"> + {category.title} + </h3> + + {/* Category Items */} + <div className="space-y-1"> + {category.items.map((item) => ( + <Link + key={item.name} + href={item.href} + className="flex items-center px-3 py-3 text-sm text-muted-foreground hover:text-foreground hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-colors touch-manipulation min-h-[44px]" > - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /> - </svg> - </Link> - ))} + <span className="flex-1">{item.name}</span> + <svg + className="w-4 h-4 opacity-40" + fill="none" + stroke="currentColor" + viewBox="0 0 24 24" + > + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /> + </svg> + </Link> + ))} + </div> </div> + ))} + + {/* Sale Section */} + <div className="space-y-3 pt-4 border-t border-neutral-200 dark:border-neutral-700"> + <h3 className="px-2 text-sm font-semibold text-red-600 uppercase tracking-wider"> + Special + </h3> + <Link + href="/sale" + className="flex items-center px-3 py-3 text-sm font-medium text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-950/30 rounded-lg transition-colors touch-manipulation min-h-[44px]" + > + <span className="flex-1">Sale Items</span> + <svg + className="w-4 h-4" + fill="none" + stroke="currentColor" + viewBox="0 0 24 24" + > + <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /> + </svg> + </Link> </div> - ))} + </nav> + </div> - {/* Sale Section */} - <div className="space-y-3 pt-4 border-t border-neutral-200 dark:border-neutral-700"> - <h3 className="px-2 text-sm font-semibold text-red-600 uppercase tracking-wider"> - Special - </h3> - <Link - href="/sale" - className="flex items-center px-3 py-3 text-sm font-medium text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-950/30 rounded-lg transition-all duration-200 touch-manipulation min-h-[44px]" + {/* Footer Section */} + <div className="border-t dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900 px-4 py-4"> + <div className="grid grid-cols-2 gap-3"> + {/* Search Button */} + <Button + variant="outline" + size="sm" + className="flex items-center justify-center gap-2 h-10 text-xs font-medium" > - <span className="flex-1">Sale Items</span> - <svg - className="w-4 h-4" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" /> - </svg> - </Link> + <Search className="h-4 w-4" /> + Search + </Button> + + {/* Account Button */} + <Button + variant="outline" + size="sm" + className="flex items-center justify-center gap-2 h-10 text-xs font-medium" + > + <User className="h-4 w-4" /> + Account + </Button> </div> - </nav> - </div> - - {/* Footer Section */} - <div className="border-t dark:border-neutral-800 bg-neutral-50 dark:bg-neutral-900 px-4 py-4"> - <div className="grid grid-cols-2 gap-3"> - {/* Search Button */} - <Button - variant="outline" - size="sm" - className="flex items-center justify-center gap-2 h-10 text-xs font-medium" - > - <Search className="h-4 w-4" /> - Search - </Button> - - {/* Account Button */} - <Button - variant="outline" - size="sm" - className="flex items-center justify-center gap-2 h-10 text-xs font-medium" - > - <User className="h-4 w-4" /> - Account - </Button> - </div> - - {/* Quick Actions */} - <div className="flex items-center justify-center space-x-6 mt-4 pt-3 border-t border-neutral-200 dark:border-neutral-700"> - <button className="flex flex-col items-center space-y-1 p-2 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors touch-manipulation relative"> - <Heart className="h-5 w-5 text-muted-foreground" /> - <span className="text-xs text-muted-foreground">Wishlist</span> - {wishlistItems > 0 && ( - <Badge className="absolute -top-1 -right-1 h-4 w-4 rounded-full p-0 text-xs"> - {wishlistItems} - </Badge> - )} - </button> - <button className="flex flex-col items-center space-y-1 p-2 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors touch-manipulation relative"> - <ShoppingBag className="h-5 w-5 text-muted-foreground" /> - <span className="text-xs text-muted-foreground">Cart</span> - {cartItems > 0 && ( - <Badge className="absolute -top-1 -right-1 h-4 w-4 rounded-full p-0 text-xs"> - {cartItems} - </Badge> - )} - </button> - - <button className="flex flex-col items-center space-y-1 p-2 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors touch-manipulation"> - <Globe className="h-5 w-5 text-muted-foreground" /> - <span className="text-xs text-muted-foreground">USD</span> - </button> + {/* Quick Actions */} + <div className="grid grid-cols-4 gap-1 mt-4 pt-3 border-t border-neutral-200 dark:border-neutral-700"> + <button className="flex flex-col items-center justify-center space-y-2 p-3 rounded-xl hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-all duration-200 touch-manipulation group min-h-[72px] border border-transparent hover:border-neutral-200 dark:hover:border-neutral-700"> + <div className="relative"> + <Heart className="h-5 w-5 text-muted-foreground group-hover:text-foreground transition-colors flex-shrink-0" /> + {wishlistItems > 0 && ( + <Badge className="absolute -top-2 -right-2 h-4 w-4 rounded-full p-0 text-[10px] leading-none"> + {wishlistItems} + </Badge> + )} + </div> + <span className="text-[10px] text-muted-foreground group-hover:text-foreground transition-colors text-center leading-tight font-medium">Wishlist</span> + </button> + + <button className="flex flex-col items-center justify-center space-y-2 p-3 rounded-xl hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-all duration-200 touch-manipulation group min-h-[72px] border border-transparent hover:border-neutral-200 dark:hover:border-neutral-700"> + <div className="relative"> + <ShoppingBag className="h-5 w-5 text-muted-foreground group-hover:text-foreground transition-colors flex-shrink-0" /> + {cartItems > 0 && ( + <Badge className="absolute -top-2 -right-2 h-4 w-4 rounded-full p-0 text-[10px] leading-none"> + {cartItems} + </Badge> + )} + </div> + <span className="text-[10px] text-muted-foreground group-hover:text-foreground transition-colors text-center leading-tight font-medium">Cart</span> + </button> + + {/* Theme Toggle in Mobile Menu */} + <button + onClick={() => { + if (theme === 'dark') { + setTheme('light'); + } else { + setTheme('dark'); + } + }} + className="flex flex-col items-center justify-center space-y-2 p-3 rounded-xl hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-all duration-200 touch-manipulation group min-h-[72px] border border-transparent hover:border-neutral-200 dark:hover:border-neutral-700" + > + <div className="relative"> + {theme === 'dark' ? ( + <Moon className="h-5 w-5 text-muted-foreground group-hover:text-foreground transition-colors flex-shrink-0" /> + ) : ( + <Sun className="h-5 w-5 text-muted-foreground group-hover:text-foreground transition-colors flex-shrink-0" /> + )} + </div> + <span className="text-[10px] text-muted-foreground group-hover:text-foreground transition-colors text-center leading-tight font-medium">Theme</span> + </button> + + <button className="flex flex-col items-center justify-center space-y-2 p-3 rounded-xl hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-all duration-200 touch-manipulation group min-h-[72px] border border-transparent hover:border-neutral-200 dark:hover:border-neutral-700"> + <div className="relative"> + <Globe className="h-5 w-5 text-muted-foreground group-hover:text-foreground transition-colors flex-shrink-0" /> + </div> + <span className="text-[10px] text-muted-foreground group-hover:text-foreground transition-colors text-center leading-tight font-medium">USD</span> + </button> + </div> </div> </div> - </div> - </SheetContent> - </Sheet> + </SheetContent> + </Sheet> + ) : ( + <Button + variant="ghost" + size="icon" + className="md:hidden nav-button-transparent backdrop-blur-sm" + > + <Menu className="h-5 w-5" /> + </Button> + )} {/* Logo */} - <div className="flex items-center"> - <Link href="/" className="flex items-center space-x-2"> - {/* Light theme logo - visible by default, hidden in dark mode */} + <div className="flex items-center flex-1 md:flex-initial justify-center md:justify-start"> + <Link href="/" className="flex items-center space-x-2 ml-8 md:ml-0"> <Image src="/black-logo.png" alt="blcklst" @@ -381,7 +483,6 @@ export function Header() { className="h-8 w-auto block dark:hidden" priority /> - {/* Dark theme logo - hidden by default, visible in dark mode */} <Image src="/white-logo.png" alt="blcklst" @@ -441,7 +542,7 @@ export function Header() { </div> {/* Action buttons */} - <div className="flex items-center space-x-1 sm:space-x-2"> + <div className="flex items-center space-x-1 sm:space-x-2 flex-shrink-0"> {/* Search icon for mobile */} <Button variant="ghost" @@ -510,7 +611,7 @@ export function Header() { size="icon" className="relative nav-button-transparent backdrop-blur-sm min-w-[44px] min-h-[44px]" > - <ShoppingBag className="h-5 w-5" /> + <ShoppingBag className="h-4 w-4 sm:h-5 sm:w-5 text-muted-foreground flex-shrink-0" /> {cartItems > 0 && ( <Badge className="absolute -top-1 -right-1 h-5 w-5 rounded-full p-0 text-xs"> {cartItems} diff --git a/frontend/src/components/theme-toggle.tsx b/frontend/src/components/theme-toggle.tsx index 53d8286..7532775 100644 --- a/frontend/src/components/theme-toggle.tsx +++ b/frontend/src/components/theme-toggle.tsx @@ -26,10 +26,10 @@ export function ThemeToggle() { <Button variant="ghost" size="icon" - className="nav-button-transparent backdrop-blur-sm relative overflow-hidden transition-all duration-300 hover:scale-105 active:scale-95" + className="nav-button-transparent backdrop-blur-sm min-w-[44px] min-h-[44px]" disabled > - <Monitor className="h-[1.1rem] w-[1.1rem] text-muted-foreground/60" /> + <Monitor className="h-5 w-5" /> <span className="sr-only">Toggle theme</span> </Button> ) @@ -41,14 +41,11 @@ export function ThemeToggle() { <Button variant="ghost" size="icon" - className="nav-button-transparent backdrop-blur-sm relative overflow-hidden transition-all duration-300 hover:scale-105 active:scale-95 group" + className="nav-button-transparent backdrop-blur-sm min-w-[44px] min-h-[44px]" > - {/* Enhanced icon transitions with better positioning */} - <Sun className="h-[1.1rem] w-[1.1rem] rotate-0 scale-100 transition-all duration-500 ease-in-out dark:-rotate-180 dark:scale-0 text-amber-500 dark:text-amber-400 group-hover:text-amber-600 dark:group-hover:text-amber-300" /> - <Moon className="absolute h-[1.1rem] w-[1.1rem] rotate-180 scale-0 transition-all duration-500 ease-in-out dark:rotate-0 dark:scale-100 text-blue-600 dark:text-blue-400 group-hover:text-blue-700 dark:group-hover:text-blue-300" /> - - {/* Subtle background glow effect on hover */} - <div className="absolute inset-0 rounded-full bg-gradient-to-r from-amber-500/0 to-blue-500/0 group-hover:from-amber-500/10 group-hover:to-blue-500/10 dark:group-hover:from-amber-400/10 dark:group-hover:to-blue-400/10 transition-all duration-300" /> + {/* Simple icon transitions with consistent styling */} + <Sun className="h-5 w-5 rotate-0 scale-100 transition-all duration-500 ease-in-out dark:-rotate-180 dark:scale-0" /> + <Moon className="absolute h-5 w-5 rotate-180 scale-0 transition-all duration-500 ease-in-out dark:rotate-0 dark:scale-100" /> <span className="sr-only">Toggle theme</span> </Button> @@ -56,39 +53,39 @@ export function ThemeToggle() { <DropdownMenuContent align="end" - className="nav-dropdown-transparent min-w-[140px] animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-200" + className="nav-dropdown-transparent" sideOffset={8} > <DropdownMenuItem onClick={() => setTheme("light")} - className="flex items-center gap-3 nav-dropdown-item cursor-pointer group/item" + className="flex items-center gap-3 nav-dropdown-item cursor-pointer" > - <Sun className="h-4 w-4 text-amber-500 group-hover/item:text-amber-600 transition-colors duration-200" /> + <Sun className="h-4 w-4" /> <span className="flex-1">Light</span> {theme === "light" && ( - <span className="text-xs text-emerald-600 dark:text-emerald-400 font-medium animate-in fade-in-0 scale-in-75 duration-200">✓</span> + <span className="text-xs font-medium">✓</span> )} </DropdownMenuItem> <DropdownMenuItem onClick={() => setTheme("dark")} - className="flex items-center gap-3 nav-dropdown-item cursor-pointer group/item" + className="flex items-center gap-3 nav-dropdown-item cursor-pointer" > - <Moon className="h-4 w-4 text-blue-600 dark:text-blue-400 group-hover/item:text-blue-700 dark:group-hover/item:text-blue-300 transition-colors duration-200" /> + <Moon className="h-4 w-4" /> <span className="flex-1">Dark</span> {theme === "dark" && ( - <span className="text-xs text-emerald-600 dark:text-emerald-400 font-medium animate-in fade-in-0 scale-in-75 duration-200">✓</span> + <span className="text-xs font-medium">✓</span> )} </DropdownMenuItem> <DropdownMenuItem onClick={() => setTheme("system")} - className="flex items-center gap-3 nav-dropdown-item cursor-pointer group/item" + className="flex items-center gap-3 nav-dropdown-item cursor-pointer" > - <Monitor className="h-4 w-4 text-slate-600 dark:text-slate-400 group-hover/item:text-slate-700 dark:group-hover/item:text-slate-300 transition-colors duration-200" /> + <Monitor className="h-4 w-4" /> <span className="flex-1">System</span> {theme === "system" && ( - <span className="text-xs text-emerald-600 dark:text-emerald-400 font-medium animate-in fade-in-0 scale-in-75 duration-200">✓</span> + <span className="text-xs font-medium">✓</span> )} </DropdownMenuItem> </DropdownMenuContent> |