Skip to main content

css-animation

Generates self-contained HTML/CSS animations of app features for walkthroughs, demos, and onboarding. Researches the target app via Chrome, interviews the user, generates a structured brief and animation HTML file, then enters an iterative freeze-inspect-feedback review loop until the user approves. Use when the user says "css animation", "animate this feature", "create a css walkthrough", "animation walkthrough", or wants to create a CSS-based visual demo of an app feature.

Source facts

Repository
neonwatty/css-animation-skill
Last source activity
May 3, 2026 at 23:13
Detected SKILL.md language
English
Stars
13
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
css-animation
description
Generates self-contained HTML/CSS animations of app features for walkthroughs, demos, and onboarding. Researches the target app via Chrome, interviews the user, generates a structured brief and animation HTML file, then enters an iterative freeze-inspect-feedback review loop until the user approves. Use when the user says "css animation", "animate this feature", "create a css walkthrough", "animation walkthrough", or wants to create a CSS-based visual demo of an app feature.
# CSS Animation Walkthrough Skill You create polished, self-contained HTML/CSS animations that mimic real app features. These are used for walkthroughs, onboarding demos, and marketing. They are NOT GIFs — they are resolution-independent, tiny file size, and easy to iterate on. ## Two Animation Styles 1. **Feature Demo** — Before → Action → After. Shows a single feature transformation (e.g., clicking "Optimize" and watching seats rearrange). 2. **Carousel** — Multi-view. Cycles through several app screens with cross-fade transitions (e.g., Dashboard → Guest List → Canvas → RSVPs). Determine which style the user needs during the Interview phase. ## Phases ``` Phase 1: Research → Phase 2: Interview → Phase 3: Generate → Phase 4: Review Loop ``` --- ## Phase 1: Research Before generating anything, deeply understand the target app's visual system by navigating it in Chrome. ### Prerequisites - Claude-in-Chrome MCP tools must be available - The target app must be accessible in a browser (running locally or deployed) ### Step 1: Set up Chrome 1. Call `tabs_context_mcp` to check existing tabs 2. Create a new dedicated tab: `tabs_create_mcp` 3. Store this tab ID — use it exclusively for all subsequent browser operations ### Step 2: Navigate and explore 1. Navigate to the target app URL 2. If auth is required, ask the user to log in manually, then resume 3. **If targeting mobile or both:** Resize the browser to mobile viewport (390×844px) using `resize_window` before navigating to the feature. This ensures you research the app's actual mobile layout, not the desktop version squeezed down. If targeting **both**, research desktop first at full size, then resize to mobile and re-extract the mobile layout. 4. Navigate to the specific feature/page to animate 5. Take exploratory screenshots to understand the layout ### Step 3: Extract design language Use `read_page`, `find`, and `javascript_tool` to extract: - **Colors**: background, surface, border, accent/primary, text, text-dim ```js // Example: extract computed styles const body = getComputedStyle(document.body); JSON.stringify({ bg: body.backgroundColor, color: body.color, fontFamily: body.fontFamily }) ``` - **Fonts**: heading font-family, body font-family, font weights used - **Spacing**: padding, margins, border-radius values - **Component styles**: buttons, cards, badges, avatars, sidebar panels Record these as CSS custom properties (e.g., `--bg: #0f0f0f`). ### Step 4: Map layout geometry For the specific feature to animate: - **Container dimensions**: width, height, position of major containers - **Element positions**: absolute coordinates of key elements - **Relationships**: which elements are inside which, z-index stacking - **Circular elements**: center point and radius - **Rectangular elements**: origin (top-left), width, height Use `javascript_tool` to extract exact positions: ```js const el = document.querySelector('.selector'); const rect = el.getBoundingClientRect(); `${rect.left}, ${rect.top}, ${rect.width}, ${rect.height}` ``` ### Step 5: Screenshot key states Take screenshots of: - The feature in its default/initial state - Any intermediate states (hover, loading, processing) - The final/result state after the feature action completes These screenshots serve as visual reference for generation. --- ## Phase 2: Interview Ask the user focused questions to define what to animate. Use AskUserQuestion for each — one at a time, with multiple choice options. ### Question 1: Animation style ``` "What style of animation should this be?" - Feature Demo (Recommended): Before → Action → After. Shows one feature transformation. - Carousel: Cycles through multiple app views with cross-fade transitions. ``` ### Question 2: Target size ``` "What size should the animation target?" - Desktop only (960×620px) — for landing pages, marketing, desktop walkthroughs - Mobile only (360×640px) — for in-app tour tooltips, mobile onboarding - Both — generates two files from the same brief, one per viewport ``` When **Mobile** or **Both** is selected: - The mobile variant uses a **360×640px** stage (portrait, matching common phone viewports) - Simplify the layout: fewer elements (8–12 max), larger relative sizing, no sidebars - Drop elements that don't translate to small screens (wide toolbars, multi-column layouts) - Prefer vertical stacking over horizontal layouts - Increase font sizes relative to stage (minimum 11px body, 14px headings) - File naming: `<app>-<feature>.html` (desktop), `<app>-<feature>-mobile.html` (mobile) ### Question 3: Feature identification ``` "What specific feature or flow should the animation show?" - [Options based on research phase findings] - Other (user describes) ``` ### Question 4: The payoff moment ``` "What's the key moment — the visual 'wow' of this animation?" - [Options relevant to the chosen feature] - Other ``` ### Question 5: Emphasis ``` "Is there anything specific to emphasize or avoid showing?" - Show everything as-is - Emphasize specific elements (user specifies) - Hide certain elements (user specifies) ``` ### Question 6: Output location ``` "Where should I save the animation files?" - Current directory: [show cwd path] - Desktop - Other (user specifies path) ``` Stop after 3-6 questions — when you have enough context to generate. Don't over-interview. --- ## Phase 3: Generate This phase produces two artifacts: a **brief** (markdown) and an **HTML animation** file. ### 3a: Generate the Brief Write a structured markdown document capturing everything needed to generate or regenerate the animation. Save as `<app>-<feature>-brief.md` in the user's chosen directory. **Brief format:** ```markdown --- app: <App Name> feature: <Feature Name> style: feature-demo | carousel target: desktop | mobile | both output_file: <app>-<feature>.html output_file_mobile: <app>-<feature>-mobile.html # only when target is mobile or both --- # Design Language - Background: <hex> - Surface: <hex> - Border: <hex> - Accent: <hex> (<name>) - Text: <hex> - Text dim: <hex> - Heading font: <font> (serif/sans-serif) - Body font: <font> (sans-serif) - Border radius: <N>px - Additional colors: <name>: <hex> (for groups, statuses, categories, etc.) # Layout (Desktop) - Stage: 960x620px - [Container hierarchy description] - [Element positions with exact pixel coordinates] - [Circular elements: center point (x,y), radius R] - [Rectangular containers: origin (x,y), width, height] - [Item sizing: WxH px] # Layout (Mobile) <!-- only when target is mobile or both --> - Stage: 360x640px - [Simplified container hierarchy — no sidebars, single-column] - [Reduced element count: 8–12 elements max] - [Element positions recalculated for smaller stage] - [Larger relative element sizing: e.g., 36x36px avatars instead of 30x30px] - [Elements or sections omitted from desktop version and why] # Animation Plan ## Style: Before → Action → After (or: ## Style: Carousel with N scenes) ### Before State - [Element positions, visual state, text content] - [For circular layouts: N items, angular spacing, starting angle] ### Action (feature-demo only) - [User action: cursor movement, button click] - [Intermediate states: loading, processing] ### After State - [New positions, trigonometrically calculated for circles] - [Visual changes: colors, borders, labels, badges] - [Text content changes] ### Scene N (carousel only) - [What's visible in this scene] - [Entry animations for elements] - [Duration and transition to next scene] ### Timing - Total loop: <N>s - [Phase-by-phase durations] - Easing: cubic-bezier(0.34, 1.56, 0.64, 1) for spring motion - Easing: ease-in-out for fades ``` **Show the brief to the user** before generating HTML: ``` "Does this brief capture the animation correctly?" - Yes, generate the animation - Needs adjustments (user specifies) ``` Iterate on the brief until the user approves it, then proceed to 3b. ### 3b: Generate the HTML/CSS Animation Using the brief as your spec, generate a self-contained HTML file. Save as `<app>-<feature>.html` in the user's chosen directory. #### File Structure ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><App> – <Feature> Animation</title> <style> @import url('https://fonts.googleapis.com/css2?family=...'); /* ALL CSS here — no external stylesheets */ </style> </head> <body> <div class="stage" id="stage"> <!-- All visual elements --> </div> <script> // Minimal JS: setTimeout loop controller + class toggling ONLY </script> </body> </html> ``` #### Technical Rules (MANDATORY) **1. Trigonometric positioning for circular layouts.** NEVER eyeball positions on circles. ALWAYS calculate: ``` left = centerX + R * cos(angle_radians) - (elementWidth / 2) top = centerY + R * sin(angle_radians) - (elementHeight / 2) ``` Where: - `R` = visible radius of container + (elementSize / 2), so the element's inner edge touches the container perimeter - For N items evenly spaced: `angle_i = startAngle + i * (2 * PI / N)`, starting from `-PI/2` (top center) - Convert degrees to radians: `radians = degrees * PI / 180` Example for 7 items on a circle with center (140, 160) and R=95, items are 30x30px: ``` Item 0: angle = -90° → left = 140 + 95*cos(-90°) - 15 = 125, top = 160 + 95*sin(-90°) - 15 = 50 Item 1: angle = -38.6° → left = 140 + 95*cos(-38.6°) - 15 = 199, top = 160 + 95*sin(-38.6°) - 15 = 86 ...etc for all N items ``` **2. Rectangular edge positioning.** For items along rectangle edges, distribute evenly: - Top/bottom edges: vary X at equal intervals, Y at edge ± (elementHeight / 2) - X spacing: `containerLeft + containerWidth * (i + 1) / (numItemsOnEdge + 1)` - Left/right edges: same logic, varying Y **3. Self-contained HTML.** No external dependencies except Google Fonts `@import`. All CSS in `<style>`, all JS in `<script>`. Zero build step. **4. CSS transitions for element movement.** ```css .element { position: absolute; transition: left 1.2s cubic-bezier(0.34, 1.56, 0.64, 1), top 1.2s cubic-bezier(0.34, 1.56, 0.64, 1); } ``` **5. JS only for loop control and class toggling.** **CRITICAL: Never use inline styles** (`element.style.opacity = '1'`) in JS reset/update functions. Inline styles override CSS class rules and cause state bugs (e.g., a "hidden" element that stays visible because an inline style trumps the CSS class). Use class toggling exclusively. ```js const stage = document.getElementById('stage'); function runCycle() { // Reset — class toggling only, no inline styles stage.classList.remove('clicking', 'processing', 'optimized', 'complete'); // Reset text content to before-state values setTimeout(() => stage.classList.add('clicking'), 500); setTimeout(() => { stage.classList.remove('clicking'); stage.classList.add('processing'); }, 900); setTimeout(() => { stage.classList.remove('processing'); stage.classList.add('optimized'); // Update text content to after-state values }, 1500); setTimeout(() => stage.classList.add('complete'), 3000); setTimeout(runCycle, 6000); // Loop } setTimeout(runCycle, 300); ``` **Default to fast timing.** Users almost always want the animation faster than your first instinct. Start with snappy defaults: - Before state hold: 0.3–0.5s (just long enough to register) - Stagger between elements: 0.3–0.5s - After state hold: 2–3s - Total loop: 5–8s - Timing will be tuned iteratively in Phase 4 — start fast and slow down only if asked. **6. CSS @keyframes for non-interactive animations** — cursor movement, badge entrance, spinner rotation. Use the `animation` property on the relevant elements. **7. Stagger transitions** with `transition-delay` on individual elements (0.04–0.08s apart) for sequential movement that feels natural. **8. Stage dimensions by target.** - **Desktop:** 960×620px, `border-radius: 12px` - **Mobile:** 360×640px, `border-radius: 16px` (portrait orientation) - Always match the app's design language (dark/light theme, colors). Adjust proportions based on the app's actual layout at that viewport. **9. Hidden elements must use `visibility: hidden` alongside `opacity: 0`.** On dark backgrounds, JPEG screenshot compression creates visible artifacts for opacity-0 elements — they appear as faint ghosts. Always pair: ```css .element-hidden { opacity: 0; visibility: hidden; transition: opacity 0.5s ease-out, visibility 0s 0.5s; /* visibility delays on hide */ } .element-hidden.visible { opacity: 1; visibility: visible; transition: opacity 0.5s ease-out, visibility 0s 0s; /* visibility instant on show */ } ``` For elements that should be completely removed from flow when hidden (like placeholder text), use `display: none` via a parent class toggle: ```css .stage.active .placeholder { display: none; } ``` **10. Verify content fits the stage.** After generating, inject JS to check that all content fits within the stage bounds before entering the review loop: ```js var content = document.querySelector('.content'); var stage = document.getElementById('stage'); JSON.stringify({ stageH: stage.offsetHeight, contentH: content.scrollHeight, fits: content.scrollHeight <= stage.offsetHeight - content.offsetTop }) ``` If content overflows, compact spacing (reduce padding, margins, font sizes) or increase stage height before proceeding to review. Don't waste review cycles on overflow bugs. #### Carousel-Specific Rules - Each scene uses `opacity` keyframes to show/hide (fade in → hold → fade out) - Child elements within each scene use `animation-delay` for staggered entry - Total loop duration = sum of all scene durations + transition gaps - Use `@keyframes` with percentage-based timing for scene visibility - Each scene is a container `div` with `position: absolute; inset: 0;`
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub