feat: Build Skills section with SVG circular gauges

- Create Skills.tsx with three categories (Technical, Clinical, Strategic)
- Add SkillGauge component with animated circular SVG progress
- Create useScrollReveal.ts hook for IntersectionObserver-based animations
- Staggered gauge fill animations (100ms delay per skill)
- Exact 18 skills with percentages from concept.html
- Hover effects matching concept.html styling
This commit is contained in:
2026-02-10 16:39:39 +00:00
parent 293e292698
commit 0ffc71f110
3 changed files with 237 additions and 6 deletions
+40
View File
@@ -0,0 +1,40 @@
import { useEffect, useRef, useState, type RefObject } from 'react'
interface UseScrollRevealOptions {
threshold?: number
rootMargin?: string
triggerOnce?: boolean
}
export function useScrollReveal<T extends HTMLElement>(
options: UseScrollRevealOptions = {}
): [RefObject<T | null>, boolean] {
const { threshold = 0.15, rootMargin = '0px', triggerOnce = true } = options
const ref = useRef<T | null>(null)
const [isVisible, setIsVisible] = useState(false)
useEffect(() => {
const element = ref.current
if (!element) return
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true)
if (triggerOnce) {
observer.unobserve(element)
}
} else if (!triggerOnce) {
setIsVisible(false)
}
},
{ threshold, rootMargin }
)
observer.observe(element)
return () => observer.disconnect()
}, [threshold, rootMargin, triggerOnce])
return [ref, isVisible]
}