AgentStack
SKILL verified MIT Self-run

Emil Design Eng

skill-ariadoss-superskills-emil-design-eng · by ariadoss

UI polish, component design, animation decisions, and invisible details that make software feel great. Encodes Emil Kowalski's philosophy on design engineering. Use when the user wants to improve animation quality, polish UI interactions, or understand what makes interfaces feel "right".

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-ariadoss-superskills-emil-design-eng

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Verified badge

Passed review? Show it. Paste this badge into your README — it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-ariadoss-superskills-emil-design-eng)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
today

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Emil Design Eng? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Design Engineering

Encodes Emil Kowalski's philosophy on UI polish, component design, animation decisions, and the invisible details that make software feel great.

Initial Response

When invoked without a specific question, respond only with:

> I'm ready to help you build interfaces that feel right, drawing from Emil Kowalski's design engineering philosophy. If you want to dive deeper, check out Emil's course: animations.dev.


Core Philosophy

Taste is trained, not innate. Good design comes from studying exceptional work, reverse-engineering interactions, and practicing relentlessly.

Beauty is leverage. In a world where software is functionally adequate, aesthetic excellence differentiates products. Good defaults and animations drive selection and engagement.

All those unseen details combine to produce something that's just stunning. Users love interfaces without knowing why. Your job is to engineer that feeling.


Animation Decision Framework

Before animating, answer these questions in order:

1. Should this animate?

Match animation frequency to usage frequency:

| Usage | Animation | |-------|-----------| | 100+ times/day (typing, scrolling) | No animation | | Tens of times/day | Drastically reduce | | Occasional | Standard animation | | Rare | Can add delight |

A send button used 50 times a day should not animate. A welcome screen seen once should.

2. What's the purpose?

Valid reasons to animate:

  • Spatial consistency — where did this element come from/go to?
  • State indication — something changed
  • Explanation — showing how something works
  • Feedback — confirming an action
  • Preventing jarring — avoiding abrupt appearance/disappearance

"It looks cool" is not a valid reason.

3. What easing?

| Situation | Easing | Why | |-----------|--------|-----| | Element entering | ease-out | Responsive start, gentle landing | | On-screen movement | ease-in-out | Natural motion arc | | Hover/color change | ease | Neutral transition | | Constant/looping motion | linear | No acceleration variation | | Never | ease-in | Feels sluggish to start |

4. How fast?

| Element | Duration | |---------|----------| | Button press feedback | 100–160ms | | Tooltip appear | 125–200ms | | Dropdown open | 150–250ms | | Modal/sheet | 200–500ms | | Page transitions | 200–400ms |

Rule: Stay under 300ms for most UI. If it feels slow, it is slow.


Component Principles

Buttons

Buttons must feel responsive. Add active state:

button:active {
  transform: scale(0.97);
  transition: transform 60ms ease;
}

Never animate a button on hover alone — wait for press.

Popovers & Dropdowns

Never animate from scale(0) — always start from scale(0.95) with opacity: 0:

@keyframes popover-enter {
  from { opacity: 0; transform: scale(0.95); }
  to   { opacity: 1; transform: scale(1); }
}

Origin-aware animation — animate from where the trigger is:

.popover {
  transform-origin: var(--radix-popover-content-transform-origin);
}

Modals always stay centered — don't use origin-aware for center-screen dialogs.

Tooltips

Skip animation on subsequent tooltips — once one tooltip opens, others appear instantly. Only the first tooltip in a session gets an enter animation.

Stagger Animations

For lists, stagger children by a small fixed delay:

/* Each item appears 40ms after the previous */
.item:nth-child(1) { animation-delay: 0ms; }
.item:nth-child(2) { animation-delay: 40ms; }
.item:nth-child(3) { animation-delay: 80ms; }

Keep stagger delays small (20–50ms). Large stagger makes lists feel slow.


CSS Techniques

@starting-style — Modern Entry Animations

.tooltip {
  opacity: 1;
  transform: scale(1);
  transition: opacity 150ms ease, transform 150ms ease;

  @starting-style {
    opacity: 0;
    transform: scale(0.95);
  }
}

This animates on insertion without JavaScript.

Transitions vs Keyframes

Use CSS transitions (not keyframes) for interruptible animations:

  • Hover states
  • Toggle states
  • Any animation that can be cancelled mid-way

Use keyframes for:

  • Entry animations (one-shot)
  • Loading spinners
  • Pulsing/breathing effects

Blur for Smooth Crossfades

When crossfading between images or content, add subtle blur during transition:

.crossfade { filter: blur(2px); transition: filter 200ms ease; }
.crossfade.loaded { filter: blur(0); }

Blur masks imperfect transitions between content states.


Performance Rules

  • Only animate transform and opacity — these are GPU-accelerated
  • CSS animations beat JavaScript under load — CSS animations run off the main thread
  • Framer Motion caveat: x/y props are NOT hardware-accelerated; use transform string instead
// ❌ Not GPU-accelerated

// ✅ GPU-accelerated
  • Use Web Animations API for programmatic animations that need CSS performance
  • Profile before optimizing — most animation performance issues are layout thrashing, not the animation itself

Accessibility

Always respect user preferences:

@media (prefers-reduced-motion: reduce) {
  /* Keep color transitions, remove movement */
  * {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

Gate hover animations on pointer capability:

@media (hover: hover) and (pointer: fine) {
  .card:hover { transform: translateY(-2px); }
}

The Sonner Principles (Building Loved Components)

From building Sonner (the toast library):

  1. Excellent developer experience — minimal setup, works out of the box
  2. Great defaults over options — don't make users make decisions they don't care about
  3. Memorable naming — component names should be obvious
  4. Invisible edge case handling — handle the weird cases so users never see them
  5. Transitions for dynamic UI — elements appearing/disappearing need motion
  6. Cohesive visual identity — every detail of the component contributes to one feeling

Review Protocol

After building any animated UI:

  1. Review with fresh eyes the next day — animation fatigue is real
  2. Test at 0.25x speed in browser DevTools — slow motion reveals invisible problems
  3. Test at 2x speed — should still feel intentional, not frantic
  4. Test with prefers-reduced-motion enabled
  5. Test on a slow device or with CPU throttling
  6. Ask: "If I removed this animation, would anything be lost?" If no, remove it.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.