// ============================================ // HERO — 3D parallax dashboard + QR scan + isometric scene + magnetic cursor // ============================================ const { useState, useEffect, useRef } = React; function MagneticCursor() { const dotRef = useRef(null); const ringRef = useRef(null); const particlesRef = useRef([]); useEffect(() => { if (window.innerWidth < 900) return; let mx = window.innerWidth / 2, my = window.innerHeight / 2; let rx = mx, ry = my; let dx = mx, dy = my; const move = (e) => { mx = e.clientX; my = e.clientY; if (dotRef.current) { dotRef.current.style.transform = `translate(${mx - 3}px, ${my - 3}px)`; } // spawn particle occasionally if (Math.random() > 0.85) { spawnParticle(mx, my); } }; const tick = () => { rx += (mx - rx) * 0.15; ry += (my - ry) * 0.15; if (ringRef.current) { ringRef.current.style.transform = `translate(${rx - 16}px, ${ry - 16}px)`; } requestAnimationFrame(tick); }; tick(); const onEnter = () => ringRef.current?.classList.add('hover'); const onLeave = () => ringRef.current?.classList.remove('hover'); window.addEventListener('mousemove', move); document.querySelectorAll('a, button, .hover-target').forEach(el => { el.addEventListener('mouseenter', onEnter); el.addEventListener('mouseleave', onLeave); }); return () => window.removeEventListener('mousemove', move); }, []); const spawnParticle = (x, y) => { const p = document.createElement('div'); p.className = 'cursor-particle'; p.style.cssText = `position:fixed;left:${x}px;top:${y}px;width:3px;height:3px;background:var(--cyan);border-radius:50%;pointer-events:none;z-index:9998;box-shadow:0 0 6px var(--cyan);transition:transform 0.8s ease-out,opacity 0.8s;`; document.body.appendChild(p); requestAnimationFrame(() => { const dx = (Math.random() - 0.5) * 40; const dy = (Math.random() - 0.5) * 40; p.style.transform = `translate(${dx}px, ${dy}px) scale(0)`; p.style.opacity = '0'; }); setTimeout(() => p.remove(), 800); }; return ( <>
); } function Hero() { const [tilt, setTilt] = useState({ x: 0, y: 0 }); const [scanPos, setScanPos] = useState(0); const [qrRevealed, setQrRevealed] = useState(false); const [screenIdx, setScreenIdx] = useState(0); const [kpi, setKpi] = useState({ total: 248, value: 4.2, maint: 12, alerts: 5 }); const heroRef = useRef(null); // Mouse parallax for dashboard useEffect(() => { const el = heroRef.current; if (!el) return; const move = (e) => { const r = el.getBoundingClientRect(); const px = (e.clientX - r.left) / r.width - 0.5; const py = (e.clientY - r.top) / r.height - 0.5; setTilt({ x: px * 10, y: -py * 10 }); }; el.addEventListener('mousemove', move); return () => el.removeEventListener('mousemove', move); }, []); // QR scan loop useEffect(() => { let t = 0; const id = setInterval(() => { t += 2; setScanPos(t % 110); if (t % 110 > 95 && !qrRevealed) setQrRevealed(true); if (t % 110 < 5) setQrRevealed(false); }, 40); return () => clearInterval(id); }, [qrRevealed]); // Screen cycling useEffect(() => { const id = setInterval(() => setScreenIdx(i => (i + 1) % 3), 3200); return () => clearInterval(id); }, []); // Live KPI ticker useEffect(() => { const id = setInterval(() => { setKpi(k => ({ total: k.total + (Math.random() > 0.55 ? 1 : 0), value: +(k.value + (Math.random() - 0.45) * 0.05).toFixed(2), maint: Math.max(4, Math.min(18, k.maint + (Math.random() > 0.5 ? 1 : -1))), alerts: Math.max(0, Math.min(9, k.alerts + (Math.random() > 0.65 ? 1 : -1))), })); }, 1800); return () => clearInterval(id); }, []); return (
{/* Hero-local ambience */}
{/* LEFT: Copy */}
SAAS · COLOMBIA · v4.2

Gestión total de
activos fijos
en tiempo real

Controla inventarios, deprecia automáticamente y gestiona mantenimientos y consumibles desde una sola plataforma. Hecho para empresas que necesitan orden, trazabilidad y reportes en segundos.

Solicitar demo Ver el sistema
{/* Trust row */}
16+
Modulos
180K+
activos
99.9%
uptime
{/* RIGHT: 3D parallax dashboard stage */}
{/* HUD crosshair */} {/* Main dashboard card */}
Dashboard Activos Depreciación
{screenIdx === 0 && (
Total Activos
{kpi.total}
↑ +3 hoy
Valor libros
${kpi.value.toFixed(1)}B
COP
En mant.
{kpi.maint}
activos
Alertas
{kpi.alerts}
pendientes
Depreciación · últimos 12 meses
)} {screenIdx === 1 && (
{[ { id: 'ACT-2021-048', name: 'Servidor Dell R-740', loc: 'Data Center', val: '$380M', state: 'activo' }, { id: 'ACT-2022-012', name: 'Planta Eléctrica 250kVA', loc: 'Sede Principal', val: '$1.2B', state: 'alquilado' }, { id: 'ACT-2020-033', name: 'Montacargas Toyota', loc: 'Bodega Norte', val: '$220M', state: 'mant' }, { id: 'ACT-2023-007', name: 'Compresor Atlas', loc: 'Taller', val: '$45M', state: 'activo' }, { id: 'ACT-2024-091', name: 'Impresora HP LaserJet', loc: 'Oficina 3', val: '$18M', state: 'activo' }, ].map((a, i) => (
{a.id}
{a.name}{a.loc}
{a.val}
))}
)} {screenIdx === 2 && (
Depreciación por método
{[ { lab: 'Línea Recta', h: 85, c: 'var(--cyan)' }, { lab: 'Saldo Dec.', h: 68, c: 'var(--violet)' }, { lab: 'Suma Dígitos', h: 52, c: 'var(--lime)' }, { lab: 'Unidades Prod.', h: 40, c: 'var(--amber)' }, { lab: 'No dep.', h: 15, c: 'var(--magenta)' }, ].map((b, i) => (
{b.lab}
))}
Total dep. anual $148.2M COP
)}
{/* Floating QR scan card */}
QR·SCAN
{qrRevealed ? (
ACT-2021-048
Servidor Dell R-740
● Activo · Sede Principal
) : (
Escaneando…
Identificando activo
)}
{/* Floating isometric site card */}
{/* Floating status chips */}
Valor
$4.23B
Próximo mant.
3 días
{/* Bottom ticker */}
{[ '◆ DEPRECIACIÓN AUTOMÁTICA', '◆ MANTENIMIENTOS', '◆ CÓDIGOS QR', '◆ CONSUMIBLES', '◆ CARGA MASIVA EXCEL', '◆ REPORTES PDF', '◆ ALERTAS TIEMPO REAL', '◆ MULTI-EMPRESA', '◆ DEPRECIACIÓN AUTOMÁTICA', '◆ MANTENIMIENTOS', '◆ CÓDIGOS QR', '◆ CONSUMIBLES', '◆ CARGA MASIVA EXCEL', '◆ REPORTES PDF', '◆ ALERTAS TIEMPO REAL', '◆ MULTI-EMPRESA', ].map((t, i) => {t})}
); } // ----- Hero helper components ----- function QRPattern() { // Deterministic QR-like pattern const cells = []; const size = 13; const seed = [ '1111111001111111', '1000001010100001', '1011101011011101', '1011101001011101', '1011101011011101', '1000001010100001', '1111111010111111', '0000000011000000', '1001011110110011', '1110010001001101', '0101110011110010', '1011001100011011', '1111111010011011', ]; return ( {seed.map((row, y) => [...row].slice(0, size).map((c, x) => c === '1' ? : null ) )} ); } function LiveSparkline() { const [points, setPoints] = useState(() => Array.from({length: 32}, (_, i) => 30 + Math.sin(i*0.4)*12 + Math.random()*10)); useEffect(() => { const id = setInterval(() => { setPoints(p => { const next = [...p.slice(1)]; const last = p[p.length-1]; next.push(Math.max(10, Math.min(60, last + (Math.random()-0.48)*8))); return next; }); }, 900); return () => clearInterval(id); }, []); const W = 280, H = 70; const stepX = W / (points.length-1); const path = points.map((y,i) => `${i===0?'M':'L'} ${i*stepX} ${H-y}`).join(' '); const fill = `${path} L ${W} ${H} L 0 ${H} Z`; return ( {points.map((y,i) => i === points.length-1 && ( ))} ); } function IsoSite() { // Isometric scene: fixed-asset office inventory — server rack, monitor+CPU, printer, QR-tagged asset return ( {/* Isometric grid floor */} {[-2,-1,0,1,2,3,4,5].map(i => ( ))} {[0,1,2,3,4,5,6,7,8].map(i => ( ))} {/* Server rack (left) — tall, cyan */} {/* top */} {/* left face */} {/* right face */} {/* rack units — blinking LEDs */} {[0,1,2,3,4].map(i => ( ))} {/* QR tag on rack */} {/* Desk with monitor + CPU (center) */} {/* desk top */} {/* desk leg */} {/* monitor base */} {/* monitor screen — left face */} {/* scan-line on screen */} {/* CPU tower on desk */} {/* Printer (right foreground) */} {/* paper tray */} {/* ejected sheet */} {/* Floating asset tag with ID (top right) */} {/* QR */} ACT-048 Servidor R-740 {/* Geolocation ping on desk area */} ); } window.Hero = Hero; window.MagneticCursor = MagneticCursor;