Lienzo de diseño
Diseñas pantallas como archivos HTML reales dentro del proyecto y las muestras en el visor de diseño local. El usuario ve cada pantalla lado a lado, cambia el tamaño del dispositivo y el tema claro/oscuro, exporta a PNG y comenta sobre una pantalla; los comentarios vuelven a ti como mensajes de chat con un prefijo exacto.
Archivos (el contrato)
design/
tokens.json la fuente única de verdad para cada token de diseño
(ambos temas); el único lugar donde viven los valores de marca
design-system.css GENERADO desde tokens.json: tokens de diseño para
[data-theme="light"] y [data-theme="dark"] (nunca editar)
utilities.css GENERADO desde tokens.json: el vocabulario cerrado de utilidades
(nunca editar)
design-system.md decisiones de marca en palabras (breve)
validate.mjs el validador (copiado una vez por proyecto — ver Configuración)
serve.mjs pequeño servidor estático para el visor (copiado una vez por proyecto)
viewer.html el visor (copiado una vez por proyecto)
mock.js entorno de ejecución simulado para pantallas interactivas (copiado una vez por proyecto)
mock.css estilos estáticos para las clases del entorno simulado (copiado una vez
por proyecto) — estados de toast/overlay/transición de entrada;
las pantallas lo enlazan como `../mock.css`; mock.js solo alterna
estas clases y nunca inyecta CSS
scripts/ copiado una vez por proyecto (ver Configuración)
gen-tokens.mjs regenera design-system.css + utilities.css desde tokens.json
sync-components.mjs rematerializa cada región marcadora de componente desde su parcial
(copiado una vez por proyecto)
marker-parser.mjs el analizador de gramática de marcadores compartido que sync importa en
tiempo de ejecución (copiado una vez por proyecto)
components/ registro de componentes + semilla de parciales (copiado una vez por
proyecto): components.json + un parcial por componente
vendor/html-to-image.js biblioteca de exportación a PNG (copiado una vez por proyecto)
index.json {"canvases": ["login", ...]} para que el visor pueda listarlos
<lienzo>/ una carpeta por lienzo, en kebab-case (login, dashboard)
canvas.json
data.json datos ficticios opcionales; objeto "scenarios" opcional
con anulaciones nombradas de nivel superior (vacío, crítico…)
01-<pantalla>.html un documento HTML completo por pantalla
assets/ imágenes/scripts locales opcionales
canvas.json (las pantallas aparecen en este orden):
{
"title": "Inicio de sesión de la app",
"screens": [
{ "id": "login", "name": "Inicio de sesión", "file": "01-login.html", "device": "mobile" },
{ "id": "registro", "name": "Registro", "file": "02-registro.html", "device": "mobile" }
]
}
device:mobile= 390×844,tablet= 834×1112,desktop= 1440×900; opcionalwidth/height(enteros 100–10000) lo anula.group(opcional): etiqueta que agrupa las pantallas en bloques titulados en la tira del visor — los proyectos complejos se mantienen legibles (p. ej.,"group": "Checkout").transition(opcional):fade,slide-leftonone(predeterminado). Es la animación de entrada de la pantalla después deMock.go— ver Paso 3 del flujo de trabajo para la regla mismo-lienzo/cruce-lienzo.idúnico y no vacío;nameno vacío;titleopcional.filees relativo a la carpeta del lienzo: nunca.., barra inicial/,\o un esquema (http:,file:…).
Configuración única por proyecto
Si design/ aún no existe, créalo y cópialo desde la carpeta de esta habilidad
(la carpeta que contiene este SKILL.md):
scripts/validate.mjs→design/validate.mjsassets/viewer.html→design/viewer.htmlassets/serve.mjs→design/serve.mjsassets/mock.js→design/mock.jsassets/mock.css→design/mock.css(estilos para las clases del entorno simulado; las pantallas enlazan../mock.css)assets/docs.html→design/docs.html(guía de uso, enlazada desde el botón 📘 Docs del visor)assets/vendor/html-to-image.js→design/vendor/html-to-image.jsscripts/gen-tokens.mjs→design/scripts/gen-tokens.mjsassets/components/→design/components/(registro + semilla de parciales)scripts/sync-components.mjs→design/scripts/sync-components.mjsscripts/marker-parser.mjs→design/scripts/marker-parser.mjs(el módulo analizador compartido que sync importa, requerido en tiempo de ejecución)scripts/export-tokens.mjs→design/scripts/export-tokens.mjs(la exportación de intercambio W3C/DTCG: tokens.json → tokens.w3c.json; artefacto derivado, nunca editado a mano)
Regla para esta lista de copia: solo los archivos que ya existen entran en ella ("só entra no
copy list arquivo que já existe"). Los archivos que aún faltan se unen solo en su
ola de Contratos: export-tokens.mjs se unió en la ola 6 de Contratos (todo 30) y está
listado arriba — la regla se cumple (el archivo existe desde todo 26).
(mock.css se unió en la ola 3 y está listado arriba).
Cada vez que tokens.json cambie, regenera los dos archivos generados desde la raíz del
proyecto:
node design/scripts/gen-tokens.mjs
Crea design/index.json ({"canvases": []}) y agrega cada nuevo nombre de lienzo
a él a medida que creas lienzos. Un ejemplo completo y válido vive en assets/example/
de la carpeta de esta habilidad — un sistema de aplicación de stock funcional en dos lienzos:
login/ (inicio de sesión, registro y un modal de confirmación de eliminación de cuenta abierto como
una superposición desde un enlace simple) y dashboard/ (resumen interactivo con una lista
larga de elementos, una actualización "Actualizar lista" en el mismo lienzo que demuestra la transición fade
y restauración de desplazamiento), donde el inicio de sesión y el registro navegan a través de
lienzos hacia el resumen, que lee sus elementos ficticios, admite escenarios con nombre,
y cierra sesión de vuelta al lienzo de inicio de sesión. Léelo antes de comenzar un nuevo sistema de diseño o lienzo y
adáptalo. La semilla example/components/ es una copia byte-idéntica de
assets/components/ ("example/components/ es copia byte-idéntica de
assets/components/ (fuente única)"): edita los parciales solo en assets/components/,
nunca en la copia de ejemplo.
Flujo de trabajo
- Primero el sistema de diseño. Lee
design/design-system.cssydesign/design-system.md. Si no existen, pide al usuario la marca (color primario, estilo de tipografía, tono; ofrece una paleta neutra como opción), luego crea ambos. Los lienzos posteriores los reutilizan. Cambia los tokens solo después de preguntar. - Pregunta solo lo que falta. Si la solicitud es vaga (qué pantallas, qué plataforma, qué datos), pregunta una vez; si es clara, comienza.
- Construye el lienzo. Lee primero
assets/craft.mdde la carpeta de esta habilidad (fusiona las habilidades hermanas — taste, emil-design-eng, impeccable — en reglas para las pantallas del lienzo) y aplícalo a cada pantalla. Luego creacanvas.jsony las pantallas. Reglas para cada pantalla:- Política de estilizado: el vocabulario de utilidades es el vocabulario. Cualquier cosa
respaldada por tokens (colores, tipo, espaciado, radio) pasa a través de las utilidades
generadas: enlaza
<link rel="stylesheet" href="../design-system.css">y<link rel="stylesheet" href="../utilities.css">, luego usa clases comobg-accent,p-2,text-heading,rounded-md. Las pantallas interactivas también enlazan<link rel="stylesheet" href="../mock.css">(las clases del entorno simulado: toast, overlay, transiciones de entrada). Las clases semánticas llevan estructura y diseño solamente.var(--…)sigue permitido donde ninguna utilidad encaja, y un bloque<style>en línea está permitido pero debe contener CERO colores literales. El barrido de prohibición busca colores literales en<style>,style=""y las posiciones de VALOR defill=/stroke=de SVG; también prohíbehttp(s)://en cualquier parte de las pantallas, clases de paleta de Tailwind comobg-zinc-900, y valores arbitrarios comotext-[13px]. - Trabaja en ambos temas a través de los tokens; el tema llega como
data-themeen<html>(lightpor defecto — incluye el atributo). - Sin CDN ni URL remota de ningún tipo (el lienzo está fuera de línea y en un entorno aislado):
iconos SVG en línea, fuentes del sistema o archivos de fuente bajo
design/, imágenes locales. - Texto real en el idioma del usuario (portugués brasileño por defecto) y datos de muestra plausibles — sin lorem ipsum.
- Cubre estados vacíos, de carga y de error cuando importen, como pantallas adicionales.
- Conceptos básicos de accesibilidad: etiquetas en entradas, foco visible, contraste suficiente, objetivos táctiles ≥ 44px en móvil.
- El diseño debe mantenerse en el ancho de dispositivo de la pantalla.
- Los componentes son instancias de parciales, nunca marcado de componente suelto
("instância usa partial, nunca markup solto de componente"). Envuelve cada
instancia en el par de marcadores
<!-- component:id size=md tone=primary state=default -->…<!-- /component:id -->con los TRES argumentos requeridossize=,tone=,state=(los valores deben estar en los enumerados del registro dedesign/components/components.json), y llena sus ranuras como marcadores emparejados<!-- slot:name -->…<!-- /slot:name -->. Precedencia: los argumentos del marcador son la fuente de verdad (marker-args-win). La sincronización reemitedata-size/data-tone/data-statey las clases variantes del marcador en cada ejecución; los contenidos de las ranuras y los atributosdata-*extra del usuario en la raíz sobreviven. - Haz que sea una vista previa del sistema, no un cartel. Cuando la solicitud implique un
producto funcional, conecta las pantallas con el entorno simulado
(
<script src="../mock.js"></script>, copiado por Configuración): los formularios validan y envían, los botones dan retroalimentación, las pantallas navegan conMock.go('03-dashboard.html'), los datos ficticios viven endata.jsondel lienzo (await Mock.data('items')), el estado del flujo (usuario conectado, elementos creados en el camino) vive enMock.state(sesión, con espacio de nombres por lienzo), y las acciones simuladas confirman conMock.toast('…'). Cada pantalla aún debe renderizarse como una composición estática si JS falla. El visor muestra un botón ↺ inicio en las tarjetas que navegaron y "⟲ Reiniciar flujo" para comenzar todo el flujo de nuevo. Cubre los estados que importan comoscenarioscon nombre endata.json(anulaciones de nivel superior, p. ej.,"vacio": {"items": []}) — el visor gana un selector para ellos, la elección sobrevive a la navegación, y cada escenario debe componerse bien (lista vacía, todos los elementos por debajo del mínimo, fallo de API). Un sistema puede abarcar lienzos (uno por flujo): navega a través de ellos conMock.go('../<lienzo>/<pantalla>.html')— el estado del flujo se comparte en todo el proyecto, así que el lienzo de inicio de sesión establece el usuario y el lienzo del dashboard lo lee. El selector de lienzo del visor salta entre lienzos (cada lienzo mantiene su propio escenario, tema y dispositivo). Los modales y los diálogos de confirmación también son pantallas completas del lienzo (una fuente de verdad): el disparador es un enlace de pantalla simple,<a href="03-modal.html">, que el entorno simulado intercepta enMock.overlay('03-modal.html')— sin JS, el href intacto navega a la propia pantalla del modal (el fallback sin JS). La navegación persistente (barra lateral, menú superior, pestañas) debe cambiar las pantallas de verdad: pondata-go="02-registro.html"en cada elemento (mantén unhref="02-registro.html"real en el mismo enlace como fallback sin JS — el entorno enrutadata-goaMock.go, preservando?scenario=y la transición de entrada). Los enlaces simples se reservan para disparadores de superposición (modales/detalles — un enlace de pantalla simple siempre abre una superposición); repite el mismo bloque de navegación en cada pantalla del lienzo y marca el elemento activo. Las pantallas pueden declarar"transition": "fade"|"slide-left"|"none"encanvas.json:Mock.goasigna una clase de entrada al destino (mock-enter-fade/mock-enter-slide-left, autoeliminada en 300 ms). La transferencia lee elcanvas.jsondel LIENZO ACTUAL coincidente con el nombre de archivo de destino, por lo que funciona para saltos en el mismo lienzo (una autonavegación comoMock.go('01-overview.html')es el patrón de actualización) — un cruce de lienzoMock.go('../<lienzo>/<pantalla>.html')es una navegación simple sin clase de entrada. La posición de desplazamiento se preserva por pantalla (scroll.<lienzo>.<archivo>en sessionStorage, restaurada cuando la pantalla regresa y sobreviviendo a ⟲ Reiniciar flujo, que limpia solomock.*).
- Política de estilizado: el vocabulario de utilidades es el vocabulario. Cualquier cosa
respaldada por tokens (colores, tipo, espaciado, radio) pasa a través de las utilidades
generadas: enlaza
- Validar y corregir. Sincronización OBLIGATORIA primero: después de editar cualquier parcial en
design/components/(o cualquier argumento de marcador), ejecutanode design/scripts/sync-components.mjsdesde la raíz del proyecto antes de presentar cualquier cosa; rematerializa cada instancia desde su parcial (marker-args-win).--checkes la forma de ejecución en seco: imprime un diffarchivo:líneapor región divergente y sale con 1 si hay divergencia (0 limpio), nunca escribe. Luego ejecuta desde la raíz del proyecto:node design/validate.mjs design/<lienzo>. Corrige cada problema que liste y ejecuta de nuevo hasta que solo quede la línea de resumen. Nunca presentes un lienzo que tenga problemas. El argumento del validador es una raíz de diseño (modo proyecto) o una sola carpeta de lienzo (modo lienzo); sin argumento, por defecto es./design. Las comprobaciones estructurales cubren solo las pantallas listadas encanvas.json; el modo proyecto adicionalmente comprueba la obsolescencia de tokens/CSS generado, componentes y comentarios. Las reglas de componentes se escanean en cada.htmlno exento, independientemente decanvas.json, con los códigoscomponent-unknown,component-variant,component-marker,component-divergenceyslot-marker.--allow-staleomite SOLO la comprobación de obsolescencia;--mark-stalees la única escritura del validador (marca pines de comentario cuyo ancla ha desaparecido);--example-inventoryes la comprobación del contrato de ejemplo (lista de archivos exacta deinventory.json+"_demo": trueen cada pin; sininventory.json= saltar, salir 0). 4b. Auditoría impecable. Después de validar, ejecuta la auditoría técnica de la habilidad hermanaimpeccableen el lienzo (instalado layout, win32):<skill-impeccable>/scripts/impeccable.cmd audit design/<lienzo>– la ruta se resuelve desde la instalada
…
[truncado para traducción]