motion-polish

Use this skill when the user wants to add animations, make transitions smooth, add micro-interactions, or apply final polish. Also use when the user says 'my app feels static,' 'add some life to this,' 'make it feel smoother,' 'the transitions are janky,' or 'make this feel like Linear/Stripe.' Covers transition patterns, micro-interactions, page transitions, loading animations, scroll interactions, and the restraint principle.

157 stars

Best use case

motion-polish is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use this skill when the user wants to add animations, make transitions smooth, add micro-interactions, or apply final polish. Also use when the user says 'my app feels static,' 'add some life to this,' 'make it feel smoother,' 'the transitions are janky,' or 'make this feel like Linear/Stripe.' Covers transition patterns, micro-interactions, page transitions, loading animations, scroll interactions, and the restraint principle.

Teams using motion-polish should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/motion-polish/SKILL.md --create-dirs "https://raw.githubusercontent.com/whawkinsiv/solo-founder-superpowers/main/skills/motion-polish/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/motion-polish/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How motion-polish Compares

Feature / Agentmotion-polishStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use this skill when the user wants to add animations, make transitions smooth, add micro-interactions, or apply final polish. Also use when the user says 'my app feels static,' 'add some life to this,' 'make it feel smoother,' 'the transitions are janky,' or 'make this feel like Linear/Stripe.' Covers transition patterns, micro-interactions, page transitions, loading animations, scroll interactions, and the restraint principle.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Motion & Polish

Animation is the final 10% that makes a functional app feel premium. Apply motion to reinforce spatial relationships, confirm user actions, and smooth state changes. This skill covers what to animate, how to animate it, and — most importantly — what to leave alone.

**This skill is for adding motion and animation polish.** For visual design (colors, typography, spacing), use **beautify**. For page layouts and component selection, use **ui-patterns**. For user flow and navigation design, use **ux-design**. For a full design audit, use **design-review**.

## Quick Start

**Tell AI:**
```
Add polish animations to my app. Apply these in order of impact:
1. Button press feedback (subtle scale on click)
2. Hover states on cards and interactive elements
3. Smooth transitions on modals, dropdowns, and side panels
4. Loading skeletons replacing spinners for content areas
5. Toast notification entrance/exit animations

Use CSS transitions where possible (not JS). Respect prefers-reduced-motion.
Keep all durations under 300ms. Use ease-out for entrances, ease-in for exits.
```

## Workflow

```
Add motion polish (in priority order):
- [ ] Button press feedback (active:scale-[0.98])
- [ ] Hover states on cards and list items
- [ ] Modal/dropdown entrance transitions (fade + scale from 95%)
- [ ] Loading skeletons instead of spinners
- [ ] Toast notification entrance/exit
- [ ] Staggered list entrance on page load
- [ ] Reduced motion support (prefers-reduced-motion)
```

**Do these in order.** Each one is independently valuable. Stop whenever it feels like enough.

**Lovable / Replit** — paste the Quick Start prompt above. These tools apply Tailwind transitions directly.

**Claude Code** — use the Quick Start prompt, or point to specific components: "Add hover state animation to the card component in `src/components/Card.tsx`."

---

## The Restraint Principle

What you don't animate matters more than what you do. If a user notices an animation, it's probably too much. Motion should feel like physics — objects have weight, momentum, and settle into place. It should never feel like a performance.

**Hard rules:**

- Never animate something just because you can. Every animation must serve a purpose: confirm an action, maintain spatial context, or guide attention.
- Never animate more than two things simultaneously. The eye can't track it.
- Never add animation during MVP. Ship the product, then polish.
- If removing an animation makes the UI worse, keep it. If removing it changes nothing, delete it.
- When in doubt, use opacity. Fading is the least distracting transition and works in nearly every context.

---

## Timing and Easing

### Duration Guidelines

| Interaction Type | Duration | Why |
|-----------------|----------|-----|
| Micro-interactions (hover, focus) | 100–150ms | Must feel instant. User expects immediate feedback. |
| Element transitions (expand, collapse) | 150–250ms | Enough to see the change, not enough to wait. |
| Page transitions | 200–300ms | Smooth the jarring content swap. |
| Complex sequences (staggered lists) | 200–400ms total | Individual items faster, total sequence under 400ms. |

**Hard ceiling: 500ms.** No UI animation should ever exceed this. Anything longer feels broken, not polished.

### Easing Functions

- **`ease-out`** — For entrances. Element arrives and decelerates into place. Most common easing in UI.
- **`ease-in`** — For exits. Element accelerates away. Use when something is leaving the screen.
- **`ease-in-out`** — For state changes where the element stays on screen (toggle slide, position shift).
- **Never use `linear`** for UI animations. Linear motion has no acceleration — it feels robotic and mechanical. Reserve it for infinite loops like spinners.

### Tailwind Defaults

```
transition-all duration-150 ease-out    /* micro-interactions */
transition-all duration-200 ease-out    /* element transitions */
transition-all duration-300 ease-in-out /* page/state transitions */
```

For custom easing, define `cubic-bezier` values in your Tailwind config. A good general-purpose curve: `cubic-bezier(0.4, 0, 0.2, 1)` (Material Design standard).

---

## Transition Patterns

### Fade

Use for content replacing content — tab changes, page loads, image swaps.

```css
/* CSS */
.fade-enter { opacity: 0; }
.fade-enter-active { opacity: 1; transition: opacity 200ms ease-out; }
.fade-exit-active { opacity: 0; transition: opacity 150ms ease-in; }
```

Tailwind: `transition-opacity duration-200 ease-out`

Fade is the safest default. When unsure which transition to use, fade.

### Slide

Use for panels, drawers, mobile menus, and side sheets. The direction must match the trigger — a left sidebar slides in from the left, a bottom sheet slides up from the bottom.

```css
/* Slide from right (for side panels) */
.panel { transform: translateX(100%); transition: transform 250ms ease-out; }
.panel.open { transform: translateX(0); }
```

Tailwind for a right panel: `translate-x-full` → `translate-x-0` with `transition-transform duration-250 ease-out`

### Scale

Use for modals, tooltips, popovers, and dropdown menus. Scale from 95% to 100% — not 0% to 100%. The subtle 5% scale change adds life without being dramatic.

```css
.modal { opacity: 0; transform: scale(0.95); transition: all 200ms ease-out; }
.modal.open { opacity: 1; transform: scale(1); }
```

Tailwind: `scale-95 opacity-0` → `scale-100 opacity-100` with `transition-all duration-200 ease-out`

Always combine scale with fade. Scale alone looks jarring.

### Expand / Collapse

Use for accordions, detail disclosures, and expandable sections. Animate `max-height` or `grid-template-rows` — not `height`, which requires knowing the exact pixel value.

```css
/* Modern approach using grid */
.collapsible { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 250ms ease-in-out; }
.collapsible.open { grid-template-rows: 1fr; }
.collapsible > div { overflow: hidden; }
```

Tailwind: Use `grid` with `grid-rows-[0fr]` → `grid-rows-[1fr]` and `transition-all duration-250 ease-in-out`. The inner content needs `overflow-hidden`.

---

## Micro-Interactions

These are the small details that make an app feel alive. Each one takes minutes to implement and compounds into a premium feel.

### Button Feedback

Add a subtle scale on press. Not on hover — on active press.

```
active:scale-[0.98] transition-transform duration-100 ease-out
```

Never go below `scale-[0.95]` — it looks broken, not responsive.

### Hover States

Go beyond color change. Combine two properties for a richer feel:

```
hover:shadow-md hover:-translate-y-0.5 transition-all duration-150 ease-out  /* cards */
hover:bg-gray-100 transition-colors duration-100 ease-out                    /* list items */
```

For primary action buttons, darken the background. For cards, elevate with shadow. For list items, add a background.

### Toggle / Switch

The thumb should slide smoothly, and the track color should transition:

```
/* Track */
transition-colors duration-200 ease-in-out

/* Thumb */
transition-transform duration-200 ease-in-out
```

### Checkbox and Radio

Add a scale bounce on check. The checkmark appears at `scale-100` from `scale-0`:

```
transition-all duration-150 ease-out
```

Do not add rotation or complex keyframes to checkboxes. A simple scale entrance is enough.

### Input Focus

Expand the focus ring outward. Combine `ring` with a color transition on the border:

```
focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-all duration-150 ease-out
```

For floating labels, translate the label up and scale it down simultaneously:

```
/* Label moves from inside input to above it */
peer-focus:-translate-y-6 peer-focus:scale-75 transition-all duration-200 ease-out
```

### Link Hover

Animate the underline rather than toggling it. Use a pseudo-element that scales from 0 to 100% width:

```css
a { text-decoration: none; position: relative; }
a::after { content: ''; position: absolute; bottom: 0; left: 0; width: 0; height: 1px;
  background: currentColor; transition: width 200ms ease-out; }
a:hover::after { width: 100%; }
```

---

## Page Transitions

### Staggered List Entrance

When a list of items loads, stagger their entrance so each item fades in 50ms after the previous one. Cap the total at 400ms — after 8 items, all remaining items appear together.

```css
.list-item { opacity: 0; transform: translateY(8px); animation: fadeUp 200ms ease-out forwards; }
.list-item:nth-child(1) { animation-delay: 0ms; }
.list-item:nth-child(2) { animation-delay: 50ms; }
.list-item:nth-child(3) { animation-delay: 100ms; }
/* ... cap at nth-child(8) with 350ms delay */

@keyframes fadeUp { to { opacity: 1; transform: translateY(0); } }
```

Keep the vertical offset small — 8px max. Larger offsets feel sluggish.

### Content Fade on Route Change

When navigating between pages, fade the outgoing content out (150ms) and the incoming content in (200ms). Do not slide pages left/right — that pattern is for mobile native apps, not web.

### Skeleton-to-Content Crossfade

When skeleton placeholders are replaced with real content, crossfade rather than swap. The skeleton fades out as real content fades in, overlapping briefly. Duration: 200ms.

### List Item Reorder

When items change position (sorting, filtering, drag-and-drop), animate the layout shift. Items should glide to their new position over 200ms with `ease-in-out`. In CSS, use `View Transitions API` or in React use `layoutId` (Framer Motion) or `<AnimatePresence>`.

Never let list items jump to new positions without animation — it's disorienting.

---

## Loading and Progress

### Skeleton Shimmer

Use content-shaped placeholder blocks with a shimmer animation. Match the skeleton shape to the real content layout — if the content is a card with a title and two lines of text, the skeleton should have a wide bar and two narrower bars.

```
animate-pulse bg-gray-200 rounded
```

`animate-pulse` is sufficient for most cases. Custom shimmer (a moving gradient) looks more polished but adds complexity — only bother for landing pages or first-impression screens.

### Spinners

Use spinners only in two places: inside buttons during form submission, and as a full-page loader during initial app load. Never use spinners for inline content — use skeletons instead.

Button spinner: replace the button text with a small spinner (16px) and disable the button. Keep the button the same width to prevent layout shift.

### Progress Bars

Use for file uploads, multi-step forms, and any process where you can report a percentage. Animate the width with `transition-all duration-300 ease-out`. Add a subtle stripe or pulse animation to indicate active progress vs. stalled.

### Optimistic UI

The fastest animation is no animation — show the result immediately. When a user toggles a setting, likes a post, or sends a message, update the UI instantly and sync to the server in the background. If the server request fails, revert the UI and show an error toast. This makes apps feel dramatically faster than waiting for a round-trip.

---

## Scroll Interactions

### Sticky Header Shadow

Add a shadow to the header when the user scrolls past 0. This provides a visual cue that there is content above.

```js
// Add shadow-sm when scrolled
window.addEventListener('scroll', () => {
  header.classList.toggle('shadow-sm', window.scrollY > 0);
});
```

Transition the shadow: `transition-shadow duration-200 ease-out`.

### Scroll-Triggered Fade-In

For landing pages, fade in sections as they enter the viewport. Use `IntersectionObserver` — not scroll event listeners. Trigger when 20% of the element is visible.

```js
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) { entry.target.classList.add('visible'); observer.unobserve(entry.target); }
  });
}, { threshold: 0.2 });
```

```css
.reveal { opacity: 0; transform: translateY(16px); transition: all 400ms ease-out; }
.reveal.visible { opacity: 1; transform: translateY(0); }
```

Use this on landing pages and marketing pages. Do not use scroll-triggered animations inside the app dashboard — it slows down task completion.

### Parallax

Almost never use in SaaS apps. Parallax is a marketing site technique that adds visual complexity without functional value. If you absolutely must use it, limit it to the hero section of your landing page and keep the offset subtle (20-30px max).

### Infinite Scroll vs. Pagination

Use pagination for data tables, search results, and anything users need to reference or return to. Use infinite scroll only for social feeds, activity logs, and chat — content that is consumed chronologically and rarely revisited.

---

## Feedback Animations

### Toast Notifications

Entrance: slide + fade from the edge. Standard position is top-right for desktop, top-center for mobile.

```css
.toast { transform: translateX(100%); opacity: 0; transition: all 300ms ease-out; }
.toast.visible { transform: translateX(0); opacity: 1; }
```

Exit: fade out after 4–5 seconds. Use `opacity` only for exit — no slide-out needed.

Include a slim progress bar at the bottom of the toast showing remaining display time. This gives users a sense of control without requiring action.

### Success State

Use a subtle green flash on the saved element, or a checkmark icon that scales in from 0. Keep it under 300ms. Do not use confetti, bouncing checkmarks, or elaborate celebrations for routine actions. Save celebratory animation for milestone events (first project created, first paying customer).

### Error Shake

A horizontal shake draws attention to the error without being aggressive:

```css
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}
.error-shake { animation: shake 200ms ease-in-out; }
```

Use this on form fields with validation errors or on a login form after failed authentication. Do not shake the entire page or large containers.

### Form Submission Flow

The full sequence for a submit button: idle → loading (spinner replaces text, button disabled) → success (checkmark, green, 1 second) → reset to idle. If error, show error shake on the button and display the error message.

```
/* Button states via Tailwind */
idle:        bg-blue-600 text-white
loading:     bg-blue-600 text-white opacity-75 cursor-not-allowed
success:     bg-green-600 text-white (hold 1s, then transition back)
error:       bg-red-600 text-white (hold 0.5s, then transition back)
```

---

## Reduced Motion

Always respect the user's motion preferences. This is an accessibility requirement, not an optional enhancement.

### CSS Implementation

```css
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
```

### Tailwind Implementation

Prefix motion-dependent classes with `motion-safe:`:

```
motion-safe:transition-all motion-safe:duration-200 motion-safe:ease-out
motion-safe:animate-pulse
motion-safe:hover:-translate-y-0.5
```

### What to Keep Under Reduced Motion

- **Keep:** Opacity transitions (fade is non-vestibular and generally safe), color transitions, border/shadow changes.
- **Remove:** All transforms (translate, scale, rotate), all keyframe animations, scroll-linked movement, parallax, staggered entrances.
- **Remove delays:** If any animation remains, it should be instant.

---

## CSS vs. JS Animation

### Use CSS When

- Hover and focus states
- Simple enter/exit transitions (fade, slide, scale)
- Skeleton shimmer and spinner loops
- State changes (color, shadow, border)
- Anything triggered by a class toggle

CSS transitions and keyframes are hardware-accelerated, have zero bundle cost, and work without JavaScript loading.

### Use JS (Framer Motion / Motion) When

- Layout animations (elements moving to new positions in the DOM)
- Exit animations (CSS cannot animate an element being removed)
- Spring physics (natural-feeling bounce and settle)
- Gesture-driven animation (drag, pinch, swipe)
- Complex orchestrated sequences (timeline of multiple elements)
- Shared layout transitions (element morphing between two states)

### The Rule

If CSS can do it, use CSS. Framer Motion adds ~30KB to your bundle. That cost is justified for layout animations and exit transitions, but not for hover states and fades.

When using Framer Motion, import only what you need:

```js
import { motion, AnimatePresence } from 'framer-motion';
// NOT: import * as framer from 'framer-motion';
```

---

## Common Mistakes

| Mistake | Fix |
|---------|-----|
| Animating everything | Apply the restraint principle. Animate interactions, not decorations. |
| Duration too long | If you can perceive the animation as "slow," cut the duration in half. |
| Using `linear` easing | Use `ease-out` for entrances, `ease-in` for exits. |
| Animating `width`/`height` | Animate `transform` and `opacity` — they're GPU-accelerated. `width`/`height` cause layout recalculation. |
| Ignoring `prefers-reduced-motion` | Wrap all motion in `motion-safe:` or the media query. |
| Adding motion during MVP | Ship first. Polish after you have users who will feel the difference. |
| Spinners for inline content | Use skeleton loaders. Spinners are for buttons and full-page loads only. |
| Parallax in a SaaS dashboard | Parallax is for marketing sites. Inside the app, it just gets in the way. |

---

## Related Skills

- **beautify** — Visual design: colors, typography, spacing, composition
- **ui-patterns** — Page layouts, component selection, responsive design
- **ux-design** — User flows, navigation, interaction patterns
- **design-review** — Full design audit and quality gate
- **optimize** — Performance optimization (animation can cause jank if done wrong)

Related Skills

validate

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to validate a business idea, test demand before building, run a smoke test, create an MVP experiment, or decide whether an idea is worth pursuing. Covers demand validation, smoke tests, fake-door tests, landing page experiments, and go/no-go decision frameworks for bootstrapped founders.

ux-design

157
from whawkinsiv/solo-founder-superpowers

Use this skill when flows feel clunky, users are confused, navigation needs planning, onboarding needs design, or accessibility needs implementation. Covers information architecture, user flows, interaction patterns, progressive disclosure, and error handling UX.

ui-patterns

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to build a dashboard, settings page, data table, or any page layout. Also use when choosing component libraries, implementing responsive design, dark mode, or handling UI states (loading, empty, error). Covers component selection, page composition, and responsive implementation.

translate

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user is a domain expert (lawyer, doctor, contractor, accountant, etc.) who wants to turn their professional knowledge into a software product. Also use when the user says 'I have an idea for my industry,' 'I know this problem exists,' 'I want to build something for [profession],' or is struggling to describe what they want the software to do. Helps identify which professional pain is worth building for, then translates it into requirements AI tools can execute.

test

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to test features before deployment, create test scenarios, find edge cases, or verify bug fixes. Covers manual testing workflows, cross-browser testing, edge case identification, and testing checklists for non-technical founders.

technical-seo

157
from whawkinsiv/solo-founder-superpowers

Use this skill to implement technical SEO optimizations in code — meta tags, schema markup, Core Web Vitals, crawlability, robots.txt, sitemaps, and GEO (Generative Engine Optimization) for AI search engines. This is the implementation skill — for strategy see seo, for content writing see seo-content, for auditing see seo-audit.

support

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to create help docs, build a knowledge base, set up self-serve support, or reduce support tickets. Covers documentation strategy, help center structure, support tone, and scaling support without hiring.

social-media

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to grow a social media presence, create content for Twitter/X, LinkedIn, or other platforms, build a founder brand, or use social media as a distribution channel. Covers platform strategy, content frameworks, posting cadence, and audience building for bootstrapped SaaS founders.

seo

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to plan SEO content, do keyword research, build a content calendar, map search intent to page types, or create an internal linking strategy. Also use when the user says 'how do I rank higher,' 'what should I write about for SEO,' 'SEO plan,' 'what keywords should I target,' or 'how to get organic traffic.' This is the strategy and planning skill — for writing content see seo-content, for technical implementation see technical-seo, for auditing see seo-audit.

seo-content

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to write SEO content — blog posts, landing pages, feature pages, comparison pages, how-to guides, or any content meant to rank in search and get cited by AI. Covers content briefs, humanized writing that avoids AI detection, SERP feature targeting, entity optimization, content refresh, and quality self-checks. This is the writing skill — for strategy see seo, for technical implementation see technical-seo, for auditing see seo-audit.

seo-audit

157
from whawkinsiv/solo-founder-superpowers

Audit a codebase for SEO and AI-answer visibility, then produce a prioritized fix-it plan. Use this skill whenever a user says things like "audit my SEO", "check my site for search visibility", "how do I rank better", "optimize for Google", "optimize for AI answers", "SEO review", "GEO audit", "run the SEO agent", or anything about improving organic traffic or search rankings. Also trigger when someone mentions wanting visibility in AI-generated answers (ChatGPT, Gemini, Perplexity, Claude). Works on any web project — static sites, Next.js, Astro, Hugo, WordPress themes, or anything that outputs HTML.

secure

157
from whawkinsiv/solo-founder-superpowers

Use this skill when the user needs to secure their SaaS app, implement authentication, protect user data, secure APIs, or check for vulnerabilities. Also use when the user says 'is my app secure,' 'security check,' 'I'm worried about hackers,' 'how do I protect user data,' or 'security before launch.' Covers OWASP Top 10, auth best practices, data protection, and security checklists for apps built with AI tools.