Files
portfolio/src/components/FloatingNav.tsx
T
admin 6cc54d8a29 Task 11: Implement scroll animations and responsive design
- Add xs (480px) breakpoint to tailwind config for mobile
- Standardize scroll-reveal animations to opacity 0→1, y 24→0
- Add responsive padding to main container (px-5 xs:px-6 md:px-8)
- Add responsive section padding (py-12 xs:py-16 md:py-20)
- FloatingNav: responsive width and font/padding on mobile
- Hero: responsive vitals grid, title font clamp to 28px min
- Skills: responsive grid (2→3→auto-fit), smaller gauges on mobile
- Experience: responsive card padding, ECG decoration size
- Education/Projects: responsive grids matching concept.html
- Contact/Footer: responsive padding
2026-02-10 17:20:27 +00:00

69 lines
2.2 KiB
TypeScript

import { useCallback } from 'react'
import { motion } from 'framer-motion'
import { useActiveSection } from '@/hooks/useActiveSection'
interface NavLink {
id: string
label: string
}
const navLinks: NavLink[] = [
{ id: 'about', label: 'About' },
{ id: 'skills', label: 'Skills' },
{ id: 'experience', label: 'Experience' },
{ id: 'education', label: 'Education' },
{ id: 'projects', label: 'Projects' },
{ id: 'contact', label: 'Contact' },
]
export function FloatingNav() {
const activeSection = useActiveSection()
const scrollToSection = useCallback((sectionId: string) => {
const element = document.getElementById(sectionId)
if (element) {
element.scrollIntoView({ behavior: 'smooth' })
}
}, [])
return (
<motion.nav
className="fixed top-4 left-1/2 -translate-x-1/2 z-[100] max-w-[600px] w-[calc(100%-32px)] md:w-auto bg-white rounded-full py-2 px-4 md:px-6 shadow-md flex items-center gap-1 border border-border overflow-x-auto scrollbar-hide"
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, ease: 'easeOut' }}
>
{navLinks.map((link) => {
const isActive = activeSection === link.id
return (
<button
key={link.id}
onClick={() => scrollToSection(link.id)}
className={`
relative font-secondary text-[11px] xs:text-[13px] font-medium py-1.5 px-2.5 xs:px-3.5 rounded-full
transition-colors duration-300 ease-out whitespace-nowrap
${isActive
? 'text-teal font-semibold'
: 'text-muted hover:text-teal hover:bg-teal-light'
}
`}
>
{link.label}
{isActive && (
<motion.span
className="absolute bottom-0 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-teal"
layoutId="navIndicator"
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
/>
)}
</button>
)
})}
</motion.nav>
)
}