const { useState, useEffect, useRef } = React; // ── Route hook ────────────────────────────────────────────────────────────── function useRoute() { const [route, setRoute] = useState(window.location.hash || '#/'); useEffect(() => { const handler = () => setRoute(window.location.hash || '#/'); window.addEventListener('hashchange', handler); return () => window.removeEventListener('hashchange', handler); }, []); return route; } // ── Scroll reveal hook ────────────────────────────────────────────────────── function useScrollReveal(dep) { useEffect(() => { const els = document.querySelectorAll('.reveal'); const observer = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('revealed'); }); }, { threshold: 0.08 }); els.forEach(el => observer.observe(el)); return () => observer.disconnect(); }, [dep]); } // ── Nav ───────────────────────────────────────────────────────────────────── function Nav({ route }) { const [scrolled, setScrolled] = useState(false); const [open, setOpen] = useState(false); useEffect(() => { const h = () => setScrolled(window.scrollY > 60); window.addEventListener('scroll', h); return () => window.removeEventListener('scroll', h); }, []); useEffect(() => { setOpen(false); }, [route]); const links = [ { href: '#/', label: 'Home' }, { href: '#/watch', label: 'Watch' }, { href: '#/music', label: 'Music' }, { href: '#/merch', label: 'Merch' }, { href: '#/resources', label: 'Resources' }, { href: '#/about', label: 'About' }, { href: '#/contact', label: 'Contact' }, ]; return ( ); } // ── Social icons ───────────────────────────────────────────────────────────── function SocialLinks() { const socials = [ { label: 'X', href: 'https://x.com/The_Idol_Killer', icon: }, { label: 'Facebook', href: 'https://www.facebook.com/IdolKiller', icon: }, { label: 'Kick', href: 'https://kick.com/idolkiller', icon: }, { label: 'Patreon', href: 'https://www.patreon.com/IdolKiller', icon: }, ]; return (
{socials.map(s => ( {s.icon} ))}
); } // ── Footer ────────────────────────────────────────────────────────────────── function Footer() { return ( ); } // ── Category badge ─────────────────────────────────────────────────────────── function CategoryBadge({ label }) { const colors = { 'Calvinism': '#8855cc', 'Original Sin': '#cc5511', 'Atonement': '#cc1111', 'Molinism': '#1155cc', 'Dynamic Omniscience': '#117755', 'Debates & Responses': '#cc9911', 'Church History': '#667788', 'Theology': '#444', }; const bg = colors[label] || '#444'; return ( {label} ); } // ── Video card ──────────────────────────────────────────────────────────────── function VideoCard({ video, onClick }) { const thumb = video.thumb || `https://i.ytimg.com/vi/${video.id}/hqdefault.jpg`; const dateStr = video.date ? new Date(video.date).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }) : ''; return (
onClick && onClick(video)}>
{video.title} { e.target.style.display = 'none'; }} />
{video.duration && {video.duration}}
{video.category && }

{video.title}

{dateStr && {dateStr}} {video.views && {video.views} views}
); } // ── Video modal ──────────────────────────────────────────────────────────────── function VideoModal({ video, onClose }) { useEffect(() => { const handler = (e) => { if (e.key === 'Escape') onClose(); }; document.addEventListener('keydown', handler); document.body.style.overflow = 'hidden'; return () => { document.removeEventListener('keydown', handler); document.body.style.overflow = ''; }; }, [onClose]); if (!video) return null; return (
e.stopPropagation()}>
{video.category && }

{video.title}

{video.date &&

{new Date(video.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })}

} {video.description &&

{video.description.slice(0, 300)}{video.description.length > 300 ? '…' : ''}

} Watch on YouTube ↗
); } // ── Section divider ────────────────────────────────────────────────────────── function RedLine() { return
; } Object.assign(window, { Nav, Footer, VideoCard, VideoModal, CategoryBadge, RedLine, SocialLinks, useRoute, useScrollReveal });