Hace unas semanas, mientras investigaba la estética de las agencias de automatización con IA más serias del mundo, di con n8nlab.io. Se ve increíble: tipografía custom, partículas violetas que respiran de fondo, iconos flotando con profundidad, glassmorphism sutil. Lo típico que hace pensar "esto lo hizo un equipo de 6 personas con un retainer de Apple".
Le hice ingeniería inversa al sitio (HTML, headers, bundle CSS, scripts) con un objetivo concreto: ¿qué stack y qué librerías necesito para tener algo así en mi agencia, siendo solo-founder con presupuesto cero?
La respuesta corta: mucho menos de lo que parece.
El stack real, verificado
Mirando los headers, los chunks que carga el bundle y los nombres de clase del CSS, lo que están usando es:
| Capa | Tecnología |
|---|---|
| Framework | Next.js 14 + Turbopack |
| Hosting | Firebase App Hosting tras Cloudflare CDN |
| UI | Tailwind + shadcn/ui (paleta HSL custom violeta + coral) |
| Iconos | lucide-react (gratis, mismo set que el del sitio que estás leyendo) |
| Fuentes | Inter, Space Grotesk, Source Code Pro vía next/font |
| CRM / forms | GoHighLevel detrás del botón "Get Free Audit" |
| Booking | Cal.com + TidyCal |
| Chat | Intercom |
Lo que no usan es lo más interesante: cero GSAP, cero Three.js, cero Spline, cero Lottie.El bundle no carga ninguna de esas librerías pesadas.
El truco del efecto "partículas flotantes"
Cuando ves el hero, parece animación 3D. La realidad: es un <canvas> fijo a pantalla completa con puntitos que rebotan + cinco keyframes CSS de Tailwind para los iconos que flotan arriba.
El componente esencial son ~70 líneas de JavaScript vanilla:
function ParticleCanvas() {
const canvasRef = useRef(null);
const rafRef = useRef(0);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
let w, h, dpr;
const particles = [];
const resize = () => {
dpr = Math.min(window.devicePixelRatio || 1, 2);
w = canvas.clientWidth; h = canvas.clientHeight;
canvas.width = w * dpr; canvas.height = h * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
};
resize();
for (let i = 0; i < 70; i++) {
particles.push({
x: Math.random() * w, y: Math.random() * h,
vx: (Math.random() - 0.5) * 0.25,
vy: (Math.random() - 0.5) * 0.25,
r: Math.random() * 1.4 + 0.6,
a: Math.random() * 0.5 + 0.2,
});
}
const loop = () => {
ctx.clearRect(0, 0, w, h);
for (let i = 0; i < particles.length; i++) {
const p = particles[i];
p.x += p.vx; p.y += p.vy;
if (p.x < 0 || p.x > w) p.vx *= -1;
if (p.y < 0 || p.y > h) p.vy *= -1;
for (let j = i + 1; j < particles.length; j++) {
const q = particles[j];
const d = Math.hypot(p.x - q.x, p.y - q.y);
if (d < 130) {
ctx.strokeStyle = `hsla(262, 83%, 70%, ${(1 - d/130) * 0.18})`;
ctx.beginPath();
ctx.moveTo(p.x, p.y); ctx.lineTo(q.x, q.y);
ctx.stroke();
}
}
ctx.fillStyle = `hsla(262, 83%, 75%, ${p.a})`;
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
ctx.fill();
}
rafRef.current = requestAnimationFrame(loop);
};
loop();
return () => cancelAnimationFrame(rafRef.current);
}, []);
return <canvas ref={canvasRef} style={{ position:'absolute', inset:0 }} />;
}Y para los iconos que "respiran" arriba del canvas, una sola animación CSS:
@keyframes float {
0%, 100% { transform: translateY(0) rotate(var(--r, 0deg)); }
50% { transform: translateY(-14px) rotate(var(--r, 0deg)); }
}Cada icono recibe un animation-delay diferente para que no respiren todos al mismo tiempo. Listo. Eso es todo el efecto.
Por qué te importa
La lección no es técnica, es de posicionamiento: el wow-factor de las landings que crees imposibles de replicar suele estar en la composición, no en el stack. Mucha gente que conozco está pagando $5,000 a una agencia que "hace animaciones 3D" cuando lo que necesitan es exactamente esto: 70 líneas de canvas + buen contraste de color + tipografía decente.
Si la única ventaja competitiva de tu landing es la animación, perdiste. Si la animación apoya un mensaje claro, ganaste — sin importar si lo hiciste con GSAP o con un canvas de 1 KB.
Lo que adopté para automatiza.ia
Esta misma web que estás leyendo usa el mismo enfoque:
- Stack: Next.js 14 App Router + React 18 (igual).
- Estilos: paleta HSL custom (violet
#7c3aed+ coral#ff6b5b), sin Tailwind para v1, en CSS vars. - Hero: el mismo canvas vanilla + 6 iconos flotantes con la animación
floatde arriba. - Cero dependencias UI extra. Cero ads de librerías 3D.
Resultado: una landing que carga en menos de 100 KB de JavaScript, ranquea bien en Core Web Vitals, y se ve comparable a sitios de agencias internacionales que cobran 50× lo que yo voy a cobrar.
Si quieres copiar esto en tu negocio
Hay dos rutas. Ruta A: contrátame para que te lo monte en 14 días o menos, con tu copy y tu funnel. Ruta B: toma el código de arriba y ármalo tú mismo — está completo, no falta nada.
La Ruta B es legítima y la respaldo. Si eliges la A, agenda un diagnóstico gratis de 15 minutos:
Agendar diagnóstico gratis (15 min)
Si quieres ver el reporte forense completo (15 fuentes, headers HTTP, CSS bundle, alternativas de stack evaluadas), está disponible en el repo interno de la agencia. Pídemelo y te lo paso.