/* Visual components: abstract tech imagery — servers, networks, dashboards */
const { useEffect, useRef, useState } = React;
/* Reveal-on-scroll hook */
function useReveal() {
useEffect(() => {
const els = document.querySelectorAll('.reveal');
if (!('IntersectionObserver' in window)) {
els.forEach(e => e.classList.add('in'));
return;
}
const io = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('in');
io.unobserve(e.target);
}
});
}, { rootMargin: '0px 0px -80px 0px', threshold: 0.05 });
els.forEach(el => io.observe(el));
return () => io.disconnect();
}, []);
}
/* Mild parallax driver */
function useParallax() {
useEffect(() => {
let ticking = false;
const items = Array.from(document.querySelectorAll('[data-parallax]'));
const onScroll = () => {
if (ticking) return;
ticking = true;
requestAnimationFrame(() => {
const vh = window.innerHeight;
items.forEach(el => {
const rect = el.getBoundingClientRect();
const speed = parseFloat(el.dataset.parallax || '0.08');
const center = rect.top + rect.height / 2;
const delta = (center - vh / 2) * speed;
el.style.transform = `translate3d(0, ${(-delta).toFixed(1)}px, 0)`;
});
ticking = false;
});
};
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
return () => window.removeEventListener('scroll', onScroll);
}, []);
}
/* ───── Hero composition: a "rack + dashboard" abstract scene ───── */
function HeroComposition() {
return (
);
}
/* Small reusable visuals for detalhe blocks */
function ComputerVisual() {
return (
);
}
function NetworkVisual() {
const nodes = [
{x:80, y:80}, {x:200, y:60}, {x:320, y:90},
{x:60, y:180}, {x:200, y:150}, {x:340, y:180},
{x:120, y:250}, {x:280, y:240}
];
return (
);
}
function ServerVisual() {
return (
);
}
function SupportVisual() {
return (
);
}
/* small icons used in svc grid / dif grid */
function Icon({ name, size = 18 }) {
const s = size;
const stroke = "currentColor";
const sw = 1.6;
const common = { width: s, height: s, viewBox: "0 0 24 24", fill: "none", stroke, strokeWidth: sw, strokeLinecap: "round", strokeLinejoin: "round" };
switch (name) {
case 'monitor': return ;
case 'laptop': return ;
case 'cloud': return ;
case 'wifi': return ;
case 'server': return ;
case 'printer': return ;
case 'shield': return ;
case 'cog': return ;
case 'database':return ;
case 'lifebuoy':return ;
case 'route': return ;
case 'check': return ;
case 'compass': return ;
case 'arrow': return ;
case 'plus': return ;
case 'pin': return ;
case 'sparkle': return ;
case 'lock': return ;
case 'whats': return ;
default: return null;
}
}
window.HeroComposition = HeroComposition;
window.ComputerVisual = ComputerVisual;
window.NetworkVisual = NetworkVisual;
window.ServerVisual = ServerVisual;
window.SupportVisual = SupportVisual;
window.Icon = Icon;
window.useReveal = useReveal;
window.useParallax = useParallax;