'use client'; import { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; function supportsScrollDrivenAnimations(): boolean { if (typeof CSS === 'undefined') return false; return CSS.supports?.('animation-timeline', 'scroll()') ?? false; } export function ReadingProgress() { const [mounted, setMounted] = useState(false); const [progress, setProgress] = useState(0); const [useScrollDriven, setUseScrollDriven] = useState(false); useEffect(() => { setMounted(true); const updateMode = () => { const prefersReducedMotion = window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches; setUseScrollDriven( supportsScrollDrivenAnimations() && !prefersReducedMotion ); }; updateMode(); const mq = window.matchMedia('(prefers-reduced-motion: reduce)'); mq.addEventListener('change', updateMode); return () => mq.removeEventListener('change', updateMode); }, []); useEffect(() => { if (!mounted || useScrollDriven) return; const handleScroll = () => { const { scrollTop, scrollHeight, clientHeight } = document.documentElement; const total = scrollHeight - clientHeight; if (total <= 0) { setProgress(0); return; } const value = Math.min(100, Math.max(0, (scrollTop / total) * 100)); setProgress(value); }; handleScroll(); window.addEventListener('scroll', handleScroll, { passive: true }); return () => window.removeEventListener('scroll', handleScroll); }, [mounted, useScrollDriven]); if (!mounted) return null; return createPortal(