import { useEffect, useRef, useState } from 'react'; import { ArrowRight, BookOpen, ChevronDown, ExternalLink, Menu, Moon, Share2, Sun, Users, } from 'lucide-react'; import GithubMark from './components/GithubMark'; interface MinistryView { name: string; blurb: string; linkUrl: string | null; linkLabel: string | null; badge: string | null; style: 'FEATURE' | 'LIGHT' | 'DARK' | 'OUTLINE'; imageUrl: string | null; statusNote: string | null; } interface LabView { name: string; repo: string; linkUrl: string } interface Network { ministries: MinistryView[]; labs: LabView[] } /** Fades a section up the first time it scrolls into view. */ function useReveal() { const ref = useRef(null); useEffect(() => { const el = ref.current; if (!el) return; const observer = new IntersectionObserver( (entries) => entries.forEach((e) => { if (e.isIntersecting) { e.target.classList.add('reveal-active'); observer.unobserve(e.target); } }), { threshold: 0.1 }, ); observer.observe(el); return () => observer.disconnect(); }, []); return ref; } function ScrollProgress() { const [pct, setPct] = useState(0); useEffect(() => { const onScroll = () => { const max = document.documentElement.scrollHeight - window.innerHeight; setPct(max > 0 ? window.scrollY / max : 0); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); return () => window.removeEventListener('scroll', onScroll); }, []); return (