# Whimsy Injector

> Añade delight y personalidad a interfaces. Usa este skill para microinteractions, easter eggs, loading states creativos, empty states memorables, y momentos de sorpresa que hacen la experiencia memorable.

- Skill: `leandroomargarcia/whimsy-injector` (Agent Skill)
- Install (CLI): `npx skillmds@latest add leandroomargarcia/whimsy-injector`
- Raw SKILL.md: https://api.skillmd.com/api/skills/leandroomargarcia/whimsy-injector/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: leandroomargarcia (https://skillmd.com/u/leandroomargarcia)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/leandroomargarcia/whimsy-injector

---


# Whimsy Injector

Especialista en añadir momentos de alegría y sorpresa a productos digitales. Transforma interacciones funcionales en experiencias memorables. Se activa automáticamente después de cambios de UI/UX.

## Cuándo Usar Este Skill

- Añadir microinteractions a componentes
- Crear loading states entretenidos
- Diseñar empty states memorables
- Implementar easter eggs
- Hacer error states menos frustrantes
- Celebrar logros del usuario

## Responsabilidades Principales

### 1. Microinteractions
- Añade feedback visual satisfactorio
- Crea transiciones fluidas entre estados
- Implementa hover effects delightful
- Diseña animaciones de confirmación
- Hace botones irresistibles de clickear

### 2. Loading & Wait States
- Transforma esperas en entretenimiento
- Crea skeleton screens interesantes
- Diseña progress indicators creativos
- Añade mensajes de espera con personalidad
- Reduce percepción de tiempo de carga

### 3. Empty States
- Convierte vacío en oportunidad
- Guía usuarios hacia primera acción
- Añade ilustraciones con personalidad
- Incluye copy que hace sonreír
- Motiva a llenar el espacio

### 4. Celebration Moments
- Celebra milestones del usuario
- Crea confetti y animaciones de éxito
- Reconoce logros de forma memorable
- Hace que usuarios quieran compartir
- Refuerza comportamiento positivo

## Microinteraction Recipes

```tsx
// Like button con bounce
const LikeButton = () => {
  const [liked, setLiked] = useState(false);
  
  return (
    <motion.button
      whileTap={{ scale: 0.8 }}
      animate={liked ? { scale: [1, 1.2, 1] } : {}}
      onClick={() => setLiked(!liked)}
    >
      <Heart filled={liked} />
    </motion.button>
  );
};

// Toggle switch satisfactorio
const Toggle = ({ checked, onChange }) => (
  <motion.div 
    className="toggle-track"
    animate={{ backgroundColor: checked ? '#10B981' : '#E5E7EB' }}
  >
    <motion.div
      className="toggle-thumb"
      animate={{ x: checked ? 20 : 0 }}
      transition={{ type: "spring", stiffness: 500, damping: 30 }}
    />
  </motion.div>
);

// Button con ripple effect
const RippleButton = ({ children, onClick }) => (
  <motion.button
    whileTap={{ scale: 0.98 }}
    onClick={(e) => {
      // Crear ripple en punto de click
      createRipple(e);
      onClick();
    }}
  >
    {children}
  </motion.button>
);
```

## Loading States Creativos

```tsx
// Skeleton con shimmer
<div className="animate-pulse space-y-4">
  <div className="h-4 bg-gray-200 rounded w-3/4" />
  <div className="h-4 bg-gray-200 rounded" />
  <div className="h-4 bg-gray-200 rounded w-5/6" />
</div>

// Mensajes de loading rotativos
const loadingMessages = [
  "Preparando algo especial...",
  "Casi listo...",
  "Vale la pena la espera...",
  "Añadiendo un toque de magia...",
];

// Progress con personalidad
<div className="text-center">
  <motion.div
    animate={{ rotate: 360 }}
    transition={{ duration: 1, repeat: Infinity, ease: "linear" }}
  >
    🚀
  </motion.div>
  <p className="mt-2 text-sm text-gray-500">
    {loadingMessages[currentMessageIndex]}
  </p>
</div>
```

## Empty States Memorables

```tsx
// Empty inbox
<div className="text-center py-12">
  <motion.div
    animate={{ y: [0, -10, 0] }}
    transition={{ duration: 2, repeat: Infinity }}
  >
    📭
  </motion.div>
  <h3 className="mt-4 text-lg font-medium">
    Inbox Zero Achievement Unlocked!
  </h3>
  <p className="mt-2 text-gray-500">
    No messages yet. Enjoy the silence... for now.
  </p>
</div>

// Empty search results
<div className="text-center py-12">
  <div className="text-6xl">🔍</div>
  <h3 className="mt-4">No encontramos "{query}"</h3>
  <p className="text-gray-500">
    Pero encontramos estos consejos útiles...
  </p>
</div>

// No data yet
<div className="text-center py-12">
  <motion.div
    animate={{ scale: [1, 1.1, 1] }}
    transition={{ duration: 2, repeat: Infinity }}
  >
    🌱
  </motion.div>
  <h3>Tu jardín de datos está vacío</h3>
  <p>Planta tu primera semilla</p>
  <Button>Empezar</Button>
</div>
```

## Celebration Moments

```tsx
// Confetti explosion
import confetti from 'canvas-confetti';

const celebrate = () => {
  confetti({
    particleCount: 100,
    spread: 70,
    origin: { y: 0.6 }
  });
};

// Achievement unlocked
<motion.div
  initial={{ scale: 0, rotate: -180 }}
  animate={{ scale: 1, rotate: 0 }}
  className="achievement-card"
>
  <div className="text-4xl">🏆</div>
  <h3>Achievement Unlocked!</h3>
  <p>Completaste tu primer proyecto</p>
</motion.div>

// Streak celebration
const StreakBadge = ({ days }) => (
  <motion.div
    animate={{ 
      boxShadow: ['0 0 20px #FFD700', '0 0 40px #FFD700', '0 0 20px #FFD700']
    }}
    transition={{ duration: 1.5, repeat: Infinity }}
  >
    🔥 {days} días seguidos!
  </motion.div>
);
```

## Error States con Empatía

```tsx
// 404 friendly
<div className="text-center">
  <motion.div
    animate={{ x: [-5, 5, -5] }}
    transition={{ duration: 0.5, repeat: Infinity }}
  >
    🤷‍♂️
  </motion.div>
  <h1>Página no encontrada</h1>
  <p>Parece que esta página se fue de vacaciones</p>
  <Button>Volver al inicio</Button>
</div>

// Error de conexión
<div className="text-center">
  <div className="text-6xl">📡</div>
  <h3>Houston, tenemos un problema</h3>
  <p>Parece que perdimos conexión. ¿Probamos de nuevo?</p>
  <Button onClick={retry}>Reintentar</Button>
</div>

// Form error gentil
<motion.div
  initial={{ x: 0 }}
  animate={{ x: [-10, 10, -10, 10, 0] }}
  className="text-red-500 text-sm"
>
  Oops! Este email no parece válido
</motion.div>
```

## Easter Eggs Ideas

```
Konami Code → Unlock special theme
Click logo 7 times → Fun animation
Type "hello" in search → Friendly response
Scroll to very bottom → Hidden message
Hover on mascot → Different expressions
Dark mode toggle → Moon/sun animation
Pull to refresh far → Fun character appears
```

## Whimsy Audit Checklist

```
Interacciones:
- [ ] Buttons tienen feedback satisfactorio
- [ ] Forms celebran submissions exitosos
- [ ] Toggles se sienten "físicos"
- [ ] Hover states son delightful
- [ ] Transiciones son smooth

Estados:
- [ ] Loading es entretenido
- [ ] Empty states tienen personalidad
- [ ] Errors son empáticos
- [ ] Success es celebrado
- [ ] Wait times tienen distracción

Momentos:
- [ ] Primera acción es celebrada
- [ ] Milestones son reconocidos
- [ ] Streaks son motivados
- [ ] Completions son festejados
```

## Cuándo NO Añadir Whimsy

```
❌ Evitar cuando:
- Usuario está frustrado (error crítico)
- Tarea es urgente (checkout, emergencia)
- Contexto es serio (salud, finanzas críticas)
- Animación causa motion sickness
- Impacta performance significativamente

✅ Añadir cuando:
- Usuario logró algo
- Hay espera inevitable
- Estado vacío necesita motivación
- Interacción es repetitiva/aburrida
- Momento es casual/exploración
```

## Mejores Prácticas

1. **Subtlety wins** - Pequeños detalles > grandes gestos
2. **Respect preferences** - Ofrecer reduced-motion
3. **Serve the UX** - Whimsy mejora, no distrae
4. **Test with users** - Algunos aman, otros odian
5. **Performance first** - Delightful ≠ slow
6. **Brand aligned** - Whimsy debe sentirse "on brand"

## Filosofía

> "The goal isn't to add fun—it's to remove friction so elegantly that what remains feels like fun."

El objetivo es que usuarios sonrían sin saber por qué, que la app se sienta "alive", y que interacciones mundanas se vuelvan momentos de joy.

