Files
Jesse EgbosionuandClaude Opus 5.5 3bb0a5e4a9 feat: redesign site as a modern developer portfolio
- New home page: hero, stats, about, focus areas, stack, projects, contact
- Light/dark theme with system default and persisted toggle
- Content centralised in data/profile.js
- Restyle /rates to match; remove it from nav and projects
- Afriex: log a clear error now that its API requires a device id

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 21:19:22 +02:00

38 lines
962 B
JavaScript

import { useEffect, useRef, useState } from 'react';
// Fades children in when they scroll into view.
export default function Reveal({ as: Tag = 'div', delay = 0, className = '', children, ...rest }) {
const ref = useRef(null);
const [visible, setVisible] = useState(false);
useEffect(() => {
const node = ref.current;
if (!node || typeof IntersectionObserver === 'undefined') {
setVisible(true);
return;
}
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setVisible(true);
observer.disconnect();
}
},
{ rootMargin: '0px 0px -10% 0px' }
);
observer.observe(node);
return () => observer.disconnect();
}, []);
return (
<Tag
ref={ref}
className={`reveal ${visible ? 'is-visible' : ''} ${className}`}
style={{ transitionDelay: `${delay}ms` }}
{...rest}
>
{children}
</Tag>
);
}