// ============================================
// PIXELPULSE — Shared components
// ============================================
const { useState, useEffect, useRef, useCallback } = React;
// ===== Custom Cursor + Pixel Trail =====
function CustomCursor() {
const dotRef = useRef(null);
const ringRef = useRef(null);
const [trails, setTrails] = useState([]);
const lastSpawn = useRef(0);
useEffect(() => {
if (window.matchMedia('(max-width: 900px)').matches) return;
let mouseX = 0, mouseY = 0;
let ringX = 0, ringY = 0;
let raf;
const onMove = (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
if (dotRef.current) {
dotRef.current.style.transform = `translate(${mouseX - 2}px, ${mouseY - 2}px)`;
}
// Spawn trail pixels
const now = performance.now();
if (now - lastSpawn.current > 28) {
lastSpawn.current = now;
const id = now + Math.random();
const isOrange = Math.random() > 0.4;
setTrails((t) => [...t.slice(-10), { id, x: mouseX, y: mouseY, color: isOrange ? '#F78F1E' : '#0A1F44' }]);
setTimeout(() => {
setTrails((t) => t.filter((p) => p.id !== id));
}, 450);
}
};
const animate = () => {
// Higher lerp factor = ring snaps to cursor faster
ringX += (mouseX - ringX) * 0.42;
ringY += (mouseY - ringY) * 0.42;
if (ringRef.current) {
ringRef.current.style.transform = `translate(${ringX - 11}px, ${ringY - 11}px)`;
}
raf = requestAnimationFrame(animate);
};
animate();
const onOver = (e) => {
const tgt = e.target.closest('a, button, .service-card, .t-card, .career-row, input, textarea, .pulse-pill');
if (tgt) {
dotRef.current?.classList.add('hover');
ringRef.current?.classList.add('hover');
} else {
dotRef.current?.classList.remove('hover');
ringRef.current?.classList.remove('hover');
}
};
window.addEventListener('mousemove', onMove);
window.addEventListener('mouseover', onOver);
return () => {
window.removeEventListener('mousemove', onMove);
window.removeEventListener('mouseover', onOver);
cancelAnimationFrame(raf);
};
}, []);
return (
{trails.map((p, i) => (
))}
);
}
// ===== Loader =====
function Loader() {
const [done, setDone] = useState(false);
useEffect(() => {
const t = setTimeout(() => setDone(true), 2000);
return () => clearTimeout(t);
}, []);
return (
PIXELPULSE / INITIALIZING
);
}
// ===== Reveal-on-scroll wrapper =====
function Reveal({ children, delay = 0, className = '', as: Tag = 'div' }) {
const ref = useRef(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) {
setTimeout(() => el.classList.add('in'), delay);
io.unobserve(el);
}
});
}, { threshold: 0.15, rootMargin: '0px 0px -50px 0px' });
io.observe(el);
return () => io.disconnect();
}, [delay]);
return {children};
}
// ===== Animated counter =====
function Counter({ to, suffix = '', duration = 2000 }) {
const [n, setN] = useState(0);
const ref = useRef(null);
const started = useRef(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting && !started.current) {
started.current = true;
const start = performance.now();
const tick = (t) => {
const p = Math.min((t - start) / duration, 1);
const eased = 1 - Math.pow(1 - p, 3);
setN(Math.floor(eased * to));
if (p < 1) requestAnimationFrame(tick);
else setN(to);
};
requestAnimationFrame(tick);
}
});
}, { threshold: 0.5 });
io.observe(el);
return () => io.disconnect();
}, [to, duration]);
return (
{n}{suffix}
);
}
// ===== Nav =====
function Nav({ onLogoClick }) {
const [scrolled, setScrolled] = useState(false);
const [open, setOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 60);
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
const navBase = (typeof window !== 'undefined' && window.__navBase) || '';
const links = [
{ href: '#home', label: 'Home' },
{ href: '#services', label: 'Services' },
{ href: '#about', label: 'About' },
{ href: '#testimonials', label: 'Testimonials' },
{ href: '#careers', label: 'Careers' },
];
return (
);
}
// ===== Tilt 3D wrapper =====
function Tilt({ children, max = 8, className = '', ...rest }) {
const ref = useRef(null);
const onMove = (e) => {
const el = ref.current; if (!el) return;
const r = el.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width - 0.5;
const py = (e.clientY - r.top) / r.height - 0.5;
el.style.transform = `rotateY(${px * max}deg) rotateX(${-py * max}deg) translateY(-4px)`;
};
const onLeave = () => {
if (ref.current) ref.current.style.transform = '';
};
return (
{children}
);
}
Object.assign(window, { CustomCursor, Loader, Reveal, Counter, Nav, Tilt });