From 4685f6400bb0fe7ead998d3bd78268ad1b31c168 Mon Sep 17 00:00:00 2001 From: rahan Date: Fri, 26 Jun 2026 00:28:40 +0200 Subject: [PATCH] fix(nav): refactor desktop layout and rebuild mobile as GSAP accordion pill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Desktop: grid → flex gap-8, avatar gap-2 → gap-3, remove dead wrapper div. Mobile: replace bare flex bar with a floating pill (24px radius, dark glass) containing an integrated accordion body animated by GSAP (height auto/0). Accordion footer adds availability badge + GitHub icon separated by a divider. Text sizes bumped to base for logo and links, sm for badge. Co-Authored-By: Claude Sonnet 4.6 --- components/layout/StickyNav.tsx | 160 ++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 47 deletions(-) diff --git a/components/layout/StickyNav.tsx b/components/layout/StickyNav.tsx index c5b8080..354ce7b 100644 --- a/components/layout/StickyNav.tsx +++ b/components/layout/StickyNav.tsx @@ -26,6 +26,8 @@ export function StickyNav() { const ulRef = useRef(null) const linkRefs = useRef<(HTMLAnchorElement | null)[]>([]) const hasAnimated = useRef(false) + const mobilePillRef = useRef(null) + const mobileAccordionRef = useRef(null) useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 60) @@ -55,6 +57,7 @@ export function StickyNav() { return () => observer.disconnect() }, [isHome]) + // Desktop indicator animation useGSAP(() => { const ul = ulRef.current if (!ul) return @@ -89,29 +92,55 @@ export function StickyNav() { } }, { dependencies: [activeSection] }) + // Mobile accordion — set initial state + useGSAP(() => { + gsap.set(mobileAccordionRef.current, { height: 0 }) + gsap.set(mobilePillRef.current, { borderRadius: 24 }) + }, { dependencies: [] }) + + // Mobile accordion — animate on toggle + useGSAP(() => { + const accordion = mobileAccordionRef.current + const pill = mobilePillRef.current + if (!accordion || !pill) return + + if (menuOpen) { + gsap.to(accordion, { + height: 'auto', + duration: 0.35, + ease: 'power3.out', + overwrite: true, + }) + } else { + gsap.to(accordion, { + height: 0, + duration: 0.25, + ease: 'power3.in', + overwrite: true, + }) + } + }, { dependencies: [menuOpen] }) + + const pillBg = scrolled + ? 'bg-black/90 border-white/[0.08]' + : 'bg-white/[0.08] border-white/[0.12]' + return (
{/* Desktop — centered floating dark pill */}
-
-
- {/* Mobile — simple flex row */} - - - {menuOpen && ( - <> - {/* ponytail: backdrop dismiss */} + {/* Mobile — pill with integrated accordion */} +
+ {/* ponytail: backdrop dismiss */} + {menuOpen && (
) }