Are you the author? Sign in to claim
Deja de pedirle algo bonito a tu agente. Dale un contrato. · Contrato de diseño + gate ejecutable para Claude Code
Tu agente no falla por falta de capacidad. Falla por falta de criterio. Cuando le pides "una landing moderna", te entrega la mediana estadística de todo lo que vio en su entrenamiento. Esa mediana tiene nombre: Inter, indigo, radio 16px, hero centrado, tres cards con icono.
criterio no te da UI bonita. Te da un contrato verificable que el agente lee
antes de escribir la primera línea de componente — y un gate que falla con exit 1
cuando el contrato se rompe.
[!NOTE] Cero dependencias. Cero build. Cero API keys. Un solo requisito: Node 18+. Todo lo que hace son scripts de Node y archivos de texto que tu agente lee.
Dos puertas, según lo que te trajo. Ninguna de las dos requiere instalar nada para empezar a leer.
| Empieza en | Para qué sirve | |
|---|---|---|
| "¿cuántas señales tiene la tuya?" | Las 7 señales → | Auditas tu web a ojo en 10 minutos. Cada señal trae el umbral exacto que usa el gate y el fix de una línea. Sin instalar nada. |
| "pídele la UI por su nombre" | Kit de nombres de UI → | ~30 componentes: "los puntitos del carrusel" → pagination dots → la línea exacta para pedírselo a tu agente. |
Cuando quieras que lo mida un script en vez de tus ojos, sigue al Quickstart: son dos comandos.
Mismo prompt, mismo modelo, mismo día. Lo único que cambia es si existe un contrato.
| 🔴 Sin contrato · "un dashboard moderno para mi SaaS" | 🟢 Con contrato · el agente leyó brand.json primero |
|---|---|
|
hljs language-yaml Correcto. Accesible. Anónimo. No hay una decisión adentro: hay siete defaults que nadie eligió. |
hljs language-yaml La diferencia no es gusto. Es que en el segundo caso hay algo contra qué fallar. |
No es magia ni un modelo más listo. Es un archivo que el agente no puede ignorar y un script que lo verifica. Cuatro pasos, y el tercero es el que hace el trabajo.
Los tells son siempre los mismos y ya están documentados:
La causa raíz es de corpus, no de gusto. Adam Wathan se disculpó públicamente en X
(agosto 2025) por haber hecho que cada botón de Tailwind UI — la librería de
componentes de pago, no Tailwind CSS core — fuera bg-indigo-500 cinco años atrás,
"leading to every AI generated UI on earth also being indigo".
[!TIP] El modelo no elige morado porque el morado sea bueno. Lo elige porque es estadísticamente común en el corpus. Te está dando la mediana, y la mediana no es una decisión.
→ Detalle completo y fuentes en docs/01-por-que-todo-se-ve-igual.md
Menos de 5 minutos y no hace falta saber programar. Lo único que se necesita:
node --version. Si el comando no existe
o el número es menor a 18, instálalo desde nodejs.org (el
botón grande, la versión LTS) y vuelve aquí.git --version. En Mac, si no está, la terminal te
ofrece instalarlo sola.git clone https://github.com/Carlos-Dominguez-faber/criterio.git
cd criterio
npx criterio init
Son 8 preguntas y ninguna es técnica: qué producto es, para quién, qué sensación debe transmitir, cuál de las 5 direcciones visuales te queda más cerca, tu color de marca si ya tienes uno, dónde se usa (móvil / escritorio), en qué dialecto habla el producto, y cuánto hype aguanta el copy del 1 al 5. Enter deja el valor sugerido. Los hex, los radios y las duraciones los deriva el script: nadie te va a preguntar por tu escala de border-radius.
Al terminar tienes cinco archivos nuevos en la carpeta: brand.json, voice.json,
motion.json, brand.css y COMPONENT_RULES.md.
Si solo quieres ver la forma de todo sin responder nada:
npx criterio init --yes.
npx criterio gate
Esto es lo único del quickstart que hay que aprender a mirar, y son tres cosas.
a. La última línea manda.
PASS — 8/8 checks. El contrato esta limpio.
FAIL — 6/8 checks. Falla: forbidden_colors, restricted_hues.
PASS significa que tu contrato es coherente consigo mismo y no arrastra los
defaults del modelo. No significa que tu diseño sea bueno: eso sigue siendo tuyo.
FAIL no rompe nada de tu proyecto, solo te dice qué contradicción quedó dentro.
b. Cada check falla con tres renglones, y el que importa es el primero.
[FAIL] Colores prohibidos forbidden_colors
real: primary=#6366F1 (Color de marca), accent=#1F5EDA (Azul de enlace)
esperado: ninguno en la lista prohibida (#6366F1, #8B5CF6, #A855F7)
Cambia primary=#6366F1 por un hex fuera de la lista. Elige el
color desde la marca, no desde el default del modelo: si no sabes
cual, toma el preset de presets/presets.json que mas se parezca a
tu posicionamiento.
real: es lo que hay de verdad en tu contrato. esperado: es la regla. El párrafo
amarillo es el fix concreto, ya escrito: se lo puedes pegar a tu agente tal cual.
Nunca vas a ver un "algo está mal" sin el número que lo provocó.
c. Arreglas y vuelves a correr.
Abre brand.json, cambia el valor que el gate te nombró —casi siempre es un hex,
un número o una entrada de una lista—, guarda y corre npx criterio gate otra vez.
El ciclo dura segundos porque no hay build, no hay red y no hay modelo opinando.
[!NOTE] ¿Ya tienes un proyecto y quieres el contrato adentro? Corre la entrevista apuntando a tu carpeta y verifica ahí mismo:
hljs language-bashnode /ruta/a/criterio/scripts/init.mjs --dir /ruta/a/mi-proyecto node /ruta/a/criterio/scripts/gate.mjs /ruta/a/mi-proyectoEl check
animated_props_safees el único que lee tu código en vez del contrato: hace grep sobre tus.css,.tsxy.jsxbuscando transiciones sobre propiedades que causan reflow. Corre el gate desde la raíz del proyecto para que las encuentre.
Y el paso que no es comando:
[!IMPORTANT] Abre Claude Code y dile: "Lee
brand.jsonyCOMPONENT_RULES.mdantes de escribir cualquier componente." Ese es el mecanismo entero. El contrato solo funciona si el agente lo lee primero.
node scripts/test.mjs
# ✔ las 4 plantillas parsean como JSON
# ✔ la fórmula de contraste WCAG da 21:1 en negro sobre blanco
# ✔ los 5 presets generan contratos que pasan su propio gate
# ✔ el gate FALLA con el indigo #8B5CF6 y con transition: all
#
# PASS — 17 ok, 0 fallando
Las mismas 17 comprobaciones corren en CI en cada push — ese es el badge test
de arriba. Si está verde, el quickstart funciona desde el repo real, no solo en
mi máquina.
| Archivo | Qué contiene | Quién lo lee |
|---|---|---|
brand.json | El mismo contrato tipado: tokens, component_rules, anti_slop, validation | Claude Code y gate.mjs |
voice.json | El gemelo verbal: dialecto, ejes de tono, avoid_words[], safe_words[], cta_style | El agente cuando escribe copy |
motion.json | Duraciones nombradas, easings, safe_props / unsafe_props, reduced_motion | El agente cuando anima, y el gate |
brand.css | Los tokens compilados en 3 niveles: primitivos → semánticos → componente | El navegador |
COMPONENT_RULES.md | Las reglas en prosa que el agente relee antes de cada componente | El agente, en cada sesión |
init.mjs escribe esos cinco. La versión en prosa larga para pegarle a otro agente
(Cursor, Codex, v0) o mandársela a un cliente es templates/design.md:
es una plantilla que rellenas tú o la skill design-contract, no un archivo que el
script genere.
Ese brand.css no es una lista plana de colores. Sale en tres niveles, y las
referencias van en un solo sentido — así cambias la marca en un lugar y baja hasta
el último botón:
→ Por qué tres niveles y no uno, en docs/03-design-tokens-en-3-niveles.md
Los adjetivos no son verificables. "Que se vea moderno" no significa nada. Seis números del 1 al 5, cada uno con una frase que lo justifica, sí.
density · expression · geometry · warmth · editoriality · materiality
| Preset | D | E | G | W | Ed | M | Se parece a |
|---|---|---|---|---|---|---|---|
tech-utility | 4 | 2 | 2 | 2 | 2 | 2 | Linear, Vercel |
editorial-monocle | 2 | 3 | 1 | 3 | 5 | 2 | Monocle |
warm-soft | 2 | 4 | 4 | 5 | 3 | 3 | Mailchimp |
craft-tool | 4 | 3 | 3 | 3 | 2 | 4 | Figma, Raycast |
loud-statement | 3 | 5 | 5 | 3 | 4 | 5 | MSCHF |
Las marcas de referencia son calibración, no objetivo. Sirven para que dos personas
discutan si expression: 4 es demasiado, que es exactamente la conversación que
"hazlo moderno" impide tener.
→ Los 6 ejes explicados uno por uno en docs/02-los-6-ejes.md
npx criterio gate corre checks binarios contra tu contrato.
Sin LLM, sin red, sin ambigüedad. Exit 0 pasa, exit 1 falla.
Salida real del check de hue cuando pones #6366F1 como primary:
[FAIL] Zona de hue restringida restricted_hues
real: primary=#6366F1 (Indigo) → hue 239° · arquetipo Caregiver
esperado: hue fuera de [235, 285] o excepcion explicita
El hue 239° cae en la zona morado/indigo, que es el default
estadistico de todo modelo. Elige un primary fuera de [235, 285].
Si el morado es una decision real y no una inercia, declara el
arquetipo "Magician" o agrega "purple_as_primary" a
brand.archetype.allowed_behaviors — y justifica por que.
────────────────────────────────────────────────────────────────────────
FAIL — 6/8 checks. Falla: forbidden_colors, restricted_hues.
Arregla el contrato y vuelve a correr el gate. Exit 1.
Los 8 checks, todos binarios y sin opinión:
| # | Check | Falla cuando… |
|---|---|---|
| 1 | forbidden_colors | tu acento es #6366F1, #8B5CF6 o #A855F7 (los defaults de todo modelo) |
| 2 | restricted_hues | el hue del primary cae en [235, 285] sin excepción declarada |
| 3 | contrast_body | el texto de cuerpo no llega a 4.5:1 contra su fondo real (WCAG AA) |
| 4 | max_fonts | hay más familias tipográficas que las que declaraste |
| 5 | max_radius_values | existen más de 3 valores de radio distintos |
| 6 | archetype_coherence | el arquetipo contradice el tono — un Sage con hype: 4 |
| 7 | animated_props_safe | animas width, top, padding… (causan reflow), incluido transition: all |
| 8 | anti_slop_patterns | faltan patrones prohibidos declarados en el contrato |
[!WARNING] El check 6 es el que separa un linter de un contrato: valida coherencia entre dos archivos (
brand.json×voice.json), no valores sueltos. El check 7 convierte una regla de performance en un dato verificable. Eso es el punto entero: el buen gusto no se pide, se testea.
→ Los 8 checks, uno por uno, en skills/design-audit/references/checklist.md · la implementación vive en scripts/lib/checks.js
Escritas desde cero, MIT, en español. Viven en skills/ y se copian a ~/.claude/skills/.
| Skill | Qué hace |
|---|---|
design-contract | Corre la entrevista de 8 preguntas, elige preset y escribe los cuatro archivos de contrato + brand.css + COMPONENT_RULES.md. |
design-audit | Lee tu contrato, corre gate.mjs y traduce cada fallo a lenguaje humano con el fix concreto. Si no hay contrato, propone crear uno. |
ui-vocabulary | Glosario ES↔EN de componentes y estilos. Describes "los puntitos del carrusel" y sales con el nombre correcto más el brief para el agente. |
La diferencia con los auditores de terceros: hallmark audit y /impeccable audit
juzgan tu UI contra su criterio. design-audit la juzga contra tu contrato.
Esa es la distinción que hace que el alumno aprenda a decidir en vez de a obedecer.
criterio enlaza, nunca copia. Cero código ajeno vendorizado en este repo —
así la atribución queda clara, la licencia intacta y nada envejece en dos semanas.
| Recurso | Autor | Licencia | Comando oficial |
|---|---|---|---|
| hallmark | Nutlope / Together AI | MIT | npx skills add nutlope/hallmark |
| emilkowalski/skills | Emil Kowalski | MIT | npx skills@latest add emilkowalski/skills |
| impeccable | Paul Bakaus | Apache-2.0 | /plugin marketplace add pbakaus/impeccable |
| frontend-design | Anthropic | sin SPDX declarado en el repo — revisa el LICENSE antes de trabajo de cliente | /plugin marketplace add anthropics/claude-plugins-official/plugin install frontend-design@claude-plugins-official |
| ui-skills | Julien Thibeaut | MIT | npx ui-skills start |
| interface-design | @Dammyjay93 | MIT | sin instalador oficial confirmado: git clone y copia a ~/.claude/skills/ |
| web-animation-skills | iart-ai | MIT declarada en el hub iart-ai/motion-skills (no verifiqué el LICENSE del pack) | npx skills add iart-ai/web-animation-skills |
Más los recursos de navegador sin instalación (NameThatUI, Kinetics) y —lo más importante— qué dejamos fuera y por qué.
→ Todo el detalle en curated/README.md · comandos comentados en curated/install.sh
Al terminar cualquier build, pega esto en Claude Code:
Revisa la UI que acabas de escribir contra estas 10 preguntas.
Responde cada una con SÍ/NO y, si es NO, con el fix concreto en una línea.
1. ¿Cada color que usaste está en brand.json? ¿Alguno tiene hue entre 235 y 285?
2. ¿Cuántas familias tipográficas hay en pantalla? ¿Alguna se usó en un contexto
que su avoid_for[] prohíbe?
3. ¿Cuántos valores de border-radius distintos existen? ¿Más de 3?
4. ¿El texto de cuerpo pasa 4.5:1 de contraste contra su fondo real?
5. ¿Hay jerarquía visual más allá de "texto más grande = título"?
6. ¿Alguna transición anima width, height, padding, margin, top, left, right o
bottom? Esas causan reflow.
7. ¿Las entradas usan ease-out y las salidas ease-in? ¿Algún feedback de
interacción pasa de 200ms?
8. ¿Existe una regla de prefers-reduced-motion?
9. ¿El copy contiene alguna palabra de voice.json avoid_words[]?
10. ¿Los inputs tienen indicador de campo requerido y estado de error visible?
→ Versión larga, con el porqué de cada pregunta, en checklists/ui-review.md
→ Cómo se ve un prompt de UI que sí funciona: checklists/prompt-anatomy.md
Esta sección es la que separa un regalo serio de una promesa inflada. Léela antes de instalar nada.
No te va a dar buen gusto. criterio hace que tus decisiones sean explícitas y
consistentes. Si eliges mal los seis ejes, vas a obtener una UI consistentemente
mala. El contrato amplifica criterio; no lo sustituye.
No elimina el AI slop. Lo reduce. El gate atrapa lo numéricamente verificable: hues, contrastes, conteos de radios y de fuentes, props inseguras animadas. No atrapa un layout aburrido ni una idea perezosa. Nadie que te prometa "elimina el slop" te está diciendo la verdad.
No mira tu pantalla. gate.mjs es un script de Node sin navegador y sin LLM.
Lee tu contrato y hace grep sobre tus archivos. No renderiza, no toma screenshots
y no juzga composición. Si quieres verificación visual, eso lo dan otras
herramientas (el loop deliver-and-verify de web-animation-skills, o
chrome-devtools-mcp), no esta.
No es un design system. No hay componentes, no hay librería, no hay npm install. Si lo que necesitas es un sistema de producción con 150+ componentes accesibles, eso es otra categoría de herramienta.
No garantiza accesibilidad. El gate revisa contraste de texto de cuerpo y poco más. No audita roles ARIA, foco, orden de tabulación, lectores de pantalla ni targets táctiles. Pasar el gate no significa que tu UI sea accesible.
No sobrevive a un agente que no lee el contrato. Si abres una sesión nueva y no
le dices que lea brand.json, el agente vuelve a la mediana. La persistencia entre
sesiones no está resuelta aquí; es el problema que ataca el eje memory de
interface-design, y vale la pena que lo mires.
No hace magia con motion. Te da duraciones y curvas nombradas. Que la animación
se sienta bien sigue dependiendo de ti — para eso está el material de Emil Kowalski
enlazado en curated/.
Los ejes son un modelo, no la verdad. Seis números no describen el diseño. Son una herramienta de conversación lo bastante buena para que dos personas discutan algo concreto. Trátalos así.
criterio es MIT. Copyright (c) 2026 Carlos Domínguez.
Todo lo que está en skills/, scripts/, templates/, presets/, docs/ y
checklists/ está escrito desde cero para este repo.
Nada de curated/ está copiado aquí. Crédito completo a sus autores, cada uno bajo
su propia licencia:
anthropics/skills, sin SPDX estándar declaradoiart-ai/motion-skillsFuentes citadas y sus precisiones — incluida la de Tailwind UI vs Tailwind CSS core,
el estatus del formato de design tokens como especificación del Community Group del
W3C (no estándar W3C), y que Theo está archivado mientras el equivalente vivo es
Style Dictionary — están en docs/99-fuentes.md.
criterio salió de una clase de Imperio Agéntico, la comunidad de educación
técnica en IA y automatización donde enseño La Forja: la metodología de
desarrollo multi-agente con Claude Code de la que este repo es un pedazo.
Si algo de aquí te falla, te sobra o te falta, ábreme un issue. El repo mejora con los casos reales de quien lo usa.
git clone https://github.com/Carlos-Dominguez-faber/criterio.git && cd criterio && npx criterio init
Después: npx criterio gate. Eso es todo.
1000+ skills curated from Anthropic, Vercel, Stripe, and other engineering teams
Agent harness performance optimization with skills, instincts, memory, and security
Design enforcement with memory — keeps your UI consistent across a project
Detects 37 AI writing patterns and rewrites text with human rhythm across 5 voice profiles