Contexto y objetivos
NutriFlow unifica la experiencia de producto en web, Android e iOS bajo un sistema de diseño compartido basado en Material Design 3, garantizando consistencia visual, accesibilidad y velocidad de desarrollo.
Proporcionar a los equipos de RRHH y empleados una plataforma de nutrición corporativa que sea inmediatamente comprensible, visualmente calmante y funcionalmente eficiente, independientemente del dispositivo o plataforma de acceso.
Design Tokens
Los tokens son la única fuente de verdad para valores visuales. Se deben referenciar siempre por nombre semántico, nunca por valor crudo.
Paleta de color
Escala tipográfica
Escala de espaciado
Elevación y motion
Button
Elemento de acción primaria. Debe comunicar la intención con claridad, responder a todos los estados de interacción y ser operable desde teclado, puntero y toque.
Anatomía
Variantes
FILLED — acción primaria
OUTLINED — acción secundaria
TEXT — acciones terciarias o en cards
STATES — disabled · loading · danger
Especificación de estados
| Estado | Background | Color texto | Cursor | Comportamiento |
|---|---|---|---|---|
| default | --color-primary | --color-text-on-primary | pointer | Estático. Foco visible no activo. |
| hover | --color-primary-dark + shadow-md | --color-text-on-primary | pointer | State layer 8% opacidad. Transition 200ms ease-standard. |
| focus-visible | --color-primary | --color-text-on-primary | pointer | outline: 3px solid --color-secondary · offset: 2px. No suprimir con outline:none. |
| active / pressed | --color-primary-dark · escala 0.97 | --color-text-on-primary | pointer | Ripple centrado. Duración 120ms. |
| disabled | --color-outline-variant | --color-text-disabled | not-allowed | pointer-events:none · aria-disabled="true". No usar opacity global. |
| loading | --color-primary (opaco) | transparent (spinner visible) | wait | Spinner centrado. aria-busy="true" · aria-label describe acción en curso. |
Card
Contenedor de información relacionada. Permite tres variantes de elevación según la jerarquía visual necesaria. Hover debe ser perceptible pero no distractivo.
Dieta mediterránea para RRHH
1.800 kcal/día. Incluye opciones para intolerantes al gluten y veganos.
Rendimiento nutricional Junio
El 78% del equipo cumplió los objetivos de proteínas esta semana.
Ajuste de menú para semana 25
Basado en tus patrones, aumentar omega-3 en un 20% mejorará el foco.
| Variante | Cuándo usarla | Sombra | Borde |
|---|---|---|---|
| Filled | Contenido principal, listas de planes | shadow-sm · shadow-lg on hover | Ninguno |
| Outlined | Datos secundarios, listas densas | Ninguna | 1px --color-outline |
| Elevated | Destacados, recomendaciones, promos | shadow-lg · shadow-xl on hover | Ninguno |
WCAG 2.2 AA
Cada regla es testeable en code review. Se prioriza accesibilidad sobre estética cuando entran en conflicto.
Ratios de contraste verificados
Criterios exigibles (testeable en PR)
| ID | Nivel | Criterio | Cómo testear |
|---|---|---|---|
| A11Y-01 | must | Contraste texto normal ≥ 4.5:1 vs background | axe-core · Chrome Contrast Checker |
| A11Y-02 | must | Contraste texto grande (≥18px bold o ≥24px) ≥ 3:1 | axe-core · inspección manual |
| A11Y-03 | must | Focus ring visible en todos los elementos interactivos | Tab por la interfaz · CSS: outline nunca 0 sin sustituto |
| A11Y-04 | must | Botones con label descriptivo (no "click aquí") | Screen reader NVDA/VoiceOver · aria-label review |
| A11Y-05 | must | Cards interactivas con role="button" o elemento <button> | Inspección DOM · tabIndex explícito |
| A11Y-06 | must | Botón disabled: aria-disabled="true" sin pointer-events | Inspección atributos ARIA |
| A11Y-07 | should | Iconos decorativos con aria-hidden="true" | axe-core landmark review |
| A11Y-08 | should | Animaciones respetan prefers-reduced-motion | DevTools: emular prefers-reduced-motion |
Anti-patrones prohibidos
Implementaciones que degradan la accesibilidad, la consistencia o la claridad. Cada uno tiene un equivalente correcto.
Texto secundario sobre fondo claro sin verificar contraste. Color raw en vez de token.
Usar tokens semánticos verificados. El token garantiza ratio ≥ 4.5:1.
Suprimir el foco de teclado rompe la navegación para usuarios que no usan ratón.
Mantener foco visible siempre. Usar focus-visible para estilizar sin afectar mouse.
Hardcodear píxeles rompe el ritmo visual y dificulta el mantenimiento.
Siempre usar tokens de la escala 4/8/12/16/24/32.
Etiquetas genéricas pierden contexto para lectores de pantalla y usuarios cognitivos.
Label descriptivo de la acción y su objeto. Contexto explícito.
Checklist de revisión de código
Lista ejecutable durante code review. Cada ítem es verificable sin interpretación subjetiva.
-
Todos los colores usan
var(--color-*), no valores hex crudos grep ":#[0-9a-fA-F]" -
Espaciado en múltiplos de 4px usando tokens
--sp-*linting - Tipografía usa las familias designadas: Inter (body), Roboto (display), Fira Code (mono) visual
-
border-radius usa tokens
--radius-*grep
- Estado hover cambia background y sombra con transition 200ms hover
- focus-visible muestra outline 3px --color-secondary con offset 2px Tab key
- Botón disabled tiene aria-disabled="true" y cursor: not-allowed axe
- Estado loading muestra aria-busy="true" y spinner visible screen reader
- Label de botón describe acción + objeto (no "clic aquí") copy review
- Tamaño mínimo touch target ≥ 44×44px en mobile DevTools
- Card interactiva usa elemento semántico (<article> + role="button") o <button> axe
- Hover eleva sombra en 200ms sin salto visual abrupto visual
- Imagen de card tiene alt descriptivo, no vacío DOM inspect
- Estado vacío de card tiene mensaje explícito (no espacio en blanco) visual
- axe-core scan en 0 violaciones de nivel AA axe CI
- Flujo completo navegable con Tab / Shift+Tab sin trampas de foco manual
- prefers-reduced-motion: duración de transiciones reducida a ≤ 50ms DevTools emulation
- Contraste verificado con Chrome Devtools Accessibility panel DevTools