---
name: ux-diseno
description: Principios de UX design para desarrolladores. Heurísticas de Nielsen, Fitts's Law, Ley de Miller, Gestalt, jerarquía visual, micro-interacciones, feedback visual, estados vacíos, error states, loading states.
version: "1.0.0"
herramientasPermitidas: [Read, Grep]
exclusiones:
  - "No cargar para accesibilidad técnica (ARIA, contraste WCAG, navegación por teclado, lectores de pantalla) — para accesibilidad cargar `accesibilidad-a11y`."
  - "No cargar para implementación CSS/Tailwind de los diseños — los principios aquí son conceptuales; para implementación cargar `css-moderno` o `tailwind-experto`."
  - "No cargar para investigación de usuario, entrevistas o user research — este skill cubre decisiones de diseño de implementación, no metodología de research."
  - "No cargar para diseño de sistemas de diseño (Design Tokens, Storybook, Figma) — este skill cubre principios UX aplicados al código, no herramientas de diseño."
evolvable: true  # default para skill estandar
---
# UX Design para Desarrolladores

## Cuándo NO cargar

- La tarea es accesibilidad técnica: ARIA correcta, contraste WCAG 2.1, focus trap, lectores de pantalla — cargar `accesibilidad-a11y`.
- La implementación concreta es en CSS o Tailwind — los principios aquí son conceptuales; para implementación cargar `css-moderno` o `tailwind-experto`.
- La tarea es investigación de usuario, entrevistas o user testing — este skill cubre decisiones de diseño en el código, no metodología de research.
- El tema es sistemas de diseño: Design Tokens, Storybook, integración Figma — este skill cubre principios UX, no herramientas de diseño.

Un desarrollador que entiende UX toma mejores decisiones de implementación sin necesitar
validación en cada detalle visual. Estos principios reducen fricción y aumentan la usabilidad
sin depender de un diseñador para cada componente.

---

## 1. Las 10 Heurísticas de Nielsen (resumen activo)

- **H1 — Visibilidad del estado**: Feedback inmediato. Loading states: skeleton > spinner > texto.
- **H2 — Match con el mundo real**: Hablar el idioma del usuario, no del desarrollador. NUNCA mostrar "Error 500" o UUIDs.
- **H3 — Control y libertad**: Botón "Cancelar", "Deshacer", confirmación antes de eliminar, breadcrumbs.
- **H4 — Consistencia**: Mismas convenciones siempre. Azul subrayado = enlace. Logo = inicio. X = cerrar. Escape = cancelar.
- **H5 — Prevención de errores**: Deshabilitar botón hasta formulario válido. Máscaras de input. Confirmar acciones peligrosas.
- **H6 — Reconocimiento antes que recuerdo**: Mostrar contexto entre pasos. Autocompletar. Progreso visible.
- **H7 — Flexibilidad**: Keyboard shortcuts, acciones en masa, filtros guardados.
- **H8 — Diseño minimalista**: Eliminar texto que nadie lee, campos que nadie llena, iconos sin texto.
- **H9 — Recuperación de errores**: Mensaje = Qué pasó + Por qué + Qué hacer. Ejemplo: "El RFC debe tener 13 caracteres. Ejemplo: PEGJ850101GR5".
- **H10 — Ayuda**: Tooltips en campos técnicos, links a artículos, ejemplos reales en errores.

---

## 2. Ley de Fitts — Tamaño y Distancia

Objetivos más grandes y más cercanos son más fáciles de alcanzar.

- Botones de acción principal: mínimo 44x44px de área táctil (estándar de accesibilidad)
- Acciones destructivas ALEJADAS de las primarias y con menor prominencia visual
- Acción principal prominente y a la derecha en formularios

---

## 3. Ley de Miller — 7 más o menos 2

- Menú de navegación: máximo 7 opciones de primer nivel
- Pasos de wizard: máximo 5-7 pasos
- Columnas en tabla: máximo 7 visibles sin scroll
- Opciones en dropdown: si hay más de 7, agregar búsqueda
- Formulario: agrupar campos en secciones (máximo 7 por sección)

---

## 4. Principios Gestalt

- **Proximidad**: Elementos cercanos parecen relacionados. Poco espacio dentro del grupo, mucho entre secciones.
- **Similitud**: Mismo color + estilo = misma función. NUNCA mismo color para funciones distintas.
- **Continuidad**: Alineación para guiar al ojo. Labels alineados, columnas numéricas a la derecha.

---

## 5. Estados que Toda UI Debe Manejar

Toda pantalla con datos debe implementar estos 4 estados:

1. **Loading**: Skeleton loader para listas, spinner inline para acciones puntuales
2. **Empty state**: Contexto + acción ("No hay expedientes. Crear expediente")
3. **Error state**: Qué pasó + qué hacer + botón reintentar
4. **Success/Data**: El estado normal con datos

---

## 6. Checklist Pre-Entrega de UI

Antes de marcar cualquier feature de UI como terminada, verificar cada punto con
valores operativos concretos — no con criterios subjetivos como "se ve bien":

| Aspecto | Requisito operativo | Anti-patrón a evitar |
|---------|--------------------|-----------------------|
| **Iconos** | SVG de librería consistente (Heroicons, Lucide, Material Symbols). Un solo set por proyecto | Emojis como iconos funcionales — no se renderizan igual entre plataformas |
| **Cursores** | `cursor: pointer` en todo elemento clicable: botones, enlaces, toggles, tabs, cards clicables | Elementos clicables con cursor default — el usuario no sabe que puede interactuar |
| **Hover/Active** | Transición de 150–300ms. Hover muestra cambio visual; active muestra feedback de presión | Transiciones > 500ms (se sienten lentas) o 0ms (se sienten rotas) |
| **Contraste** | Texto normal 4.5:1, texto grande 3:1, componentes de UI 3:1 (WCAG 2.1 AA) | Texto gris claro sobre fondo blanco — falla contraste en todos los monitores |
| **Foco teclado** | `focus-visible` con anillo de 2px de contraste 3:1 contra el fondo. Tab order lógico | `outline: none` sin reemplazo — invisible para usuarios de teclado |
| **Movimiento** | `@media (prefers-reduced-motion: reduce)` desactiva animaciones no esenciales | Animaciones sin escape — usuarios con vértigo o epilepsia fotosensible |
| **Breakpoints** | Verificar en 375px (móvil), 768px (tablet), 1024px (laptop), 1440px (desktop) | Solo probar en 1 resolución — se rompe en el dispositivo del usuario |
| **Estados** | Loading (skeleton), empty, error (qué pasó + qué hacer), success — los 4 siempre | Solo el happy path — la primera interacción del usuario suele ser el empty state |
| **Touch targets** | Mínimo 44×44px de área táctil en móvil. Separación mínima de 8px entre targets | Botones de 24px — imposibles de presionar con precisión en pantalla táctil |

---

## Patrones de Referencia Completos

Para implementaciones de jerarquía visual (escala tipográfica), estados de UI
con código HTML/CSS, micro-interacciones, formularios UX, mobile first, y tabla
completa de anti-patrones UX, ver
[recursos/patrones-ux-referencia.md](recursos/patrones-ux-referencia.md).

## Gotchas / Errores comunes no obvios

**Los skeleton loaders que no coinciden con el layout real crean un "layout shift" perceptible al resolver**: si el skeleton muestra 3 líneas horizontales pero el contenido real es una tarjeta con imagen y botones, el usuario percibe un salto visual brusco al cargar. Causa: el skeleton debe ser una aproximación fiel del contenido real. Fix: construir el skeleton usando los mismos contenedores y proporciones del componente real, solo reemplazando el contenido con barras animadas — usar las mismas clases de grid/flex del componente original.

**Deshabilitar el botón de submit durante la validación de formulario frustran a usuarios mobile**: en dispositivos táctiles con teclado virtual, el usuario cierra el teclado y toca el botón — si el botón está deshabilitado porque el campo no pasó validación, el usuario no recibe feedback de por qué. Causa: la validación inline (campo por campo) no siempre es visible cuando el teclado oculta parte del formulario. Fix: permitir el submit siempre, mostrar todos los errores inline al enviar, y enfocar automáticamente el primer campo con error (`scrollIntoView()` + `focus()`).

**Mensajes de error genéricos ("Algo salió mal") bloquean al usuario más que los técnicos**: en producción es tentador mostrar mensajes genéricos para no exponer internos, pero el usuario no puede resolver un error sin saber qué hacer. Causa: confundir privacidad de implementación con utilidad del mensaje de error. Fix: separar el mensaje visible del usuario (qué pasó en términos de negocio + qué puede hacer) del log interno (detalles técnicos). El mensaje de error debe responder: ¿Qué pasó? + ¿Por qué? + ¿Qué hago ahora?

**El estado vacío (empty state) con solo texto "No hay resultados" no guía al usuario al siguiente paso**: el empty state es frecuentemente la primera pantalla que ve un usuario nuevo — si solo dice "No tienes facturas" sin una CTA clara, el usuario no sabe cómo empezar. Causa: el empty state se diseña como excepción en lugar de como estado de onboarding. Fix: el empty state debe tener: ícono/ilustración que contextualice, texto que explique qué puede hacer aquí, y un botón de acción primaria que lleve al siguiente paso ("Crear primera factura").
