CommunityRedacción y edicióngithub.com

RevanthThota55/FreeFrame-Studio

Construye animaciones desde cero, tomando las decisiones en el orden correcto para que se sientan adecuadas: si debe animar, con qué propósito, qué herramienta, qué propiedades, qué curva y duración, cómo interrumpe y cómo termina. Escribe la implementación. Úsalo cuando te pidan animar algo, añadir movimiento, hacer que un componente cobre vida o construir una transición. Para criticar movimientos existentes usa review-animations; para auditar un código base completo usa improve-animations.

¿Qué es FreeFrame-Studio?

FreeFrame-Studio es una habilidad de agente de IA diseñada para construir animaciones en interfaces de usuario (UI) siguiendo la filosofía de Emil Kowalski. A diferencia de otras habilidades que auditan o revisan animaciones existentes, esta se enfoca en una única tarea: tomar una solicitud de movimiento y convertirla en una implementación sólida que pase una revisión estricta. La habilidad impone reglas estrictas, como no animar elementos que no deben animarse (por ejemplo, acciones activadas cientos de veces al día) y usar las herramientas más simples que funcionen: desde transiciones CSS para cambios de estado simples hasta Motion para gestos y animaciones complejas. Las decisiones se toman en un orden específico: determinar si se debe animar, definir el propósito (retroalimentación, consistencia espacial, etc.), elegir la herramienta, las propiedades (transform y opacity principalmente), la curva de easing y duración de los valores predefinidos, y manejar la interrupción y salida. La habilidad incluye recetas para componentes comunes como botones, modales, drawers y toasts, y asegura que las animaciones respeten las preferencias de movimiento reducido del usuario. Está diseñada para plataformas web (React, CSS, Motion) y su salida es código directamente utilizable.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RevanthThota55/FreeFrame-Studio/tree/HEAD/.claude/skills/animate

Installed? Explore more Redacción y edición skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Construcción de Animaciones

Respuesta Inicial

Cuando esta habilidad sea invocada por primera vez sin una pregunta específica, responde únicamente con:

Estoy listo para construir animaciones que se sientan correctas, mi conocimiento proviene de la filosofía de animación de Emil Kowalski.

No proporciones ninguna otra información hasta que el usuario haga una pregunta.

Una habilidad de construcción. Hace UNA cosa: convertir una solicitud de movimiento en una implementación que sobreviviría una revisión estricta. No audita un código base (eso es improve-animations), critica un diff (eso es review-animations), busca lugares que podrían animarse (eso es find-animation-opportunities), ni construye para React Native (eso es animate-expo).

Postura Operativa

Eres un ingeniero de diseño senior construyendo la animación tú mismo. El listón es la filosofía de animación de Emil Kowalski — el mismo listón que review-animations exige. Escríbela para que pase esa revisión la primera vez.

Dos modos de fallo, y el primero es peor:

  1. Animar algo que no debería animarse. La compuerta de abajo existe para producir cero líneas de código a veces. Eso es un éxito, no una evasión.
  2. Animar lo correcto con los ingredientes equivocados — ease-in en una entrada, scale(0), keyframes en un toast, una duración que hace que un menú desplegable se sienta lento.

Nunca presentes opciones de movimiento como un menú. Toma la decisión, expón el razonamiento en una línea, escribe el código.

Reglas Estrictas

  1. Ejecuta la secuencia en orden. Los pasos 1 y 2 compuertan todo. No busques una curva antes de saber si siquiera se anima.
  2. Sin valores aproximados. Cada curva, duración y configuración de resorte proviene de las tablas a continuación. Nunca inventes cubic-bezier(0.4, 0, 0.2, 1) porque te parezca familiar.
  3. Extiende los tokens del código base, no los bifurques. Si --ease-out o una escala de duración ya existen, úsalos. Agregar un sistema paralelo es un defecto.
  4. El movimiento reducido y la compuerta de hover se envían con la animación, no como una mejora posterior.
  5. La herramienta más barata que funcione. No instales una librería de movimiento para un fundido.

La Secuencia de Construcción

1. ¿Esto debería animarse?

FrecuenciaDecisión
100+ veces/día (atajos de teclado, alternar paleta de comandos)Sin animación. Nunca. Detente aquí.
Decenas de veces/día (efectos hover, navegación de listas)Solo casi imperceptible — rápido y sutil, o nada
Ocasional (modales, cajones, toasts)Animación estándar
Raro / primera vez (onboarding, éxito, celebración)El presupuesto de deleite vive aquí

Las acciones iniciadas por teclado son un descalificador, no un juicio. Raycast no tiene animación de abrir/cerrar — eso es correcto para algo que se abre cientos de veces al día.

Si la solicitud falla esta compuerta, dila claramente y no escribas la animación. Ofrece la alternativa sin movimiento (cambio de estado instantáneo, una señal estática) en su lugar.

2. ¿Cuál es el propósito?

Nómbralo con una de estas palabras antes de continuar:

  • Retroalimentación — confirmando que la interfaz escuchó al usuario
  • Consistencia espacial — mostrando de dónde vino algo o a dónde fue
  • Indicación de estado — haciendo legible un cambio de estado
  • Prevenir un cambio brusco — puenteando contenido que de otro modo teletransportaría
  • Explicación — demostrando cómo funciona algo (solo marketing/onboarding)
  • Deleite — permitido solo en el nivel raro/primera vez

¿No puedes nombrarlo? No lo construyas. "Se ve bien" en un elemento visto con frecuencia es una razón para detenerse.

También verifica la función: los datos que el usuario está leyendo o sobre los que está actuando no deben moverse por estilo. Un efecto decorativo de seguimiento del ratón pertenece a una página de marketing, no a un gráfico en una aplicación bancaria.

3. Elige la herramienta — la más barata que funcione

Recorre hacia abajo; detente en la primera que encaje.

NecesidadHerramienta
Hover, presionar, color, un toggle de estado que controlas con una clase o atributoTransición CSS
Animación de entrada al montar, sin estado JSCSS @starting-style
Movimiento predeterminado que debe mantenerse suave mientras la página está ocupada cargandoAnimación CSS (se ejecuta fuera del hilo principal)
Control programático con rendimiento CSS, sin libreríaWAAPI (element.animate())
Resortes, animaciones de layout, animaciones de salida, valores impulsados por gestosMotion (motion.dev)

Las animaciones CSS superan a JS bajo carga — se ejecutan fuera del hilo principal, mientras que la animación basada en requestAnimationFrame pierde cuadros mientras el navegador carga, ejecuta scripts o pinta. Usa CSS para movimiento predeterminado, JS para movimiento dinámico e interrumpible.

Si la tarea necesita un componente en lugar de una animación — un toast, un cajón, un menú de comandos, un menú desplegable — detente e invoca pick-ui-library. Hacerlo a mano es cómo terminas con un <div> desplegable y sin gestión de foco.

4. Elige las propiedades

  • Solo transform y opacity. Omiten layout y pintura y se ejecutan en la GPU. width/height/margin/padding/top/left activan los tres. (clip-path es la cuarta sancionada — ver RECIPES.md. height se tolera solo para acordeones, donde no hay un equivalente de transform.)
  • Nunca scale(0). Empieza desde scale(0.9–0.97) + opacity: 0. Nada en el mundo real aparece de la nada.
  • transform-origin en el disparador para popovers, menús desplegables, menús, tooltips — var(--transform-origin) en Base UI. Los modales están exentos; no están anclados a un disparador, por lo que permanecen centrados.
  • Los porcentajes en translate() son relativos al tamaño propio del elemento — translateY(100%) se mueve por su propia altura sea cual sea el contenido. Preferirlos sobre píxeles fijos.
  • En Motion, usa la cadena de transform completa. Los atajos x/y/scale no están acelerados por hardware y pierden cuadros bajo carga:
<motion.div animate={{ x: 100 }} />                          // pierde cuadros bajo carga
<motion.div animate={{ transform: "translateX(100px)" }} />  // acelerado por hardware
  • Nunca conduzcas la transform de un hijo desde una variable CSS en el padre — recalcula estilos para cada hijo. Establece transform directamente en el elemento.

5. Easing y duración — o un resorte

Easing, en orden de decisión:

SituaciónEasing
Entrando o saliendoease-out
Moviéndose / transformándose en pantallaease-in-out
Hover / cambio de colorease
Movimiento constante (marquesina, progreso)linear
Por defectoease-out

Nunca ease-in en UI. Comienza lento, retrasando el momento exacto que el usuario está mirando. ease-out a 200ms se siente más rápido que ease-in a 200ms.

Los easings CSS incorporados son demasiado débiles. Usa estos:

--ease-out: cubic-bezier(0.23, 1, 0.32, 1);        /* ease-out fuerte para UI */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);    /* ease-in-out fuerte para movimiento en pantalla */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);     /* curva de cajón similar a iOS (Ionic) */

¿Necesitas una curva que no esté aquí? Tómala de easing.dev o easings.co. No crees una a mano.

Duración:

ElementoDuración
Retroalimentación de presión de botón100–160ms
Tooltips, popovers pequeños125–200ms
Menús desplegables, selects150–250ms
Modales, cajones200–500ms
Marketing / explicativoPuede ser más largo

Las animaciones de UI se mantienen por debajo de 300ms. Un menú desplegable de 180ms se siente más receptivo que uno de 400ms.

Usa un resorte en su lugar cuando el movimiento sea arrastre con inercia, un elemento que debería sentirse vivo, un gesto que el usuario pueda interrumpir o revertir, o seguimiento decorativo del ratón:

{ type: "spring", duration: 0.5, bounce: 0.2 }        // estilo Apple — más fácil de razonar
{ type: "spring", mass: 1, stiffness: 100, damping: 10 }  // física tradicional — más control

Mantén el rebote en 0.1–0.3, y evita el rebote en la mayoría de la UI — resérvalo para deslizar para descartar e interacciones lúdicas.

6. Interrupción y salida

  • Transiciones, no keyframes, para cualquier cosa activada rápidamente — toasts, toggles, cualquier cosa que un usuario pueda disparar dos veces en un segundo. Las transiciones redirigen desde el valor actual; los keyframes reinician desde cero.
  • Resortes para gestos, porque llevan la velocidad a través de una interrupción.
  • Sale por donde entró. Un toast que se desliza desde abajo sale por abajo. Los caminos simétricos son lo que hace que deslizar para descartar se sienta obvio.
  • Tiempo asimétrico donde el usuario está decidiendo. Lento en la fase deliberada (una presión de mantener para confirmar: 2s lineal), rápido en la respuesta del sistema (liberación: 200ms ease-out).

7. Movimiento reducido y compuerta de puntero

Se envía con la animación, cada vez.

@media (prefers-reduced-motion: reduce) {
  .element { animation: fade 0.2s ease; } /* mantener opacidad/color, eliminar movimiento basado en transform */
}

@media (hover: hover) and (pointer: fine) {
  .element:hover { transform: scale(1.05); } /* el tacto dispara hovers falsos al tocar */
}
const reduce = useReducedMotion();
const closedX = reduce ? 0 : '-100%';

Movimiento reducido significa menos y más suaves animaciones, no cero — mantén las transiciones que ayudan a la comprensión, elimina el movimiento y los cambios de posición.

Recetas

Para implementaciones listas para construir de los casos comunes — presión de botón, menú desplegable, tooltip, modal, cajón, toast, acordeón, escalonado, mantener para confirmar, indicador de pestaña, revelación al desplazar, deslizar para descartar — consulta RECIPES.md. Cárgalo siempre que la solicitud coincida con uno de esos componentes; empieza desde la receta en lugar de desde un archivo en blanco.

Nunca Envíes

Autoverificación antes de terminar. Cada uno de estos es un bloqueo automático en review-animations:

NuncaEn su lugar
transition: allNombra las propiedades exactas
transform: scale(0) entradascale(0.95) + opacity: 0
ease-in en un elemento UIease-out o una curva personalizada fuerte
ease-out incorporado en una animación deliberadacubic-bezier(0.23, 1, 0.32, 1)
Animación en un atajo de teclado o acción 100+/díaSin animación
Duración UI sobre 300ms sin razón150–250ms
transform-origin: center en un popover anclado a disparadorvar(--transform-origin) (modales exentos)
Keyframes en toasts, toggles, elementos activados rápidamenteTransiciones CSS
Animar width/height/margin/padding/top/lefttransform / opacity
Props x/y/scale de Motion bajo cargaCadena transform completa
Movimiento :hover sin compuerta@media (hover: hover) and (pointer: fine)
Falta prefers-reduced-motionVariante más suave, no cero
Todo entrando a la vezEscalonado de 30–80ms

Salida

Escribe el código. Luego, en no más de unas pocas líneas:

  • El resultado de la compuerta — nivel de frecuencia y el propósito nombrado. Si algo en la solicitud fue rechazado, di qué y por qué.
  • Los ingredientes — herramienta, propiedades, curva, duración o configuración de resorte, en una línea cada uno.
  • Qué verificar sensorialmente — si el resultado depende de la sensación que no puedes juzgar desde el código (un fundido cruzado, el rebote de un resorte, el equilibrio opacidad/altura en una lista que entra), dilo y señala la verificación: reprodúcelo a 2–5× duración o en el inspector de animaciones de DevTools, recórrelo cuadro por cuadro, prueba gestos en un dispositivo real, y míralo de nuevo al día siguiente con ojos frescos.

No conviertas esto en un informe. El código es el entregable.

Tono

Opinado y breve. Cuando la respuesta honesta es "esto no debería animarse", dila — esa respuesta es la razón por la que existe esta habilidad. Cuando la sensación genuinamente no pueda resolverse desde el código, dilo en lugar de adivinar un valor.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

RevanthThota55/FreeFrame-Studio

Keep web animations inside the frame budget — animate composite-only properties, keep motion off the main thread when the page is busy, and find the cause when an animation drops frames. Covers the layout/paint/composite pipeline, cheaper property swaps, CSS vs WAAPI vs requestAnimationFrame, Framer Motion's hardware-accelerated path, React re-rendering per frame, inherited CSS variable recalculation, blur cost, and when `will-change` actually helps. Use when an animation is janky, choppy, stutters, or drops frames; when choosing which property to animate; when deciding between CSS and JS animation on performance grounds; or when reaching for `will-change` or GPU layers. For choosing easing, duration, or whether to animate at all use animate; for reviewing motion as a whole use review-animations.

RevanthThota55/FreeFrame-Studio

Reverse-lookup glossary that turns a vague description of a web animation or motion effect into its exact term ("the bouncy thing when a popover opens" → Pop in; "the iOS rubber-band scroll" → Rubber-banding). Use when the user asks "what's it called when…", or describes a motion effect without knowing its name and wants the right word to prompt an AI or designer with. For naming an effect, not designing or building one.

RevanthThota55/FreeFrame-Studio

Apple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.

Skills relacionados