feat: better navigation, updated cc.json, icons on homepage, better structure, cleanup manifesto page, NowPlaying.tsx fix

This commit is contained in:
Aidan 2025-09-01 05:08:38 -04:00
parent c1f0832f4a
commit f81b145bf7
9 changed files with 773 additions and 252 deletions

View file

@ -12,8 +12,11 @@ import {
Menu,
Globe,
ChevronDown,
Brain
ChevronRight,
Brain,
Smartphone
} from 'lucide-react'
import { SiClaude, SiGoogle } from 'react-icons/si'
import { useTranslation } from 'react-i18next'
interface NavItemProps {
@ -31,6 +34,181 @@ const NavItem = ({ href, icon, children }: NavItemProps) => (
</div>
);
interface DropdownNavItemProps {
id: string;
href: string;
icon: React.ElementType;
children: React.ReactNode;
dropdownContent: React.ReactNode;
isMobile?: boolean;
isOpen?: boolean;
onOpenChange?: (id: string | null) => void;
}
const DropdownNavItem = ({ id, href, icon, children, dropdownContent, isMobile = false, isOpen = false, onOpenChange }: DropdownNavItemProps) => {
const dropdownRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
onOpenChange?.(null);
}
};
if (isMobile && isOpen) {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}
}, [isMobile, isOpen, onOpenChange]);
const handleMouseEnter = () => {
if (!isMobile) {
onOpenChange?.(id);
}
};
const handleMouseLeave = (e: React.MouseEvent) => {
if (!isMobile) {
const relatedTarget = e.relatedTarget as HTMLElement;
if (relatedTarget && dropdownRef.current?.contains(relatedTarget)) {
return;
}
onOpenChange?.(null);
}
};
const handleClick = (e: React.MouseEvent) => {
if (isMobile) {
e.preventDefault();
onOpenChange?.(isOpen ? null : id);
}
};
return (
<div
className="nav-item relative"
ref={dropdownRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<Link
href={href}
onClick={isMobile ? handleClick : undefined}
className="flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all duration-300 w-full"
>
{React.createElement(icon, { className: "text-md mr-2", strokeWidth: 2.5, size: 20 })}
<span className="flex-1">{children}</span>
<ChevronDown className={`ml-2 transform transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`} strokeWidth={2.5} size={16} />
</Link>
{isOpen && (
<>
{/* Invisible bridge to handle gap */}
{!isMobile && (
<div className="absolute left-0 top-full w-full h-1 z-50" />
)}
<div
className={`${
isMobile
? 'relative mt-2 w-full bg-gray-700/50 rounded-md'
: 'absolute left-0 mt-1 z-50 flex'
}`}
>
{dropdownContent}
</div>
</>
)}
</div>
);
};
interface NestedDropdownItemProps {
children: React.ReactNode;
nestedContent: React.ReactNode;
isMobile?: boolean;
}
const NestedDropdownItem = ({ children, nestedContent, isMobile = false }: NestedDropdownItemProps) => {
const [isOpen, setIsOpen] = useState(false);
const itemRef = useRef<HTMLDivElement>(null);
const handleMouseEnter = () => {
if (!isMobile) {
setIsOpen(true);
}
};
const handleMouseLeave = (e: React.MouseEvent) => {
if (!isMobile) {
const relatedTarget = e.relatedTarget as HTMLElement;
if (relatedTarget && itemRef.current?.contains(relatedTarget)) {
return;
}
setIsOpen(false);
}
};
const handleClick = (e: React.MouseEvent) => {
if (isMobile) {
e.preventDefault();
setIsOpen(!isOpen);
}
};
if (isMobile) {
return (
<div
className="relative"
ref={itemRef}
>
<button
onClick={handleClick}
className="flex items-center justify-between w-full text-left px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300"
>
<span className="flex items-center">
<Smartphone className="mr-3" strokeWidth={2.5} size={18} />
{children}
</span>
<ChevronRight className={`transform transition-transform duration-200 ${isOpen ? '-rotate-90' : ''}`} strokeWidth={2.5} size={18} />
</button>
{isOpen && (
<div className="relative mt-2 ml-4 bg-gray-700/30 rounded-md">
{nestedContent}
</div>
)}
</div>
);
}
return (
<div
className="relative"
ref={itemRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<button
onClick={handleClick}
className="flex items-center justify-between w-full text-left px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300"
>
<span className="flex items-center">
<Smartphone className="mr-3" strokeWidth={2.5} size={18} />
{children}
</span>
<ChevronRight className={`transform transition-transform duration-200 ${isOpen ? 'rotate-0' : 'rotate-90'}`} strokeWidth={2.5} size={18} />
</button>
{isOpen && (
<>
{/* Invisible bridge to handle gap */}
<div className="absolute left-full top-0 w-2 h-full z-50" />
<div className="absolute left-full top-0 ml-2 w-64 bg-gray-800 rounded-lg shadow-xl border border-gray-700 z-50">
{nestedContent}
</div>
</>
)}
</div>
);
};
const LanguageSelector = () => {
const { i18n } = useTranslation();
const [isOpen, setIsOpen] = useState(false);
@ -63,9 +241,33 @@ const LanguageSelector = () => {
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
if (isMobile) {
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}
}, [isMobile]);
const handleMouseEnter = () => {
if (!isMobile) {
setIsOpen(true);
}
};
const handleMouseLeave = (e: React.MouseEvent) => {
if (!isMobile) {
const relatedTarget = e.relatedTarget as HTMLElement;
if (relatedTarget && dropdownRef.current?.contains(relatedTarget)) {
return;
}
setIsOpen(false);
}
};
const handleClick = () => {
if (isMobile) {
setIsOpen(!isOpen);
}
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Escape') {
@ -76,53 +278,56 @@ const LanguageSelector = () => {
}
};
const buttonContent = (
<>
<Globe className="text-md mr-2" strokeWidth={2.5} size={20} />
{languages.find(lang => lang.code === i18n.language)?.name || 'English'}
{!isMobile && (
<ChevronDown className={`w-4 h-4 ml-1 transform transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`} strokeWidth={2.5} size={20} />
)}
</>
);
return (
<div className="relative" ref={dropdownRef}>
<div
className="relative"
ref={dropdownRef}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<button
onClick={() => setIsOpen(!isOpen)}
onClick={handleClick}
onKeyDown={handleKeyDown}
className={`flex items-center text-gray-300 hover:text-white hover:bg-gray-700 rounded-md px-3 py-2 transition-all duration-300 ${isMobile ? 'w-full' : ''}`}
aria-expanded={isOpen}
aria-haspopup="true"
>
{buttonContent}
<Globe className="text-md mr-2" strokeWidth={2.5} size={20} />
<span className="flex-1">{languages.find(lang => lang.code === i18n.language)?.name || 'English'}</span>
<ChevronDown className={`ml-2 transform transition-transform duration-200 ${isOpen ? 'rotate-180' : ''}`} strokeWidth={2.5} size={16} />
</button>
{isOpen && (
<div
className={`${
isMobile
? 'relative mt-1 w-full bg-gray-800 rounded-md shadow-lg'
: 'absolute right-0 mt-2 w-48 bg-gray-800 rounded-md shadow-lg z-50'
}`}
role="menu"
aria-orientation="vertical"
aria-labelledby="language-menu"
>
{languages.map((lang) => (
<button
key={lang.code}
onClick={() => changeLanguage(lang.code)}
className={`block w-full text-left px-4 py-2 text-sm ${
i18n.language === lang.code
? 'text-white bg-gray-700'
: 'text-gray-300 hover:text-white hover:bg-gray-700'
}`}
role="menuitem"
>
{lang.name}
</button>
))}
</div>
<>
{/* Invisible bridge to handle gap */}
{!isMobile && (
<div className="absolute right-0 top-full w-56 h-2 z-50" />
)}
<div
className={`${
isMobile
? 'relative mt-2 w-full bg-gray-700/50 rounded-md'
: 'absolute right-0 mt-2 w-56 bg-gray-800 rounded-lg shadow-xl border border-gray-700 z-50'
}`}
role="menu"
aria-orientation="vertical"
aria-labelledby="language-menu"
>
{languages.map((lang) => (
<button
key={lang.code}
onClick={() => changeLanguage(lang.code)}
className={`block w-full text-left px-5 py-3 text-base rounded-md ${
i18n.language === lang.code
? 'text-white bg-gray-700'
: 'text-gray-300 hover:text-white hover:bg-gray-700'
} transition-all duration-300`}
role="menuitem"
>
{lang.name}
</button>
))}
</div>
</>
)}
</div>
);
@ -130,39 +335,125 @@ const LanguageSelector = () => {
export default function Header() {
const [isOpen, setIsOpen] = useState(false);
const [isMobile, setIsMobile] = useState(false);
const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
const toggleMenu = () => setIsOpen(!isOpen);
return (
<header className="bg-gray-800 relative">
{isOpen && (
<div
className="fixed inset-0 backdrop-blur-md z-40 lg:hidden"
onClick={toggleMenu}
/>
)}
<nav className="container mx-auto px-4 py-4 flex justify-between items-center relative z-50">
<Link href="/" className="text-gray-300 hover:text-white text-2xl font-bold transition-all duration-300 hover:glow">
aidxn.cc
useEffect(() => {
const checkMobile = () => {
setIsMobile(window.innerWidth < 1024);
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
const aboutDropdownContent = (
<>
<div className="w-64 bg-gray-800 rounded-lg shadow-xl border border-gray-700">
<Link href="/about" className="flex items-center px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300">
<User className="mr-3" strokeWidth={2.5} size={18} />
About Me
</Link>
<button onClick={toggleMenu} className="lg:hidden text-gray-300 focus:outline-hidden">
{isOpen ? <X className="text-2xl" /> : <Menu className="text-2xl" />}
</button>
<ul className={`flex flex-col lg:flex-row space-y-2 lg:space-y-0 lg:space-x-4 absolute lg:static bg-gray-800 lg:bg-transparent w-full lg:w-auto left-0 lg:left-auto top-full lg:top-auto p-4 lg:p-0 transition-all duration-300 ease-in-out z-50 ${isOpen ? 'flex' : 'hidden lg:flex'}`}>
<NavItem href="/" icon={House}>Home</NavItem>
<NavItem href="/about" icon={User}>About</NavItem>
<NavItem href="/ai" icon={Brain}>AI</NavItem>
<NavItem href="/contact" icon={Phone}>Contact</NavItem>
<NavItem href="/domains" icon={LinkIcon}>Domains</NavItem>
<NavItem href="/manifesto" icon={BookOpen}>Manifesto</NavItem>
<div className="lg:hidden">
<NestedDropdownItem
isMobile={isMobile}
nestedContent={
<>
<Link href="/device/bonito" className="flex items-center px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300">
<SiGoogle className="mr-3" size={18} />
Pixel 3a XL (bonito)
</Link>
<Link href="/device/cheetah" className="flex items-center px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300">
<SiGoogle className="mr-3" size={18} />
Pixel 7 Pro (cheetah)
</Link>
<Link href="/device/komodo" className="flex items-center px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300">
<SiGoogle className="mr-3" size={18} />
Pixel 9 Pro (komodo)
</Link>
</>
}
>
Devices
</NestedDropdownItem>
</div>
</>
);
const aiDropdownContent = (
<div className="w-64 bg-gray-800 rounded-lg shadow-xl border border-gray-700">
<Link href="/ai" className="flex items-center px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300">
<Brain className="mr-3" strokeWidth={2.5} size={18} />
AI
</Link>
<Link href="/ai/claude" className="flex items-center px-5 py-3 text-base text-gray-300 hover:text-white hover:bg-gray-700 rounded-md transition-all duration-300">
<SiClaude className="mr-3" size={18} />
Claude Usage
</Link>
</div>
);
return (
<>
<div
className={`fixed inset-0 z-30 pointer-events-none transition-all duration-300 ${
activeDropdown && !isMobile
? 'backdrop-blur-sm opacity-100'
: 'backdrop-blur-none opacity-0'
}`}
/>
<header className="bg-gray-800 relative">
{isOpen && (
<div
className="fixed inset-0 backdrop-blur-md z-40 lg:hidden"
onClick={toggleMenu}
/>
)}
<nav className="container mx-auto px-4 py-4 flex justify-between items-center relative z-50">
<Link href="/" className="text-gray-300 hover:text-white text-2xl font-bold transition-all duration-300 hover:glow">
aidxn.cc
</Link>
<button onClick={toggleMenu} className="lg:hidden text-gray-300 focus:outline-hidden">
{isOpen ? <X className="text-2xl" /> : <Menu className="text-2xl" />}
</button>
<ul className={`flex flex-col lg:flex-row space-y-2 lg:space-y-0 lg:space-x-4 absolute lg:static bg-gray-800 lg:bg-transparent w-full lg:w-auto left-0 lg:left-auto top-full lg:top-auto p-4 lg:p-0 transition-all duration-300 ease-in-out z-50 ${isOpen ? 'flex' : 'hidden lg:flex'}`}>
<NavItem href="/" icon={House}>Home</NavItem>
<DropdownNavItem
id="about"
href="/about"
icon={User}
dropdownContent={aboutDropdownContent}
isMobile={isMobile}
isOpen={activeDropdown === 'about'}
onOpenChange={setActiveDropdown}
>
About
</DropdownNavItem>
<DropdownNavItem
id="ai"
href="/ai"
icon={Brain}
dropdownContent={aiDropdownContent}
isMobile={isMobile}
isOpen={activeDropdown === 'ai'}
onOpenChange={setActiveDropdown}
>
AI
</DropdownNavItem>
<NavItem href="/contact" icon={Phone}>Contact</NavItem>
<NavItem href="/domains" icon={LinkIcon}>Domains</NavItem>
<NavItem href="/manifesto" icon={BookOpen}>Manifesto</NavItem>
<div className="lg:hidden">
<LanguageSelector />
</div>
</ul>
<div className="hidden lg:block">
<LanguageSelector />
</div>
</ul>
<div className="hidden lg:block">
<LanguageSelector />
</div>
</nav>
</header>
</nav>
</header>
</>
);
}

View file

@ -181,10 +181,10 @@ const NowPlaying: React.FC = () => {
rel="noopener noreferrer"
className="bg-gradient-to-b from-gray-700 to-gray-900 border-b border-gray-700 px-2 py-0 block" style={{background: 'linear-gradient(to bottom, #4b5563 0%, #374151 30%, #1f2937 70%, #111827 100%)'}}
>
<div className="text-center leading-none">
<ScrollTxt text={currentTrack.artist_name.toUpperCase()} type="artist" className="-my-0.5" />
<ScrollTxt text={currentTrack.track_name} type="track" className="-my-0.5" />
{currentTrack.release_name && <ScrollTxt text={currentTrack.release_name} type="release" className="-mt-1.5 mb-0.5" />}
<div className="text-center leading-none pb-1">
<ScrollTxt text={currentTrack.artist_name.toUpperCase()} type="artist" />
<ScrollTxt text={currentTrack.track_name} type="track" className="-mt-0.5" />
{currentTrack.release_name && <ScrollTxt text={currentTrack.release_name} type="release" />}
</div>
</a>
{/* Album art */}
@ -202,70 +202,6 @@ const NowPlaying: React.FC = () => {
</div>
)}
</div>
{/* Player controls and seekbar */}
<div className="bg-gradient-to-b from-gray-700 to-gray-900 pb-2.5 flex flex-col items-center" style={{background: 'linear-gradient(to bottom, #4b5563 0%, #374151 30%, #1f2937 70%, #111827 100%)'}}>
<div className="flex justify-center items-center gap-0 px-2">
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="34" viewBox="0 0 24 20" className="drop-shadow-sm">
<defs>
<linearGradient id="skipBackGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<rect x="2" y="4" width="2" height="12" fill="url(#skipBackGradient)" />
<polygon points="12,4 6,10 12,16" fill="url(#skipBackGradient)" />
<polygon points="20,4 12,10 20,16" fill="url(#skipBackGradient)" />
</svg>
</button>
<div className="w-[1px] h-6 bg-gray-800 mx-0.5"></div>
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="38" viewBox="0 0 24 24" className="drop-shadow-sm">
<defs>
<linearGradient id="pauseGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<rect x="6" y="4" width="4" height="16" fill="url(#pauseGradient)" />
<rect x="14" y="4" width="4" height="16" fill="url(#pauseGradient)" />
</svg>
</button>
<div className="w-[1px] h-6 bg-gray-800 mx-1"></div>
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="34" viewBox="0 0 24 20" className="drop-shadow-sm">
<defs>
<linearGradient id="skipForwardGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<polygon points="2,4 9,10 2,16" fill="url(#skipForwardGradient)" />
<polygon points="9,4 17,10 9,16" fill="url(#skipForwardGradient)" />
<rect x="18" y="4" width="2" height="12" fill="url(#skipForwardGradient)" />
</svg>
</button>
</div>
<div className="relative w-full flex justify-center mt-1">
<div className="w-38 h-2 bg-gray-800 rounded-full relative">
<div className="absolute inset-0 bg-gradient-to-b from-white to-gray-600 rounded-full" style={{width: `${volume}%`}} />
<div
className="absolute top-1/2 transform -translate-y-1/2 w-3.5 h-3.5 bg-gradient-to-b from-gray-200 via-gray-300 to-gray-500 rounded-full border border-gray-400 shadow-inner" style={{
left: `calc(${volume}% - 8px)`,
backgroundImage: 'radial-gradient(circle at 30% 30%, #f0f0f0 0%, #c0c0c0 60%, #808080 100%), repeating-conic-gradient(#f9fafb 0deg 45deg, #9ca3af 45deg 90deg)',
backgroundBlendMode: 'overlay',
boxShadow: 'inset 0 1px 2px rgba(0,0,0,0.3), 0 1px 2px rgba(255,255,255,0.5)'
}}></div>
<input type="range" min="0" max="100" value={volume} onChange={(e) => setVolume(Number(e.target.value))} className="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer" />
</div>
</div>
</div>
</>
)
}
@ -283,89 +219,89 @@ const NowPlaying: React.FC = () => {
<div className="absolute right-1 -top-[3px] w-9 h-[3px] bg-[#BFAF8A] rounded-t-2xl cursor-pointer" onClick={() => setScreenOn(prev => !prev)}></div>
{/* White bezel (fuses screen+home btn) */}
<div className="absolute inset-2 bg-white rounded-sm overflow-hidden flex flex-col">
{/* Virtual screen */}
{/* Virtual screen */}
<div className="mx-2 mt-2 flex-1 bg-black overflow-hidden flex flex-col">
{screenOn && (
<div className="bg-gradient-to-b from-gray-700 via-gray-800 to-gray-900 border-b border-gray-700" style={{background: 'linear-gradient(to bottom, #4b5563 0%, #374151 30%, #1f2937 70%, #111827 100%)'}}>
<div className="relative flex items-center pr-1 py-0.5">
<FaBluetoothB size={14} className="text-gray-400" />
<div className="absolute left-1/2 transform -translate-x-1/2 text-white text-xs font-medium">{formatTime(currentTime)}</div>
<div className="flex items-center gap-0.5 ml-auto ">
<IoIosPlay size={14} className="text-white" />
<IoBatteryFullSharp size={18} className="text-white" />
</div>
{screenOn && (
<div className="bg-gradient-to-b from-gray-700 via-gray-800 to-gray-900 border-b border-gray-700" style={{background: 'linear-gradient(to bottom, #4b5563 0%, #374151 30%, #1f2937 70%, #111827 100%)'}}>
<div className="relative flex items-center pr-1 py-0.5">
<FaBluetoothB size={14} className="text-gray-400" />
<div className="absolute left-1/2 transform -translate-x-1/2 text-white text-xs font-medium">{formatTime(currentTime)}</div>
<div className="flex items-center gap-0.5 ml-auto ">
<IoIosPlay size={14} className="text-white" />
<IoBatteryFullSharp size={18} className="text-white" />
</div>
</div>
)}
{screenOn ? renderScreenContent() : (
<div className="w-full h-full bg-black"></div>
)}
{/* Player controls and seekbar */}
{screenOn && track && (
<div className="bg-gradient-to-b from-gray-700 to-gray-900 pb-2.5 flex flex-col items-center" style={{background: 'linear-gradient(to bottom, #4b5563 0%, #374151 30%, #1f2937 70%, #111827 100%)'}}>
<div className="flex justify-center items-center gap-0 px-2">
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="34" viewBox="0 0 24 20" className="drop-shadow-sm">
<defs>
<linearGradient id="skipBackGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<rect x="2" y="4" width="2" height="12" fill="url(#skipBackGradient)" />
<polygon points="12,4 6,10 12,16" fill="url(#skipBackGradient)" />
<polygon points="20,4 12,10 20,16" fill="url(#skipBackGradient)" />
</svg>
</button>
<div className="w-[1px] h-6 bg-gray-800 mx-0.5"></div>
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="38" viewBox="0 0 24 24" className="drop-shadow-sm">
<defs>
<linearGradient id="pauseGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<rect x="6" y="4" width="4" height="16" fill="url(#pauseGradient)" />
<rect x="14" y="4" width="4" height="16" fill="url(#pauseGradient)" />
</svg>
</button>
<div className="w-[1px] h-6 bg-gray-800 mx-1"></div>
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="34" viewBox="0 0 24 20" className="drop-shadow-sm">
<defs>
<linearGradient id="skipForwardGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<polygon points="2,4 9,10 2,16" fill="url(#skipForwardGradient)" />
<polygon points="9,4 17,10 9,16" fill="url(#skipForwardGradient)" />
<rect x="18" y="4" width="2" height="12" fill="url(#skipForwardGradient)" />
</svg>
</button>
</div>
<div className="relative w-full flex justify-center mt-1">
<div className="w-38 h-2 bg-gray-800 rounded-full relative">
<div className="absolute inset-0 bg-gradient-to-b from-white to-gray-600 rounded-full" style={{width: `${volume}%`}} />
<div
className="absolute top-1/2 transform -translate-y-1/2 w-3.5 h-3.5 bg-gradient-to-b from-gray-200 via-gray-300 to-gray-500 rounded-full border border-gray-400 shadow-inner" style={{
left: `calc(${volume}% - 8px)`,
backgroundImage: 'radial-gradient(circle at 30% 30%, #f0f0f0 0%, #c0c0c0 60%, #808080 100%), repeating-conic-gradient(#f9fafb 0deg 45deg, #9ca3af 45deg 90deg)',
backgroundBlendMode: 'overlay',
boxShadow: 'inset 0 1px 2px rgba(0,0,0,0.3), 0 1px 2px rgba(255,255,255,0.5)'
}}></div>
<input type="range" min="0" max="100" value={volume} onChange={(e) => setVolume(Number(e.target.value))} className="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer" />
</div>
</div>
)}
{screenOn ? renderScreenContent() : (
<div className="w-full h-full bg-black"></div>
)}
{/* Player controls and seekbar */}
{screenOn && track && (
<div className="bg-gradient-to-b from-gray-700 to-gray-900 pb-2.5 flex flex-col items-center" style={{background: 'linear-gradient(to bottom, #4b5563 0%, #374151 30%, #1f2937 70%, #111827 100%)'}}>
<div className="flex justify-center items-center gap-0 px-2">
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="34" viewBox="0 0 24 20" className="drop-shadow-sm">
<defs>
<linearGradient id="skipBackGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<rect x="2" y="4" width="2" height="12" fill="url(#skipBackGradient)" />
<polygon points="12,4 6,10 12,16" fill="url(#skipBackGradient)" />
<polygon points="20,4 12,10 20,16" fill="url(#skipBackGradient)" />
</svg>
</button>
<div className="w-[1px] h-6 bg-gray-800 mx-0.5"></div>
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="38" viewBox="0 0 24 24" className="drop-shadow-sm">
<defs>
<linearGradient id="pauseGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<rect x="6" y="4" width="4" height="16" fill="url(#pauseGradient)" />
<rect x="14" y="4" width="4" height="16" fill="url(#pauseGradient)" />
</svg>
</button>
<div className="w-[1px] h-6 bg-gray-800 mx-1"></div>
<button className="hover:drop-shadow-[0_0_8px_rgba(255,255,255,0.9)] hover:filter hover:brightness-110 transition-all duration-200 p-1 rounded-full overflow-hidden">
<svg width="38" height="34" viewBox="0 0 24 20" className="drop-shadow-sm">
<defs>
<linearGradient id="skipForwardGradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor="#f9fafb" />
<stop offset="49%" stopColor="#e5e7eb" />
<stop offset="51%" stopColor="#6b7280" />
<stop offset="100%" stopColor="#d1d5db" />
</linearGradient>
</defs>
<polygon points="2,4 9,10 2,16" fill="url(#skipForwardGradient)" />
<polygon points="9,4 17,10 9,16" fill="url(#skipForwardGradient)" />
<rect x="18" y="4" width="2" height="12" fill="url(#skipForwardGradient)" />
</svg>
</button>
</div>
<div className="relative w-full flex justify-center mt-1">
<div className="w-38 h-2 bg-gray-800 rounded-full relative">
<div className="absolute inset-0 bg-gradient-to-b from-white to-gray-600 rounded-full" style={{width: `${volume}%`}} />
<div
className="absolute top-1/2 transform -translate-y-1/2 w-3.5 h-3.5 bg-gradient-to-b from-gray-200 via-gray-300 to-gray-500 rounded-full border border-gray-400 shadow-inner" style={{
left: `calc(${volume}% - 8px)`,
backgroundImage: 'radial-gradient(circle at 30% 30%, #f0f0f0 0%, #c0c0c0 60%, #808080 100%), repeating-conic-gradient(#f9fafb 0deg 45deg, #9ca3af 45deg 90deg)',
backgroundBlendMode: 'overlay',
boxShadow: 'inset 0 1px 2px rgba(0,0,0,0.3), 0 1px 2px rgba(255,255,255,0.5)'
}}></div>
<input type="range" min="0" max="100" value={volume} onChange={(e) => setVolume(Number(e.target.value))} className="absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer" />
</div>
</div>
)}
</div>
)}
</div>
{/* Home button */}
<div className="flex justify-center py-2">