FrontLaxWeb
Convierte una landing en una web-experiencia: parallax, scroll interactivo y gestos premium, siempre a 60fps.
Cuándo se usa
Al montar un hero, el storytelling de un producto o cualquier web que deba sentirse como un vídeo que el usuario dirige con el scroll, el ratón o el dedo.
SKILL.md
# FrontLaxWeb — parallax y scroll interactivo premium
Convierte una landing normal en una web-experiencia: el scroll y el puntero se vuelven el mando de
una animación continua. Marca-agnóstico: recibe los colores y tokens de cada proyecto. Es la versión
pro de la skill "Animar con el scroll"; si solo quieres apariciones sencillas y seguras, esa basta.
## Lo primero, siempre: el cuestionario de arranque (OBLIGATORIO)
No empieces a construir en frío. Antes de tocar una línea, hazle al usuario este cuestionario y
devuélvele un brief que apruebe. Construir sin contexto es exactamente como sale el diseño genérico.
Si dice "hazlo ya" o "tú decides", pásale al menos las tres primeras. Se hace una vez por proyecto.
1. **El producto en una frase.** ¿Qué es y qué hace? ¿Cuál es la UNA acción que quieres del visitante
(comprar, registrarse, leer, contactar)?
2. **Para quién y en qué nicho.** ¿Quién la va a ver? ¿Sector? (fintech, moda, SaaS, portfolio, evento).
3. **El tono, en dos ejes.** ¿Más funcional (confianza, sobrio) o más expresivo (impacto, marca)?
¿Vende rápido, capta un lead, o cuenta una historia?
4. **La marca.** Tres adjetivos que quieras transmitir. Colores y tipografía si ya los tienes.
5. **Tu gusto.** Abre vibeset.dev/components y vibeset.dev/concepts y di 2 o 3 efectos o conceptos que
te gusten, y por qué. Pega 1 o 2 webs que te vuelen la cabeza. Sin gusto de referencia salen tokens
genéricos, y las referencias las pone el usuario, no el diseñador.
6. **Lo práctico.** ¿React o HTML/CSS/JS puro? ¿Restricciones (rendimiento estricto, público sensible
al movimiento, plazo)?
Con las respuestas, entrega un **brief** y apruébalo antes de construir: arquetipo e intensidad,
dirección de tokens (marcada "a validar" si no hay referencias, sin inventar), 1 o 2 efectos del
catálogo, componentes sugeridos y las tres paradas del dial.
## Los 7 efectos (el catálogo)
1. Smooth scroll (cimiento) — Lenis. La base de que todo se sienta premium.
2. Parallax de capas — fondos lentos, frente rápido: profundidad.
3. Scroll-linked animation — propiedades atadas al porcentaje de scroll.
4. Scroll-reveal — entrar o animar al aparecer en el viewport.
5. Sticky / pin — algo se pega mientras cambia lo de alrededor (stacking cards).
6. Micro-interacciones de puntero — tilt 3D, cursor con lerp, hover magnético.
7. Gestos con springs — arrastrar, soltar, tap: física de resorte interrumpible en vez de
transiciones CSS de duración fija. Destilado de los principios de motion de las WWDC de Apple
recopilados por Emil Kowalski (github.com/emilkowalski/skills).
## Cimientos no negociables (rendimiento)
- Anima SOLO transform y opacity: van por GPU. Nunca top, left, width, height ni margin.
- Apariciones con IntersectionObserver, nunca con un listener de scroll suelto.
- Si necesitas la posición exacta del scroll, léela dentro de requestAnimationFrame, no en el evento.
- Listeners con { passive: true }.
- Cinturón de seguridad: nunca dejes contenido invisible a merced de un observer o de rAF. En una
pestaña en segundo plano no disparan. Tras load, un setTimeout de rescate revela lo que ya esté visible.
## El dial --motion-gain (la política de movimiento)
Lo estándar es apagar el movimiento cuando el sistema pide prefers-reduced-motion. FrontLaxWeb ofrece
otra vía: en vez de apagar, baja la AMPLITUD. Un solo dial gobierna la web entera.
- Por defecto: gain 1 — la experiencia completa.
- Sistema en reduce: gain 0.25 — el mismo diseño con un cuarto de recorrido, acento y no cámara.
- URL con ?motion=off: gain 0 — se queda quieto lo que se movía solo.
- URL con ?motion=full: fuerza 1, ignorando la preferencia del sistema.
Las tres reglas del dial:
1. gain multiplica el RECORRIDO: píxeles, escala, rotación, skew. En efectos continuos multiplica la velocidad.
2. gain NUNCA multiplica la opacidad. Un fundido no marea, así que se ve siempre; por eso, con gain 0,
un efecto no se rompe: degrada a un fundido en vez de a un hueco vacío.
3. gain NO escala el movimiento que dirige el usuario (arrastrar, hover, tilt, cursor). Escala solo el
no solicitado: parallax, zoom al scroll, scrubbing, horizontal, velocity skew.
Interruptor central, en el head, antes de cualquier CSS de animación:
<script>
(function () {
var h = document.documentElement;
var q = new URLSearchParams(location.search).get('motion');
var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
var gain = q === 'off' ? 0 : q === 'full' ? 1 : reduce ? 0.25 : 1;
h.style.setProperty('--motion-gain', String(gain));
h.classList.toggle('motion', gain > 0);
})();
</script>
**Accesibilidad, con rigor (WCAG, MDN, web.dev).** Esta política es opinada y solo se sostiene si:
- Existe la **válvula** de apagado. WCAG 2.3.3 (nivel AAA) exige poder DESACTIVAR el movimiento, no
solo reducirlo; ?motion=off es ese mecanismo, y debe estar siempre y ser descubrible. Sin ella, no
cumples la norma.
- Bajo reduce, el 0.25 es un PUNTO DE PARTIDA. Lo que marea es el movimiento de gran amplitud
(parallax, zoom, translación de gran superficie), no la opacidad. Ese movimiento grande hay que
llevarlo a ~cero o sustituirlo por un fundido, no dejarlo "más pequeño pero presente". Para un reveal
de 16 px, 0.25 sobra; para un parallax de 300 px, sigue mareando: baja más o pásalo a opacidad.
- **WCAG 2.2.2 "Pause, Stop, Hide" (nivel A, obligatorio):** todo bucle automático de más de 5 s
(marquee, vídeo de fondo, gradiente en movimiento) DEBE tener un control de pausa o stop. El dial no
lo sustituye.
Si el público es sensible o el sitio es funcional (banca, salud, formularios, checkout), usa el apagado
estándar de "Animar con el scroll".
## Cuándo SÍ y cuándo NO
- SÍ: hero de producto, storytelling de features, "cómo funciona", secciones largas de scroll.
- NO: formularios, dashboards densos, tablas, checkout, páginas legales, o si baja el LCP, el INP o el CLS.
(Umbrales buenos p75, verificados 2026: LCP < 2,5 s, INP < 200 ms, CLS < 0,1.)
- Regla de oro: el efecto sirve al mensaje, no al revés. Si distrae o marea, sobra.
## El contexto manda (paso 0) y la matriz por arquetipo
Sitúa la web en dos ejes antes de elegir un solo efecto: funcional contra expresivo, y conversión
contra narrativa. El arquetipo cae de ahí, y decide el resto.
- SaaS / B2B — baja-media. SÍ reveal con stagger, sticky demo, contadores, micro hover. NO scrolljacking
ni WebGL pesado. Referentes: Linear, Vercel.
- Fintech / salud — baja. SÍ fade y slide sutil, jerarquía tipográfica. NO parallax profundo ni scrolljacking.
- E-commerce / producto físico — media. SÍ sticky con scrubbing del producto, zoom al scroll. NO hijack en checkout.
- Marca creativa / moda / agencia — alta. SÍ WebGL, horizontal, tipografía cinética, cursor con lerp.
NO lo genérico y tímido. Referentes: Obys, Lusion.
- Portfolio — media-alta. SÍ máscaras, hover magnético, WebGL si eres dev.
- Editorial / medio — media. SÍ scrollytelling, parallax narrativo. NO hijacking.
- Landing de lanzamiento — media-alta. SÍ hero parallax, marquee, countdown. NO preloaders largos.
## Transiciones entre páginas: View Transitions API (nativo)
El paso de una página a otra ya es nativo, antes que Barba.js o AnimatePresence.
- Same-document (SPA): document.startViewTransition(() => actualizarDOM()). Ya es Baseline (~90%).
- Multipágina (MPA): dos líneas de CSS y cero JS:
@view-transition { navigation: auto; }
.hero { view-transition-name: hero; }
Cubre ~85% (Chrome/Edge 126, Safari 18.2). Firefox aún no la hace, pero degrada solo a navegación
normal. Por eso: nunca la uses como única señal de un cambio de estado, y exige mismo origen.
## El kitchen sink: de un nicho a una web entera
1. Contexto: el cuestionario de arranque de arriba. De él sale el arquetipo y el brief.
2. Tokens de diseño estático: tipografía, escala de color, espaciado. La capa más fácil de descuidar y
la más notoria; hazla a conciencia, apoyada en las referencias del usuario.
3. Componentes: elige las piezas que fijan el arquetipo, no las más vistosas.
4. Movimiento: uno o dos efectos del catálogo, con el dial de serie.
5. Cierre: prueba las tres paradas del dial y mide los Core Web Vitals.
Cada capa la manda la de arriba. Elegir primero un efecto chulo y buscarle un sitio es el error que la
matriz existe para frenar.
## Motores por stack (verificado 2026)
- React: Motion (el antiguo Framer Motion; paquete motion, import motion/react, v13; con LazyMotion y el
componente m el arranque baja a ~4,6 kB) más Lenis (paquete lenis, componente ReactLenis). Añade GSAP
con ScrollTrigger solo para scrubbing, pin o SplitText. Al sincronizar Lenis con el ticker de GSAP,
arranca Lenis con autoRaf: false, o corres dos bucles de rAF a la vez (el fallo típico).
- Vanilla: para reveals y parallax, CSS scroll-driven (animation-timeline: view()/scroll()) es 0 KB pero
es mejora progresiva, NO base: Firefox estable aún no lo trae (~85%). El estado base debe ser el
visible y el efecto va encima con @supports (animation-timeline: view()); si el base es opacity: 0, el
usuario de Firefox no ve nada. Para scrubbing, pin u horizontal: GSAP con ScrollTrigger, más Lenis.
- GSAP es 100% gratis desde 2025 (compra por Webflow): SplitText, MorphSVG y ScrollSmoother incluidos.
- WebGL (Three.js o React Three Fiber): solo si la marca ES la experiencia; opt-in con chequeo de capacidad.
Al terminar, di qué se anima, con qué está hecho y qué pasa en las tres paradas del dial.