Communitygithub.com

cdesiles/design-system

Construye un sistema de diseño como dos archivos CSS que otras aplicaciones pueden copiar: tokens.css (propiedades personalizadas) y components.css (clases basadas en ellos), documentados mediante una página de muestra. Léelo antes de diseñar cualquier cosa que vaya a tener más de una pantalla, y siempre que el proyecto no tenga un sistema existente.

¿Qué es design-system?

Esta skill permite construir un sistema de diseño completo y portable, generando dos archivos CSS que otras aplicaciones pueden copiar directamente: `tokens.css` (con propiedades personalizadas CSS) y `components.css` (con clases basadas únicamente en tokens semánticos). La documentación se materializa en una página de muestra (specimen) que declara todos los colores, tipografías, espaciados y componentes, asegurando que el sistema sea extensible, rebrandeable y consistente. Es útil para desarrolladores que trabajan con múltiples pantallas o equipos, ya que establece una base de diseño reutilizable sin dependencias de preprocesadores o herramientas de compilación. Está diseñada para cualquier proyecto web (React, HTML estático, etc.) y promueve reglas como el uso de Oklch para colores, escalas tipográficas y de espaciado, y la medición de contraste para accesibilidad. La skill también incluye verificación automática para evitar valores literales fuera de los tokens, y una estrategia de versionado semántico para mantener la consistencia entre actualizaciones.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/cdesiles/opencode-kit/tree/HEAD/skills/design-system

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Sistema de diseño

El sistema es el artefacto. Todo lo demás se construye a partir de él. Un entregable que inventa sus propios colores y espaciados es una pieza única; un entregable construido sobre tokens puede extenderse, renombrarse y mantenerse coherente.

Salida

Tres archivos, y la separación es el punto clave:

  • design/tokens.css — los tokens, y nada más. Propiedades personalizadas CSS simples.
  • design/components.css — los componentes, como clases construidas únicamente a partir de los tokens semánticos.
  • design/Design System.html — la página de muestra. Enlaza ambos archivos y los documenta. Solo documentación: no declara valores propios.

Los dos archivos CSS son el sistema: son lo que otras aplicaciones copian. La página de muestra permanece en el proyecto como su documentación.

Secciones en la página de muestra, en este orden:

  1. Intención — tres frases: para quién es, cómo debería sentirse, qué no es explícitamente.
  2. Color — cada muestra con su nombre de token, el valor al que resuelve y las combinaciones que pasan el contraste.
  3. Tipografía — familias, pesos, la escala con un rol nombrado por paso y un párrafo de muestra en tamaño de cuerpo.
  4. Espacio y forma — la escala de espaciado, radios, sombras, bordes.
  5. Componentes — cada uno renderizado en sus estados reales, junto con el marcado que una aplicación copia.
  6. Reglas — las cinco o seis decisiones que alguien podría tomar mal.
  7. Úsalo en una aplicación — la versión, los dos archivos a copiar, el orden de carga, el enlace de la fuente, la clase raíz y qué cambió desde la última versión.

Tokens

Dos capas. Los primitivos contienen valores brutos; los tokens semánticos nombran una tarea y apuntan a un primitivo. Los componentes solo hacen referencia a tokens semánticos — eso es lo que hace que un cambio de marca sea un cambio de una línea.

Escribe esto en design/tokens.css. Es el único archivo del proyecto donde puede aparecer un valor bruto. acme representa el prefijo del sistema (ver Compartir):

/* Sistema de diseño Acme 1.0.0 — tokens. Copia este archivo tal cual; cámbialo en su proyecto fuente. */
:root {
  /* primitivos */
  --acme-ink-900: oklch(0.22 0.02 260);
  --acme-ink-600: oklch(0.48 0.02 260);
  --acme-paper-50: oklch(0.99 0.005 90);
  --acme-paper-100: oklch(0.96 0.008 90);
  --acme-line-200: oklch(0.90 0.006 90);
  --acme-accent-500: oklch(0.55 0.14 35);
  --acme-accent-600: oklch(0.45 0.15 35);
  --acme-accent-100: oklch(0.94 0.03 35);

  /* semánticos */
  --acme-text: var(--acme-ink-900);
  --acme-text-muted: var(--acme-ink-600);
  --acme-bg: var(--acme-paper-50);
  --acme-surface: var(--acme-paper-100);
  --acme-border: var(--acme-line-200);
  --acme-accent: var(--acme-accent-500);
  --acme-accent-hover: var(--acme-accent-600);
  --acme-accent-wash: var(--acme-accent-100);

  /* tipografía */
  --acme-font-display: "Fraunces", Georgia, serif;
  --acme-font-text: "Public Sans", system-ui, sans-serif;
  --acme-step--1: 0.875rem;
  --acme-step-0: 1rem;
  --acme-step-1: 1.25rem;
  --acme-step-2: 1.5625rem;
  --acme-step-3: 1.953rem;
  --acme-step-4: 2.441rem;
  --acme-step-5: 3.052rem;

  /* espacio, sobre una base de 4px */
  --acme-s-1: 4px;  --acme-s-2: 8px;   --acme-s-3: 12px;  --acme-s-4: 16px;
  --acme-s-5: 24px; --acme-s-6: 32px;  --acme-s-7: 48px;  --acme-s-8: 64px;  --acme-s-9: 96px;

  /* forma y movimiento */
  --acme-radius-sm: 4px; --acme-radius: 8px; --acme-radius-lg: 16px;
  --acme-border-width: 1px; --acme-ring-width: 2px;
  --acme-shadow-1: 0 1px 2px oklch(0.2 0.02 260 / 0.06);
  --acme-shadow-2: 0 4px 16px oklch(0.2 0.02 260 / 0.08);
  --acme-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --acme-dur: 160ms;
}

Ese bloque es un punto de partida, no una plantilla para copiar ciegamente. Cambia el tono del acento, la combinación tipográfica y la calidez de la tinta para que coincida con el resumen, pero mantén la estructura.

Reglas para los tokens

  • El contraste se mide, no se calcula a ojo. Texto de cuerpo 4.5:1 contra su fondo real; texto grande y bordes de UI 3:1. Cada página de muestra indica sus combinaciones.
  • Oklch, no hex aleatorio. Los pasos uniformes de luminosidad evitan que las paletas se vean embarradas. Mantén el croma aproximadamente constante dentro de una familia de tonos.
  • Sin tokens no usados. Si nada referencia un token, elimínalo.
  • Sin valores fuera de este archivo. Un hex, literal oklch(), tamaño en px o sombra en cualquier otro lugar es un token que aún no se ha nombrado.
  • Dos familias tipográficas. Una de visualización, otra de texto. Las pilas de respaldo deben ser reales, no solo sans-serif.
  • Escala, no improvises. Si un valor no está en la escala de espaciado o tipográfica, agrégalo deliberadamente o usa el más cercano.
  • Modo oscuro solo si se pide — pero mantén los colores semánticos para que agregarlo después sea un intercambio de tokens, no una reescritura.

Componentes

Escríbelos en design/components.css, y renderiza cada uno en la página de muestra en los estados predeterminado, hover, foco, activo y deshabilitado donde apliquen:

  • Botón — primario, secundario, ghost. Un tamaño suele ser suficiente.
  • Entrada de texto y select, con etiqueta, texto de ayuda y estado de error.
  • Tarjeta, con un ejemplo de contenido real, no "Lorem ipsum".
  • Navegación, tanto en escritorio como en ancho reducido.
  • Fila de tabla o lista con un encabezado.
  • Insignia y etiqueta.
  • Modal o diálogo.
  • Estado vacío.
  • Toast o aviso en línea.

Cada componente usa solo tokens semánticos. Si un componente necesita un valor que no tiene token, eso es una brecha en el sistema — agrega el token, no codifiques el valor.

/* Sistema de diseño Acme 1.0.0 — componentes. Necesita tokens.css de la misma versión, cargado primero. */

.acme {
  font-family: var(--acme-font-text);
  font-size: var(--acme-step-0);
  color: var(--acme-text);
  background: var(--acme-bg);
}

.acme-button {
  font: inherit;
  padding: var(--acme-s-2) var(--acme-s-4);
  border: var(--acme-border-width) solid transparent;
  border-radius: var(--acme-radius);
  background: var(--acme-accent);
  color: var(--acme-bg);
  transition: background var(--acme-dur) var(--acme-ease);
}
.acme-button:hover { background: var(--acme-accent-hover); }
.acme-button:focus-visible { outline: var(--acme-ring-width) solid var(--acme-accent); outline-offset: var(--acme-ring-width); }
.acme-button--ghost { background: transparent; color: var(--acme-accent); border-color: var(--acme-border); }

Compartir

Otras aplicaciones toman el sistema copiando tokens.css y components.css. Las reglas a continuación son lo que permite que una copia funcione en cualquier lugar.

  • Prefíjalo todo. Elige un nombre corto para el sistema antes del primer token y ponlo en cada propiedad personalizada y cada clase: --acme-accent, .acme-button. Las copias entonces se colocan junto al CSS propio de la aplicación sin colisiones. El prefijo es parte de la API; nunca lo cambies.
  • CSS simple en ambos archivos. Sin directivas de Tailwind, sin sintaxis de preprocesador, sin anidamiento, sin requisito de @layer, sin @import entre ellos. Una aplicación React, una página estática u otra herramienta de diseño debe obtener resultados idénticos con una copia directa.
  • Todo se resuelve en tiempo de ejecución. Sin matemáticas de color en tiempo de compilación, sin salida compilada.
  • Nada global en components.css. Sin resets, sin selectores de elementos, nada en html o body: incluir el archivo en una aplicación no debe reestilizarla. Los estilos de texto base viven en la clase raíz, .acme, que una aplicación agrega donde los quiera.
  • Los estados vienen del marcado. Estiliza :hover, :focus-visible, :disabled, [aria-invalid="true"], [aria-current] y [aria-expanded] en lugar de clases de estado que una aplicación tendría que alternar, para que los componentes funcionen con cualquier HTML de framework.
  • Fácil de sobrescribir. Una clase por regla cuando sea posible, sin IDs, sin !important.
  • Una versión para ambos archivos. La primera línea de cada uno nombra el sistema y su versión; aumentala en cada cambio, en ambos. Parche para un valor cambiado, menor para un nuevo token o componente, mayor para una eliminación. Renombra agregando el nuevo token y manteniendo el antiguo como un alias, --acme-old: var(--acme-new);, hasta que las aplicaciones se hayan movido; eliminar el alias es el aumento mayor.
  • Las cosas del proyecto se quedan en la página de muestra. Las etiquetas <link> de fuentes, anchos de contenedor y rutas de activos no son tokens. La página de muestra muestra el enlace de la fuente para que una aplicación pueda copiarlo con los archivos.

Si el proyecto destino ya tiene un archivo de tokens, iguala su nomenclatura antes de inventar la tuya. Un vocabulario compartido vale más que un nombre mejor.

Página de muestra

La página de muestra es documentación para humanos, no una galería de componentes para admirar. Muestra el nombre del token junto a la muestra. Muestra cada componente con el marcado que una aplicación copia. Señala los estados que son difíciles de ver (anillos de foco, deshabilitado).

Enlaza ambos archivos, primero los tokens, y pon la clase raíz en <body>. Usa la tipografía y el espaciado del propio sistema para diseñar la página de muestra — es la primera prueba de que el sistema funciona.

Lee los valores del archivo en lugar de escribirlos, para que la documentación no pueda desviarse:

<link rel="stylesheet" href="tokens.css">
<link rel="stylesheet" href="components.css">
…
<body class="acme">
<figure class="swatch" data-token="--acme-accent-500"></figure>
…
<script>
  for (const el of document.querySelectorAll('[data-token]')) {
    const name = el.dataset.token;
    const value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
    el.dataset.value = value;                // impreso por CSS
    el.style.setProperty('--swatch', value); // pintado por CSS
  }
</script>

La muestra se pinta a sí misma desde el token e imprime el valor que el navegador resolvió. Un hex escrito a mano es una mentira futura.

Finalización

Ejecuta design-verify en la página de muestra. Enumera cualquier literal de color en la página de muestra o en components.css; no debería haber ninguno. Verifica que cada etiqueta de muestra sea legible, que cada componente esté alineado con la misma cuadrícula base y que ningún texto de muestra desborde su contenedor a 1024px de ancho.

Cuando el sistema vaya a otra aplicación, copia tokens.css y components.css sin cambios, más el enlace de la fuente de la página de muestra — no la página de muestra en sí. Exporta una copia independiente de la página de muestra solo si necesita ser leída en algún lugar sin la carpeta.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Skills relacionados