Por qué necesitas un design system

Si trabajas en un proyecto que crece, tarde o temprano enfrentaras estos problemas:

  • 47 tonos diferentes de gris en tu CSS
  • Botones que se ven distintos en cada página
  • Un componente que tarda 2 horas en crear porque no hay patrones establecidos
  • Inconsistencias entre lo que disena el equipo de UX y lo que implementa el equipo de desarrollo

Un design system resuelve todo esto estableciendo reglas, tokens y componentes reutilizables. Y no necesitas ser una empresa grande para tener uno.

La arquitectura de tres niveles

Un design system bien estructurado tiene tres niveles de tokens, cada uno con un propósito específico.

Nivel 1: Tokens primitivos

Son los valores crudos: colores hexadecimales, tamaños en rem, nombres de fuentes. No tienen significado semántico. --primitive-ember-500 es un naranja, nada más.

Estos tokens nunca se usan directamente en componentes. Son el fundamento sobre el que se construye todo lo demas.

Nivel 2: Tokens semanticos

Asignan significado a los primitivos. --surface-primary no dice "gris claro", dice "el fondo principal de la aplicación". Esto permite que el mismo token tenga valores diferentes segun el tema.

Los tokens semanticos son los que más usas en tus componentes. Cuando escribes background: var(--surface-elevated), no importa si el tema es claro u oscuro; el valor correcto se resuelve automaticamente.

Nivel 3: Tokens de componente

Son variables locales de CSS que definen la API visual de un componente. El componente .btn define --btn-height, --btn-bg, etc., y sus variantes solo sobreescriben esos tokens sin duplicar estilos.

Implementando la escala de espaciado

Un espaciado consistente es lo que separa un diseño amateur de uno profesional. Usa una escala basada en multiplos:

:root {
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-6: 1.5rem;   /* 24px */
  --space-8: 2rem;     /* 32px */
  --space-12: 3rem;    /* 48px */
  --space-16: 4rem;    /* 64px */
  --space-24: 6rem;    /* 96px */
}

La regla: nunca uses valores magicos. Si necesitas margin-top: 1.25rem, preguntate por que no encaja en la escala. Generalmente la respuesta es que el diseño tiene una inconsistencia.

Sistema tipografico

Escala de tamaños

Define una escala tipografica con propósito:

:root {
  --text-xs: 0.75rem;    /* Labels, captions */
  --text-sm: 0.875rem;   /* Body small, metadata */
  --text-base: 1rem;     /* Body text */
  --text-lg: 1.125rem;   /* Body large */
  --text-xl: 1.25rem;    /* H4 */
  --text-2xl: 1.5rem;    /* H3 */
  --text-3xl: 1.875rem;  /* H2 */
  --text-4xl: 2.25rem;   /* H1 */
  --text-5xl: 3rem;      /* Display */
}

Line height por contexto

No uses un line-height global. Diferentes tamaños necesitan diferentes ratios:

:root {
  --leading-tight: 1.2;   /* Titulos */
  --leading-normal: 1.5;  /* Body text */
  --leading-relaxed: 1.75; /* Texto largo (blog) */
}

Componentes con tokens locales

La técnica más poderosa del design system es usar tokens locales en los componentes. En lugar de crear variantes duplicando estilos, defines la "API" del componente como custom properties y las variantes solo sobreescriben esos valores.

Mira el tercer bloque de código para ver como funciona con un componente .btn. Las variantes .btn--secondary y .btn--lg no repiten ningun estilo base; solo cambian los tokens que necesitan.

Ventajas de este patrón

  • Zero duplicacion: El estilo base se escribe una sola vez
  • Variantes triviales: Crear una nueva variante es sobreescribir 2-3 tokens
  • Themeable: Los tokens del componente pueden referenciar tokens semanticos
  • Debugging fácil: Inspeccionas un elemento y ves exactamente que tokens usa

Cards como caso de estudio

Las cards son el componente más comun en aplicaciones web. Así se implementa con el sistema de tokens:

.card {
  --card-padding: var(--space-6);
  --card-radius: var(--primitive-radius-lg);
  --card-bg: var(--surface-elevated);
  --card-border: var(--border-default);

  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--card-radius);
  padding: var(--card-padding);
  transition: border-color 150ms ease;
}

.card:hover {
  --card-border: var(--border-strong);
}

.card--compact {
  --card-padding: var(--space-4);
}

.card--glass {
  --card-bg: rgb(255 255 255 / 6%);
  backdrop-filter: blur(16px);
}

Responsive tokens

Para un diseño responsive, puedes cambiar tokens globales en media queries:

:root {
  --content-width: 90rem;
  --content-padding: var(--space-4);
  --section-gap: var(--space-8);
}

@media (min-width: 768px) {
  :root {
    --content-padding: var(--space-8);
    --section-gap: var(--space-16);
  }
}

@media (min-width: 1280px) {
  :root {
    --content-padding: var(--space-12);
    --section-gap: var(--space-24);
  }
}

Todos los componentes que usen estos tokens se adaptan automaticamente sin media queries propias.

Documentacion del design system

Un design system sin documentación es un repositorio de CSS. Documenta al menos:

Inventario de tokens

Crea una página que muestre todos tus tokens con sus valores y usos:

Token Light Dark Uso
--surface-primary #fafafa #0a0a0f Fondo principal
--surface-elevated #ffffff #1a1a28 Cards, modales
--text-primary #1a1a2e #f0f0f5 Texto principal
--interactive-primary #ff530f #ff6b35 Botones CTA

Catalogo de componentes

Para cada componente documenta:

  • Variantes disponibles
  • Tokens que acepta
  • Ejemplos de uso
  • Consideraciones de accesibilidad

Integracion con Angular

En Angular, puedes encapsular tus tokens en el styles.css global y usarlos en componentes con ViewEncapsulation.None para tokens globales, o directamente en estilos de componente para tokens locales:

@Component({
  selector: 'app-card',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="card" [class.card--compact]="compact()">
      <ng-content />
    </div>
  `,
  styleUrl: './card.css',
})
export class CardComponent {
  compact = input(false);
}

Errores comunes

Demasiados tokens

Si tienes --color-blue-100 hasta --color-blue-900 para 15 colores, tienes demasiados. Usa solo los que realmente necesitas. Un buen design system tiene 30-50 tokens semanticos, no 300.

Tokens sin usar

Revisa periodicamente y elimina tokens que no se usan. Un token muerto es ruido en el codebase.

Saltarse la capa semántica

Usar var(--primitive-gray-700) directamente en un componente rompe la tematicidad. Siempre pasa por un token semántico.

No documentar

Si otro desarrollador no puede entender tu sistema en 10 minutos, necesitas mejor documentación.

Conclusion

Un design system basado en CSS custom properties es poderoso, mantenible y no requiere ninguna dependencia externa. La arquitectura de tres niveles (primitivos, semanticos, componente) te da la flexibilidad de cambiar temas, crear variantes y escalar sin acumular deuda técnica.

Empieza pequeño: define tus colores, espaciado y tipografia como tokens. Luego ve construyendo componentes que los consuman. En unas semanas tendras un sistema que acelera tu desarrollo y mantiene la consistencia visual de tu producto.