Movimiento y animación: los límites que vigila markeup-motion
La skill markeup-motion define cómo se anima el sitio: transform, opacidad y clip-path por delante, cero propiedades de layout y pre-estados que evitan saltos al cargar la página.
Navegando en el blogver navegación en todos los blogs
La skill markeup-motion —«Anima con CSS y GSAP sin animar propiedades de layout»— es una de las
habilidades que el sistema MarkeUP tiene escritas para Hermes Agent y para Cline.
Esta página es su ficha pública: lo que sabe hacer, cuándo se usa y qué comandos ejecuta.
La animación se nota cuando falta y se sufre cuando abusa: la skill fija qué se puede mover y qué nunca.
El texto de la sección «Instrucciones del canon» está transcrito del fichero fuente —que se escribe sin tildes por convención de su propio gate—, así que es exactamente lo que lee el agente cuando le pides algo. La cabecera y esta entradilla sí están redactadas para leerlas.
| Dato | Valor |
|---|---|
| Skill | markeup-motion |
| Responsabilidad | Anima con CSS y GSAP sin animar propiedades de layout. |
| Versión | 1.0.0 |
| Autoría | uriszarernesto-blip · licencia MIT |
| Plataformas | linux · macos |
| Tags del canon | motion · gsap · css · animacion · accesibilidad · markeup |
| Skills relacionadas | markeup-content · markeup-cli · markeup-graphs |
| Fuente | ~/.hermes/skills/markeup/markeup-motion/SKILL.md |
Responsabilidad unica: la animacion del sitio (CSS primero + GSAP para coreografiar) y sus dos gates.
Detalle y mediciones: docs/motion-system.md · reglas de trabajo: references/motion-rules.md.
- Se anade o se toca una animacion, un beat (
data-motion), un bloque (data-motion-block), una cifra (data-count-to) o el ambiente de scroll. npm run verify:motiononpm run verify:previewen rojo.- Hay que tocar el vendor de GSAP.
- Pre-estado en CSS, animacion en el motor. Lo que se oculta se oculta bajo
html.motion-armed(clase que pone el script inline del layout solo si hay JS, GSAP y el visitante no pide movimiento reducido). Sin JS no se oculta nada. - Prohibido animar layout. Solo
transform,opacity,clip-path,mask-*,stroke-dashoffsetyfilterpequeno. Nada dewidth,height,top,left,margin. - Nada de
background-clip: textsobre texto partido: las piezas quedan transparentes. - Una animacion gana al
styleen linea. Si el motor escribe una propiedad en un elemento, ninguna animacion de scroll puede escribir esa misma propiedad.
| Pieza | Donde |
|---|---|
Tokens y @property, pre-estados y guardas | src/styles/motion/{tokens,primitives,scroll,interactions,home}.css |
| Motor: bloques, beats, efectos, cifras, ciclo de vida | src/lib/motion/choreograph.ts |
| Instalacion en el ciclo de Astro, foco del puntero, header | src/lib/motion/index.ts |
| Reparto de texto en el build (palabras o letras) | src/components/motion/SplitText.astro |
| Contrato CSS ↔ modulo | src/lib/motion/styles.test.ts |
Un contenedor se marca data-motion-block (+ data-motion si tambien es beat, como las
tarjetas) y sus hijos con data-motion. Dentro de un bloque, los elementos de un bloque
anidado se excluyen: el panel de un acordeon es data-motion-block="manual" y se dibuja
al abrirse.
El elemento que es bloque y beat lleva su entrada con GSAP y queda fuera de la cortina
m-block-exit: si el motor escribe una propiedad, el scroll no puede tocarla.
Un enlace que preview.js mida (o un ancestro suyo) entra solo con opacidad (el motor
fuerza fade) y el guion del bloque se termina en pointerover/focusin. Las pildoras de
«Posts que enlazan a este articulo» viven fuera de .prose, donde el gate de findHit()
no mira: solo tienen tooltip si llevan data-preview="on".
Icon.astro renderiza una cadena SVG fija y no hace spread: un data-motion puesto en
<Icon /> desaparece sin aviso. Si un beat tiene que envolver un icono, se envuelve
(<span data-motion="draw">). No hay astro check en el proyecto: un atributo o un
import perdido no lo detecta ni el linter ni el build.
public/vendor/gsap.min.js se sincroniza con npm run vendor:gsap, y npm run build corre
npm run vendor:gsap -- --check, que compara byte a byte. No se toca a mano ni se
formatea: si hay que regenerarlo, npm run vendor:gsap.
cd ~/markeup
npm run verify:motion # GATE: orden, nada oculto sin JS, CLS 0, p95 < 20 ms,
# ningun frame > 60 ms, movimiento reducido.
# Recorre portada + /posts + primera categoria + un articulo
npm run verify:preview # hover-tooltip en un navegador real (necesita build + Chrome)
npm run test # styles.test.ts (contrato CSS ↔ modulo)
verify:motioninyecta dos sondeos a proposito: uno temprano (Page.addScriptToEvaluateOnNewDocument) que apunta cuando entra cada tarjeta y otro posterior. Cambiar eso rompe la lectura de los tiempos.verify:previewno esta en el CI bloqueante (necesita un navegador instalado) y su comprobacion del maximo de frame es fragil: el indicador que hay que mirar es el p95.
- Anima con
transform/opacity/clip-path; si necesitas animar un tamano, replantea la pieza (el tooltip se cae justo por eso). - Respeta
prefers-reduced-motion: los componentes que no son del sistema tambien lo miran (media reduceencomponents.cssy en los grafos). - Tras tocar animacion:
npm run verify:motion,npm run verify:previewy, si tocaste los grafos,npm run verify:graphs. - No anadir librerias de animacion: se reutiliza el GSAP que el layout ya carga.
references/motion-rules.md— pre-estados, beats, prohibiciones y checklist.markeup-graphs— el otro subsistema con gate de navegador.- Codigo:
src/lib/motion/,src/styles/motion/,scripts/mjs/verify-motion.mjs.
¿Quieres saber cómo se piden estas cosas? La guía completa está en skills de Hermes Agent, con la chuleta de objetivos y los casos paso a paso.
Movimiento y animación
Explora las ramas del artículo
