/* 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 ( {/* notebook */} {/* code-like lines */} {/* perf gauge */} PERFORMANCE + 64% {/* hinge */} ); } 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 ( {/* central router */} {/* lines */} {nodes.map((n,i) => ( ))} {/* animated pulse on a couple */} {nodes.map((n,i) => ( ))} CORE ); } function ServerVisual() { return ( {Array.from({length:6}).map((_,i) => ( DISK-{String.fromCharCode(65+i)} {['64TB','32TB','16TB','64TB','32TB','64TB'][i]} ))} {/* backup arrows */} backup cloud ); } function SupportVisual() { return ( {/* chat window */} {/* messages */} {/* typing indicator */} ); } /* 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;