---
name: design-tokens
description: Design tokens y sistemas de diseño. Cubre definición de tokens (color, tipografía, espaciado, sombras, bordes), formatos (JSON, YAML, CSS custom properties), tokens semánticos vs primitivos, theming (light/dark/brand), transformación con Style Dictionary, integración con Tailwind/CSS-in-JS/Angular Material y versionado.
version: "1.0.0"
herramientasPermitidas: [Read, Grep]
evolvable: true  # default para skill estandar
exclusiones:
  - "No cargar para implementar componentes UI concretos (botones, formularios, cards) — para componentes cargar `angular-moderno`, `react-experto` o el skill del framework."
  - "No cargar para configuración de Tailwind CSS sin sistema de tokens — para Tailwind sin design system cargar `tailwind-experto`."
  - "No cargar para diseño responsivo (breakpoints, container queries, layout adaptativo) — para responsivo cargar `diseno-responsivo`."
  - "No cargar para accesibilidad de color (contraste, daltonismo) — los tokens definen los colores, pero la validación de accesibilidad corresponde a `accesibilidad-a11y`."
---
# Design Tokens y Sistemas de Diseño

## Cuándo NO cargar

- La tarea es implementar componentes UI concretos (botones, inputs, cards): cargar el skill del framework (`angular-moderno`, `react-experto`).
- La configuración es de Tailwind CSS sin un sistema de tokens formal: cargar `tailwind-experto`.
- El trabajo es diseño responsivo (breakpoints, layout, container queries): cargar `diseno-responsivo`.
- La validación es de accesibilidad de color (ratios de contraste WCAG): cargar `accesibilidad-a11y`.

## Qué es un Design Token

Un design token es la unidad mínima de una decisión de diseño: un par nombre-valor
con semántica explícita. No es `#3b82f6` — es `color.marca.primario = #3b82f6`.

**Por qué importan**:
- Una sola fuente de verdad para diseñadores y desarrolladores
- Los cambios de tema afectan todos los consumidores automáticamente
- Los tokens semánticos aíslan los cambios de implementación

---

## Tipos de Tokens — Regla Fundamental

### Primitivos (base)

Valores crudos sin semántica de uso: `color.azul.500 = #3b82f6`, `espacio.4 = 16px`.

### Semánticos (decisión de uso)

Referencian primitivos y comunican propósito: `color.marca.primario = {color.azul.600}`.

**REGLA**: Los componentes SIEMPRE usan tokens semánticos, NUNCA primitivos directamente.

```css
/* MAL */
color: #3b82f6;

/* BIEN */
color: var(--color-marca-primario);
```

---

## Formato de Tokens

- **JSON**: formato W3C Design Tokens (estándar emergente) con `$value`, `$type`, `$description`.
- **YAML**: legible para humanos, bueno para edición manual.
- **CSS Custom Properties**: output generado automáticamente para web.

```css
:root {
  --color-marca-primario: var(--color-azul-500);
  --color-texto-primario: var(--color-gris-900);
  --espacio-componente-padding-md: var(--espacio-4);
}
```

---

## Theming: Light / Dark / Brand

- Tokens semánticos se sobreescriben por tema, primitivos no cambian.
- Usar `[data-tema="oscuro"]` para selector CSS del tema oscuro.
- Respetar `prefers-color-scheme: dark` con `:root:not([data-tema])`.
- Multi-tenant: sobreescribir `color.marca.*` por empresa.

---

## Transformación con Style Dictionary

- SIEMPRE generar tokens desde código, no mantener archivos manuales.
- Configurar platforms: `css`, `js` (con TypeScript declarations), `android`, `ios-swift`.
- Scripts: `tokens:build`, `tokens:watch`, `tokens:build:claro`, `tokens:build:oscuro`.

---

## Integraciones con Frameworks

### Tailwind CSS v4

Referenciar CSS vars generados en `@theme`:
```css
@theme {
  --color-primario: var(--color-marca-primario);
  --font-sans: var(--fuente-sans);
}
```

### Angular Material

Definir paleta desde tokens primitivos, usar en `define-light-theme`.

### CSS-in-JS

Objeto de tema que referencia CSS custom properties.

---

## Versionado de Tokens

```
MAYOR: Eliminar o renombrar tokens (breaking change)
MENOR: Agregar tokens, cambiar valores existentes
PARCHE: Correcciones de metadata sin cambio de valor
```

- SIEMPRE mantener CHANGELOG de tokens.
- Tokens deprecated: marcar con `"$deprecated": true` + mensaje de migración.
- NUNCA renombrar sin período de transición (alias del viejo al nuevo).

---

## Anti-patrones

| Anti-patrón | Corrección |
|-------------|------------|
| Primitivos directamente en componentes | Usar tokens semánticos |
| Tokens de un solo uso | No crear — usar valor directo |
| Sin documentación del propósito | `$description` en cada token |
| Cambiar primitivo sin evaluar cascada | Revisar todos los semánticos que lo referencian |
| Tokens en Figma que no existen en código | Sincronizar con Style Dictionary |
| Versionar sin CHANGELOG | Mantener changelog de tokens |

---

## Checklist

- [ ] Tokens primitivos definidos (color, espacio, tipografía, sombras, bordes)
- [ ] Tokens semánticos para cada decisión de uso
- [ ] Componentes usan semánticos, nunca primitivos
- [ ] Temas light/dark funcionan con `prefers-color-scheme`
- [ ] Style Dictionary configurado y genera automáticamente
- [ ] CHANGELOG de tokens actualizado
- [ ] Tokens deprecated marcados con `$deprecated`

Para definiciones completas de tokens, temas, configuración de Style Dictionary e integraciones, ver [recursos/tokens-y-configuracion.md](recursos/tokens-y-configuracion.md).

## Gotchas / Errores comunes no obvios

**Style Dictionary genera los archivos CSS pero los tokens semánticos no resuelven los primitivos en runtime**: Style Dictionary resuelve las referencias `{color.azul.500}` en tiempo de build y genera variables CSS con el valor literal. Si el token semántico se define como `var(--color-azul-500)` en lugar de que Style Dictionary lo resuelva, el valor literal no se embebe y depende de que ambas variables estén declaradas en el mismo scope CSS. Causa: confundir la resolución en build-time de Style Dictionary con la referencia en runtime de CSS custom properties. Fix: en Style Dictionary, usar la sintaxis de referencia `{color.azul.500}` (llaves, sin `var()`) para que el build resuelva el valor. Las `var()` solo aparecen en el CSS generado cuando se configura explícitamente la plataforma `css/variables`.

**Cambiar un token primitivo de valor afecta componentes que deberían estar aislados por el token semántico**: si un componente usa directamente `var(--color-azul-500)` en lugar de `var(--color-marca-primario)`, cambiar el valor del primitivo cambia ese componente aunque el primitivo sea de "base" y no debería afectar la interfaz. Causa: la regla "componentes solo usan semánticos" se rompe gradualmente cuando los desarrolladores toman atajos. Fix: establecer un lint de CSS que detecte el uso directo de tokens primitivos en componentes: buscar `var(--color-azul-` o `var(--espacio-` en archivos de componentes y rechazar en CI.

**El tema oscuro no aplica cuando el usuario tiene `prefers-color-scheme: dark` pero el sistema tiene `[data-tema="claro"]` forzado**: la prioridad de CSS hace que `[data-tema="claro"]` en el `<html>` gane sobre `@media (prefers-color-scheme: dark)` porque el selector de atributo tiene mayor especificidad. Causa: el override explícito del tema en el atributo HTML tiene precedencia sobre la media query del sistema operativo. Fix: es el comportamiento correcto cuando el usuario eligió explícitamente el tema en la app. Pero si el sistema no tiene selector de tema en `<html>`, agregar `:root:not([data-tema])` al selector de dark mode para que solo aplique cuando no hay tema forzado.

**Los tokens deprecated con `"$deprecated": true` siguen siendo usados por componentes porque el equipo de diseño los eliminó en Figma pero no en código**: el `$deprecated: true` es solo metadata en el JSON de tokens — no causa error en build ni lint. Los componentes siguen usando el token viejo sin ninguna advertencia visible. Causa: la deprecación de tokens es declarativa pero no hay enforcement automático. Fix: agregar un paso en el pipeline de Style Dictionary que genera una lista de tokens deprecated y un script de lint que verifica si algún archivo CSS/TS los referencia. Sin enforcement, los tokens deprecated nunca se eliminan.
