← Volver a la página

Cómo se hizo

Quirófano — la línea que dibuja la página

La home de CyberSenseAI se construyó sobre una sola idea: salud es precisión que respira. Todo el sitio es un quirófano luminoso — blanco cálido, verde quirófano, azul pulso — recorrido de arriba abajo por un trazo de electrocardiograma que nace en el monitor del hero, baja serpenteando por las secciones, late una vez junto a cada titular y termina reposando, con su punto luminoso, sobre la llamada final. No hay ni una sola imagen: todo es SVG y canvas procedural en un único archivo HTML.

1 · La forma de onda: P-QRS-T como suma de gaussianas

En vez de trocear un dibujo, la onda cardiaca es una función continua: cinco campanas de Gauss — onda P, complejo QRS (Q, R, S) y onda T — sumadas sobre una fase normalizada. La misma función alimenta el monitor del hero, las cuatro mini-ondas del panel de métricas y el ritmo general de la página.

// p ∈ [0,1) → desplazamiento vertical (negativo = arriba)
function gauss(p,c,w,a){var d=(p-c)/w;return a*Math.exp(-d*d/2)}
function ecg(p){
  return gauss(p,.16,.022,-7)   // onda P
       + gauss(p,.235,.008,6)   // Q
       + gauss(p,.25,.011,-46)  // R
       + gauss(p,.268,.009,13)  // S
       + gauss(p,.45,.05,-11);  // onda T
}

El monitor del hero es multiparamétrico, como uno real: al canal II del ECG (azul, a 54 ppm) le acompañan la pletismografía de SpO₂ (verde, sincronizada con el corazón con su retardo fisiológico) y la curva de respiración (12 rpm, casi imperceptible), cada una con su forma de onda, su amplitud y su etiqueta mono en el margen derecho. La carga está orquestada sobre ese ritmo: las tres líneas entran planas (isoeléctricas), a los 900 ms llega el primer latido real — y es ese latido el que despierta la página — y después los canales se conectan uno a uno (SpO₂ a los 1,6 s, respiración a los 2,1 s). Titular, entradilla y botones se revelan en escalera; el punto del logotipo y el CTA principal pulsan en sincronía con cada latido mientras el hero está a la vista, y la palabra respira respira de verdad, en el mismo ciclo de 9 s que el fondo.

2 · La línea vital: un path que se construye leyendo el DOM

La columna vertebral del sitio no está dibujada a mano: se calcula en tiempo de ejecución. Cada sección coloca un marcador invisible (.pulse-node) donde quiere recibir su latido. Un script recoge esos puntos, los ordena por altura y teje entre ellos curvas Bézier verticales; al llegar a cada nodo inserta el glifo P-QRS-T como segmento relativo del propio path:

function beatGlyph(x,y,mobile){
  var s = mobile? .55 : 1;
  var seg=function(dx,dy){return ' l '+(dx*s)+' '+(dy*s)};
  var d=' L '+x+' '+y;
  d+=seg(12,0);
  d+=' q '+(5*s)+' '+(-9*s)+' '+(10*s)+' 0';   // onda P
  d+=seg(7,0);
  d+=seg(4,7)+seg(7,-46)+seg(7,56)+seg(5,-17); // QRS
  d+=seg(8,0);
  d+=' q '+(7*s)+' '+(-13*s)+' '+(14*s)+' 0';  // onda T
  return d+seg(12,0);
}

Al redimensionar, el path entero se reconstruye: en escritorio la línea zigzaguea de un margen a otro (92 % → 7 % → 92 %…); por debajo de 900 px se pliega a una columna de 12 px junto al borde con glifos compactos. Los nodos viven en los márgenes reales y dentro del colchón de padding superior de cada sección: el latido cae junto al titular, nunca encima del texto. El trazo se pinta con un gradiente userSpaceOnUse cuyas paradas también se calculan: verde quirófano en campo abierto, menta al cruzar la sección oscura de XAIOS y azul pulso en el tramo final.

3 · Dibujado por scroll con muestreo y→longitud

El clásico stroke-dasharray revela la línea, pero la longitud del path no es lineal respecto a la altura (los latidos añaden recorrido). Para que el frente del trazo coincida siempre con la línea de lectura del viewport, el path se muestrea una vez (420 puntos longitud→coordenada) y en cada frame se busca la longitud cuya y alcanza el 72 % del viewport, con interpolación para que el avance respire:

var readLine = scrollY + innerHeight*0.72;
target  = lenAtY(readLine);          // lookup en las muestras
current += (target-current)*0.09;    // lerp: el trazo respira
trace.style.strokeDashoffset = L - current;
var p = trace.getPointAtLength(current);
dot.setAttribute('cx',p.x); dot.setAttribute('cy',p.y);

El punto azul que corona el frente del trazo es la «cabeza» del electrocardiógrafo: acompaña el scroll todo el viaje y se queda encendido al final, reposando sobre «Tu próximo fichaje ya tiene pulso».

4 · Iconos que se dibujan: el truco pathLength="1"

Todos los iconos (verticales, escudo XAIOS, sellos ENS/ISO/GDPR, checks de la checklist, el equipo híbrido y el retrato de SoulBot) son SVG de un solo trazo que se dibujan al entrar en pantalla. Sin medir nada en JS: declarando pathLength="1", cualquier path se normaliza y basta CSS puro con retardos en cascada:

.draw path{stroke-dasharray:1;stroke-dashoffset:1;
  transition:stroke-dashoffset 1.7s cubic-bezier(.4,0,.2,1);
  transition-delay:var(--d,0s)}
.draw.in path{stroke-dashoffset:0}

Un único IntersectionObserver gestiona reveals, dibujos y contadores (los números del panel — 40 %, 10×, 24/7, 171 % — cuentan con easing cúbico al entrar).

5 · Lenguaje visual

#faf6ef · hueso
#122420 · tinta
#0f7a5c · verde quirófano
#07352b · sala honda
#7fd9bb · menta
#1f6df2 · azul pulso
VozFuentePapel
DisplayInstrument Serif (+ itálica)Titulares finos y humanistas; la itálica verde marca la palabra clínica («respira», «quirófano», «pulso»)
TextoInstrument SansCuerpo humanista, legible para un comprador enterprise
InstrumentalFragment MonoKickers, constantes, fichas y sellos: la voz del monitor

La metáfora se sostiene en el copy sin volverse circo: XAIOS es «el quirófano de tus datos» (aislamiento, gobernanza, soberanía), SoulBot llega con «ficha de incorporación» y constantes estables, los valores CREI son un «protocolo» — cada valor firma con su propio mini-trazado de ECG que se dibuja al entrar — y los 8 criterios enterprise, una «checklist preoperatoria» con el instrumental contado dos veces. Atmósfera: gradientes radiales que respiran (ciclo de 9 s en el hero), retícula de campo quirúrgico enmascarada, grano de gasa por feTurbulence, y cartas ligeramente rotadas (ficha −1,1°, equipo +1,2°) sobre un grid roto en las verticales.

6 · Rendimiento y respeto

7 · Decisiones que importaron

  1. El latido como evento de carga. Descartamos el fade-in genérico: la página literalmente no despierta hasta que el monitor late. Con tres redes de seguridad (temporizador, load, primer scroll) para que nadie espere ante una pantalla vacía.
  2. Path calculado, no dibujado. Hacer que la línea lea el DOM permite que sobreviva a cualquier reflow, idioma o viewport — y que el latido caiga siempre exactamente junto al titular de su sección.
  3. Final con destino. La primera versión prolongaba la línea hasta el footer atravesando el CTA; ahora termina su último latido y el punto se queda quieto encima del cierre: la línea te entrega, no te cruza.
  4. Espectáculo con credibilidad. Cada floritura sostiene un argumento de compra: las constantes son las cifras reales (40 % · 10× · 24/7 · 171 %), el campo estéril es la arquitectura de XAIOS y la checklist son los 8 criterios que firma un CTO/CISO/CIO.

8 · Segunda pasada: el peine fino

9 · Peine de púas finas

10 · Tercera pasada: la lupa final