Back to skills
SKILL.md
Whimsy Injector
ASecurityUse when Micro-delight generator for frontend interfaces. Suggests and implements subtle animations, playful transitions, and interaction polish across any frontend stack.
- 5 stars
- 0 votes
- 0 copies
- 0 views
- Added September 27, 2026
Works with
Security analysis
100/100npx -y skills add Harmitx7/tribunal-kit --skill whimsy-injector --agent claude-codeAre you the author of Whimsy Injector?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/harmitx7-whimsy-injector-tribunal-kit)---
name: whimsy-injector
description: "Use when Micro-delight generator for frontend interfaces. Suggests and implements subtle animations, playful transitions, and interaction polish across any frontend stack."
version: 5.0.0
last-updated: 2026-09-13
skills:
- delight
- micro-interaction
- 60fps-animation
- accessible-animation
tools: Read, Grep, Glob, Bash, Edit, Write
scripts-binding:
- .agent/scripts/lint_runner.js
- .agent/scripts/verify_all.js
---
# Whimsy Injector Skill β Micro-Delight Generator
---
## π οΈ Technical Architecture & Reference Recipes
---
## When to Activate
- During `/enhance` or `/ui-ux-pro-max` workflows as a polish pass.
- When user asks to "add animations", "make it feel alive", "add polish", "add delight", or "make it premium".
- During the `VERIFICATION` phase of any frontend build, for a final quality pass.
- When `ui-ux-researcher` flags P2.5 (missing micro-interactions).
- When `trend-researcher` provides a motion intent that needs implementation.
## Whimsy Philosophy
**Whimsy is not decoration.** Every animation must serve a purpose:
- Guide attention β where should the user look?
- Confirm action β did the thing work?
- Create continuity β where did I come from, where am I going?
- Build personality β does this app feel human?
**If an animation doesn't serve one of these purposes, don't add it.**
## Animation Pattern Library
### Category 1: Entrance Animations
| Pattern | Purpose | Duration | Trigger |
| --------------- | ------------------------------- | ------------------ | ------------------------- |
| Fade-up | Content appearing naturally | 300-400ms | On mount / viewport entry |
| Scale-in | Modal or card emphasis | 200-300ms | On open / on mount |
| Stagger cascade | List items loading sequentially | 50ms delay Γ index | On mount / data load |
| Slide-in | Side panels, drawers | 250-350ms | On toggle |
| Blur-to-sharp | Hero images, lazy content | 400-600ms | On image load |
**Framework Implementations:**
```css
/* Vanilla CSS β Fade-up on scroll */
.reveal {
opacity: 0;
transform: translateY(20px);
transition:
opacity 0.4s ease-out,
transform 0.4s ease-out;
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
```
```javascript
// Vanilla JS β IntersectionObserver trigger
const observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
},
{ threshold: 0.1 },
);
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
```
```jsx
// React β Framer Motion stagger (only if framer-motion is in package.json)
<motion.ul variants={{ show: { transition: { staggerChildren: 0.05 } } }}>
{items.map((item, i) => (
<motion.li
key={item.id}
variants={{ hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0 } }}
/>
))}
</motion.ul>
```
```vue
<!-- Vue 3 β TransitionGroup stagger -->
<TransitionGroup name="list" tag="ul" appear>
<li v-for="(item, i) in items" :key="item.id"
:style="{ transitionDelay: `${i * 50}ms` }">
{{ item.name }}
</li>
</TransitionGroup>
```
### Category 2: Hover & Interaction States
| Pattern | CSS Implementation | Purpose |
| ------------------- | ---------------------------------------------------------------------- | ----------------------- |
| Card lift | `transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.12)` | Clickable affordance |
| Button press | `transform: scale(0.97)` on `:active` | Tactile feedback |
| Link underline draw | `background-size: 100% 2px` from `0% 2px` | Navigation affordance |
| Icon rotate | `transform: rotate(90deg)` on expand | State change indicator |
| Color shift | `background-color` transition on hover | Interactive affordance |
| Border glow | `box-shadow: 0 0 0 3px rgba(primary, 0.2)` on focus | Accessibility + delight |
```css
/* Card Lift β Universal */
.card {
transition:
transform 0.2s ease-out,
box-shadow 0.2s ease-out;
}
.card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.card:active {
transform: translateY(0);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
```
```css
/* Underline Draw β Link Hover */
.link {
background-image: linear-gradient(currentColor, currentColor);
background-position: 0% 100%;
background-repeat: no-repeat;
background-size: 0% 2px;
transition: background-size 0.3s ease-out;
text-decoration: none;
}
.link:hover {
background-size: 100% 2px;
}
```
### Category 3: Loading & Skeleton States
| Pattern | When | Duration |
| ------------------ | ---------------------------- | ------------------------- |
| Shimmer pulse | Data fetching, image loading | Continuous until loaded |
| Spinner-to-content | Short waits (< 2s) | Until complete |
| Progress bar | File uploads, long processes | Mapped to actual progress |
| Skeleton screen | Initial page paint | Until first data render |
```css
/* Shimmer Skeleton */
.skeleton {
background: linear-gradient(90deg, hsl(0, 0%, 90%) 25%, hsl(0, 0%, 95%) 50%, hsl(0, 0%, 90%) 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
border-radius: 4px;
}
@keyframes shimmer {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
```
### Category 4: Micro-Feedback
| Pattern | Trigger | Duration |
| ---------------------- | ---------------------------------- | ---------------------- |
| Success checkmark draw | Form submit success | 300ms |
| Error shake | Validation failure | 300ms (3 oscillations) |
| Counter tick-up | Stat change | 600ms (ease-out) |
| Toast slide-in | Notification | 250ms in, 200ms out |
| Confetti burst | Achievement, first-time completion | 1.5s |
```css
/* Error Shake */
@keyframes shake {
0%,
100% {
transform: translateX(0);
}
20%,
60% {
transform: translateX(-4px);
}
40%,
80% {
transform: translateX(4px);
}
}
.shake {
animation: shake 0.3s ease-in-out;
}
```
### Category 5: Page Transitions
| Pattern | When | CSS Approach |
| ------------- | ---------------------------- | -------------------------------------------------------- |
| Crossfade | Default page change | `view-transition-name` (View Transitions API) |
| Slide lateral | Tab switching, step wizard | `transform: translateX(Β±100%)` |
| Scale + fade | Modal open/close | `scale(0.95)` + `opacity: 0` β `scale(1)` + `opacity: 1` |
| Morph | Shared element between pages | `view-transition-name` on shared elements |
```css
/* View Transitions API (Chrome 111+) */
/* VERIFY: View Transitions API β check browser support for your target */
::view-transition-old(root) {
animation: fade-out 0.2s ease-out;
}
::view-transition-new(root) {
animation: fade-in 0.3s ease-in;
}
```
## Whimsy Quota Rules
> [!IMPORTANT]
> Whimsy must be **tasteful, not invasive**. These are hard limits:
### Hard Constraints
| Rule | Limit | Reason |
| ---------------------------- | ------------- | -------------------------- |
| Max animation types per page | 3 distinct | Visual coherence |
| Max concurrent animations | 5 elements | Performance |
| `prefers-reduced-motion` | **MANDATORY** | Accessibility (WCAG 2.3.3) |
| CLS impact | **Zero** | Core Web Vitals |
### Duration Constraints
| Animation Type | Min | Max | Sweet Spot |
| ------------------- | ------ | ------ | ---------- |
| Entrance | 200ms | 500ms | 300ms |
| Hover / Interaction | 100ms | 250ms | 150ms |
| Feedback | 100ms | 400ms | 200ms |
| Page transition | 150ms | 400ms | 250ms |
| Loading (loop) | 1000ms | 2000ms | 1500ms |
### Easing Reference
| Easing | CSS Value | Use For |
| ----------- | ----------------------------------- | ---------------------------- |
| Standard | `cubic-bezier(0.4, 0, 0.2, 1)` | Most UI motion |
| Decelerate | `cubic-bezier(0, 0, 0.2, 1)` | Entrances (coming into view) |
| Accelerate | `cubic-bezier(0.4, 0, 1, 1)` | Exits (leaving view) |
| Spring-like | `cubic-bezier(0.34, 1.56, 0.64, 1)` | Playful UI, toggles |
| **Never** | `linear` | β Not for UI motion |
### Mandatory Accessibility Block
Every file with animations MUST include:
```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;
}
}
```
### Performance Rules
- **Only animate `transform` and `opacity`** β these are GPU-composited and won't trigger layout/paint.
- **Never animate** `width`, `height`, `top`, `left`, `margin`, or `padding` β these trigger layout recalculation.
- **Use `will-change` sparingly** β only on elements that are actively animating.
- **Remove observers** when components unmount.
## Cross-Skill Integration
| Paired Skill | Integration Point |
| ----------------------- | ---------------------------------------------------------- |
| `trend-researcher` | Receives motion intent β implements specific animations |
| `ui-ux-researcher` | Addresses P2.5 audit findings (missing micro-interactions) |
| `frontend-design` | Ensures animations match component design tokens |
| `performance-profiling` | Monitors that injections don't degrade Web Vitals |
| `web-design-guidelines` | Validates animations against established UI patterns |
## Anti-Hallucination Guard
- **Check `package.json`** before suggesting framework-specific code (`framer-motion`, `gsap`, `@vueuse/motion`).
- **Only use documented CSS properties** β never invent animation APIs.
- **Mark experimental APIs** with `// VERIFY: [API] β check browser support for your target`.
- **Never suggest animations that cause layout shift** β enforce `transform` and `opacity` only.
- **Verify `will-change` usage** β only apply to actively animating elements, remove after animation completes.
Attribution
Comments
Loading commentsβ¦