Canvas de Design
Você projeta telas como arquivos HTML reais dentro do projeto e as exibe no visualizador local de design. O usuário vê cada tela lado a lado, alterna o tamanho do dispositivo e o tema claro/escuro, exporta PNG e comenta em uma tela; os comentários voltam para você como mensagens de chat com um prefixo exato.
Arquivos (o contrato)
design/
tokens.json a única fonte da verdade para cada token de design
(ambos os temas); o único lugar onde os valores da marca vivem
design-system.css GERADO a partir de tokens.json: tokens de design para
[data-theme="light"] e [data-theme="dark"] (nunca editar)
utilities.css GERADO a partir de tokens.json: o vocabulário fechado
de utilitários (nunca editar)
design-system.md decisões da marca em palavras (curto)
validate.mjs o validador (copiado uma vez por projeto — consulte Configuração)
serve.mjs servidor estático pequeno para o visualizador (copiado uma vez por projeto)
viewer.html o visualizador (copiado uma vez por projeto)
mock.js runtime mock para telas interativas (copiado uma vez por projeto)
mock.css estilos estáticos para as classes do runtime mock (copiado uma vez
por projeto) — estados de toast/overlay/enter-transition;
as telas o referenciam como `../mock.css`; mock.js apenas alterna
essas classes e nunca injeta CSS
scripts/ copiado uma vez por projeto (consulte Configuração)
gen-tokens.mjs regenera design-system.css + utilities.css a partir de
tokens.json
sync-components.mjs rematerializa cada região de marcador de componente a partir de sua
partial (copiado uma vez por projeto)
marker-parser.mjs o parser de gramática de marcadores compartilhado que sincroniza importações em
tempo de execução (copiado uma vez por projeto)
components/ registro de componentes + semente de partials (copiado uma vez
por projeto): components.json + uma partial por componente
vendor/html-to-image.js biblioteca de exportação PNG (copiada uma vez por projeto)
index.json {"canvases": ["login", ...]} para que o visualizador possa listá-los
<canvas>/ uma pasta por canvas, em kebab-case (login, dashboard)
canvas.json
data.json dados fictícios opcionais; objeto "scenarios" opcional
com substituições nomeadas de alto nível (vazio, crítico…)
01-<tela>.html um documento HTML completo por tela
assets/ imagens/scripts locais opcionais
canvas.json (as telas aparecem nesta ordem):
{
"title": "Login do app",
"screens": [
{ "id": "login", "name": "Login", "file": "01-login.html", "device": "mobile" },
{ "id": "cadastro", "name": "Cadastro", "file": "02-cadastro.html", "device": "mobile" }
]
}
device:mobile= 390×844,tablet= 834×1112,desktop= 1440×900;width/heightopcionais (inteiros 100–10000) substituem.group(opcional): rótulo que agrupa as telas em blocos com título na faixa do visualizador — projetos complexos permanecem legíveis (ex.:"group": "Checkout").transition(opcional):fade,slide-leftounone(padrão). É a animação de entrada da tela apósMock.go— consulte a etapa 3 do Fluxo de trabalho para a regra de mesmo-canvas/entre-canvases.idúnico e não vazio;namenão vazio;titleopcional.fileé relativo à pasta do canvas: nunca.., barra inicial/,\ou um esquema (http:,file:…).
Configuração única por projeto
Se design/ ainda não existir, crie-o e copie da pasta desta skill
(a pasta que contém 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 as classes do runtime mock; as telas referenciam../mock.css)assets/docs.html→design/docs.html(guia de uso, vinculado ao botão 📘 Docs do visualizador)assets/vendor/html-to-image.js→design/vendor/html-to-image.jsscripts/gen-tokens.mjs→design/scripts/gen-tokens.mjsassets/components/→design/components/(registro + semente de partials)scripts/sync-components.mjs→design/scripts/sync-components.mjsscripts/marker-parser.mjs→design/scripts/marker-parser.mjs(o módulo do parser compartilhado que sincroniza importações, necessário em tempo de execução)scripts/export-tokens.mjs→design/scripts/export-tokens.mjs(a exportação de intercâmbio W3C/DTCG: tokens.json → tokens.w3c.json; artefato derivado, nunca editado manualmente)
Regra para esta lista de cópia: apenas arquivos que já existem entram nela ("só entra no
copy list arquivo que já existe"). Arquivos ainda por vir entram apenas em sua
onda de Contratos: export-tokens.mjs entrou na onda 6 de Contratos (todo 30) e está
listado acima — a regra é satisfeita (o arquivo existe desde o todo 26).
(mock.css entrou na onda 3 e está listado acima.)
Sempre que tokens.json mudar, regenere os dois arquivos gerados a partir da raiz do projeto:
node design/scripts/gen-tokens.mjs
Crie design/index.json ({"canvases": []}) e adicione cada novo nome de canvas
conforme você cria canvases. Um exemplo completo e válido vive na pasta
assets/example/ desta skill — um sistema funcional de aplicativo de estoque em dois canvases:
login/ (login, cadastro e um modal de confirmação de exclusão de conta aberto como
um overlay a partir de um link simples) e dashboard/ (visão geral interativa com uma longa
lista de itens, uma atualização "Atualizar lista" no mesmo canvas que demonstra a transição
fade e restauração de rolagem), onde login e cadastro navegam entre canvases
para a visão geral, que lê seus itens fictícios, suporta cenários nomeados
e faz logout de volta ao canvas de login. Leia-o antes de iniciar um novo sistema de design ou canvas e
a adapte. A semente example/components/ é uma cópia byte-idêntica de
assets/components/ ("example/components/ é cópia byte-idêntica de
assets/components/ (fonte única)"): edite partials apenas em assets/components/,
nunca na cópia de exemplo.
Fluxo de trabalho
- Sistema de design primeiro. Leia
design/design-system.cssedesign/design-system.md. Se eles não existirem, peça ao usuário a marca (cor primária, sensação da tipografia, tom; ofereça uma paleta neutra como uma opção), então crie ambos. Canvases posteriores os reutilizam. Altere os tokens apenas após perguntar. - Pergunte apenas o que está faltando. Se o pedido for vago (quais telas, qual plataforma, quais dados), pergunte uma vez; se estiver claro, comece.
- Construa o canvas. Leia primeiro
assets/craft.mdda pasta desta skill (ele funde as skills craft irmãs — taste, emil-design-eng, impeccable — em regras para telas do canvas) e aplique-o a cada tela. Então criecanvas.jsone as telas. Regras para cada tela:- Política de estilização: o vocabulário de utilitários é o vocabulário. Qualquer
coisa baseada em token (cores, tipo, espaçamento, raio) passa pelos utilitários
gerados: vincule
<link rel="stylesheet" href="../design-system.css">e<link rel="stylesheet" href="../utilities.css">, então use classes comobg-accent,p-2,text-heading,rounded-md. Telas interativas também vinculam<link rel="stylesheet" href="../mock.css">(as classes do runtime mock: toast, overlay, transições de entrada). Classes semânticas carregam estrutura e layout apenas.var(--…)permanece permitido onde nenhum utilitário se encaixa, e um bloco<style>embutido é permitido, mas deve conter ZERO cores literais. A varredura de proibição verifica cores literais em<style>,style=""e nas posições VALOR de SVGfill=/stroke=; ela também proíbehttp(s)://em qualquer lugar nas telas, classes de paleta Tailwind comobg-zinc-900e valores arbitrários comotext-[13px]. - Trabalhe em ambos os temas através dos tokens; o tema chega como
data-themeem<html>(lightpor padrão — inclua o atributo). - Nenhuma CDN ou URL remota de qualquer tipo (o canvas é offline e em sandbox):
ícones SVG embutidos, fontes do sistema ou arquivos de fonte em
design/, imagens locais. - Texto real no idioma do usuário (Português Brasileiro por padrão) e dados de amostra plausíveis — sem lorem ipsum.
- Cubra estados vazios, de carregamento e de erro quando eles importarem, como telas extras.
- Noções básicas de acessibilidade: rótulos em inputs, foco visível, contraste suficiente, alvos de toque ≥ 44px em mobile.
- O layout deve se ajustar à largura do dispositivo da tela.
- Componentes são instâncias de partials, nunca marcação de componente solta
("instância usa partial, nunca markup solto de componente"). Envolva cada
instância no par de marcadores
<!-- component:id size=md tone=primary state=default -->…<!-- /component:id -->com os TRÊS argumentos obrigatóriossize=,tone=,state=(os valores devem estar nos enums do registro dedesign/components/components.json), e preencha seus slots como marcadores pareados<!-- slot:nome -->…<!-- /slot:nome -->. Precedência: argumentos do marcador são a fonte da verdade (marcador-args-vence). A sincronização reemitedata-size/data-tone/data-statee as classes de variante a partir do marcador em cada execução; conteúdos dos slots edata-*extras do usuário no elemento raiz sobrevivem. - Faça uma prévia do sistema, não um pôster. Quando o pedido implicar um
produto funcional, conecte as telas com o runtime mock
(
<script src="../mock.js"></script>, copiado pela Configuração): formulários validam e enviam, botões dão feedback, telas navegam comMock.go('03-dashboard.html'), dados fictícios vivem nodata.jsondo canvas (await Mock.data('items')), estado do fluxo (usuário logado, itens criados ao longo do caminho) vive emMock.state(sessão, com namespace por canvas), e ações simuladas confirmam comMock.toast('…'). Cada tela ainda deve renderizar como uma composição estática se JS falhar. O visualizador mostra um botão ↺ início em cards que navegaram e "⟲ Reset fluxo" para recomeçar todo o fluxo. Cubra os estados que importam comoscenariosnomeados emdata.json(substituições de alto nível, ex.:"vazio": {"items": []}) — o visualizador ganha um seletor para eles, a escolha sobrevive à navegação, e cada cenário deve compor bem (lista vazia, todos os itens abaixo do mínimo, falha de API). Um sistema pode abranger canvases (um por fluxo): navegue entre eles comMock.go('../<canvas>/<tela>.html')— o estado do fluxo é compartilhado em todo o projeto, então o canvas de login define o usuário e o canvas de dashboard o lê. O seletor de canvas do visualizador pula entre canvases (cada canvas mantém seu próprio cenário, tema e dispositivo). Modais e diálogos de confirmação também são telas completas do canvas (uma única fonte da verdade): o gatilho é um link de tela simples,<a href="03-modal.html">, que o runtime mock intercepta emMock.overlay('03-modal.html')— sem JS o href intocado navega para a própria tela do modal (o fallback sem JS). A navegação persistente (barra lateral, menu superior, abas) deve trocar de telas de verdade: coloquedata-go="02-cadastro.html"em cada item (mantenha umhref="02-cadastro.html"real no mesmo link como fallback sem JS — o runtime roteiadata-goparaMock.go, preservando?scenario=e a transição de entrada). Links simples permanecem reservados para gatilhos de overlay (modais/detalhes — um link de tela simples sempre abre um overlay); repita o mesmo bloco de navegação em cada tela do canvas e marque o item ativo. Telas podem declarar"transition": "fade"|"slide-left"|"none"emcanvas.json:Mock.goadiciona uma classe de entrada ao destino (mock-enter-fade/mock-enter-slide-left, auto-removida em 300 ms). O handoff lê ocanvas.jsondo canvas ATUAL correspondido pelo nome do arquivo de destino, então funciona para pulos no mesmo canvas (uma autonavegação comoMock.go('01-overview.html')é o padrão de atualização) — umMock.go('../<canvas>/<tela>.html')entre canvases é uma navegação simples sem classe de entrada. A posição de rolagem é preservada por tela (scroll.<canvas>.<file>em sessionStorage, restaurada quando a tela retorna e sobrevivendo a ⟲ Reset fluxo, que limpa apenasmock.*).
- Política de estilização: o vocabulário de utilitários é o vocabulário. Qualquer
coisa baseada em token (cores, tipo, espaçamento, raio) passa pelos utilitários
gerados: vincule
- Valide e corrija. Sincronização OBRIGATÓRIA primeiro: após editar qualquer partial em
design/components/(ou quaisquer argumentos de marcador), executenode design/scripts/sync-components.mjsda raiz do projeto antes de apresentar qualquer coisa; ele rematerializa cada instância a partir de sua partial (marcador-args-vence).--checké a forma de execução a seco: imprime um diffarquivo:linhapor região divergente e sai com 1 em divergência (0 limpo), nunca escrevendo. Em seguida, execute da raiz do projeto:node design/validate.mjs design/<canvas>. Corrija cada problema que ele listar e execute novamente até que apenas a linha de resumo permaneça. Nunca apresente um canvas que tenha problemas. O argumento do validador é uma raiz de design (modo projeto) ou uma única pasta de canvas (modo canvas); sem argumento, ele padrão é./design. Verificações estruturais cobrem apenas as telas listadas emcanvas.json; o modo projeto adicionalmente verifica desatualização de tokens/CSS gerado, componentes e comentários. Regras de componente são escaneadas em cada.htmlnão isento, independentemente decanvas.json, com os códigoscomponent-unknown,component-variant,component-marker,component-divergenceeslot-marker.--allow-stalepula APENAS a verificação de desatualização;--mark-staleé a única escrita do validador (marca pins de comentário cuja âncora sumiu);--example-inventoryé a verificação de contrato de exemplo (lista exata de arquivos deinventory.json+"_demo": trueem cada pin; seminventory.json= pular, sair 0). 4b. Auditoria Impecável. Após validar, execute a auditoria técnica da skill irmãimpeccableno canvas (instalada em layout, win32):<skill-impeccable>/scripts/impeccable.cmd audit design/<canvas>- o caminho é resolvido a partir do diretório instalado da skill. Se o comandoimpeccablefalhar (código de saída diferente de zero), pare e corrija os problemas antes de prosseguir. A auditoria cobre: layout responsivo (sem overflow horizontal na largura alvo do dispositivo; a largura alvo para cada dispositivo: mobile 390px, tablet 834px, desktop 1440px — a largura da viewport para auditoria é a largura do dispositivo da tela), verificações de acessibilidade (rótulos de formulário, foco visível, contraste de cor WCAG AA, alvos de toque ≥ 44px em mobile), e aderência ao sistema de design (apenas utilitários gerados para cores e tipografia, nenhuma cor literal). A auditoria produz um relatório JSON emdesign/<canvas>/.impeccable-audit.json; leia-o e corrija quaisquer problemas. - Apresente o canvas. Informe ao usuário quantas telas você criou e em qual canvas.
Use uma quebra de linha suave em vez de listar tudo. Se o visualizador não estiver
rodando, inicie-o com
node design/serve.mjsem segundo plano (ou informe ao usuário para executá-lo) e forneça o link do visualizador.
Regras do contrato: Comentários
Este contrato entra em vigor na onda 10+ (todo 30+).
Comentários do visualizador chegam como mensagens de chat formatadas:
📝 /* Nome da Tela */ ID do Pin Comentário (prefixo fixo)
Campos:
Nome da Telacorresponde ao camponamedo arquivo da tela emcanvas.json.ID do Piné o identificador do comentário vinculado (pin). Pode estar vazio se nenhum pin foi colocado.- Após o
>, a mensagem real do usuário (prefixo fixo"Design: "em Português; ajuste se o idioma do usuário for diferente).
Regras:
- Se
ID do Pinestiver vazio: o comentário não está vinculado a um pin no visualizador nem a uma região específica. Responda ao feedback geral ou peça esclarecimentos. - Se
ID do Pinnão estiver vazio: encontre o pin correspondente na lista de pins da tela (no marcador com aquele ID). O pin especifica um seletor e um deslocamento (x,y) aproximado. Leia o contexto do comentário: examine o elemento alvo do pin e seu código-fonte HTML ao redor para entender por que o usuário comentou ali. Responda com uma alteração de design ou explicação relevante. - Nunca remova manualmente um pin. Quando você fizer alterações que tornem um pin
obsoleto, o validador irá marcá-lo automaticamente com
"_demo": truena próxima execução devalidate.mjs. Pins marcados como"_demo"não são mais exibidos no visualizador. - Tratar comentários de forma reativa: você não precisa pesquisar por novos comentários. Eles chegam como mensagens normais de chat.
Regras do contrato: Exportação W3C/DTCG
Este contrato entra em vigor na onda 6 de Contratos (todo 30).
design/scripts/export-tokens.mjs lê design/tokens.json, mescla ambos os
$themes em uma única saída de tokens DTCG e escreve design/tokens.w3c.json:
node design/scripts/export-tokens.mjs
- O arquivo de saída é um artefato derivado (nunca editado manualmente).
- A exportação usa a sintaxe de design tokens W3C (https://tr.designtokens.org/format/).
- Apenas tokens com o modificador
$descriptiondo DTCG são incluídos (tokens sem descrição são considerados internos e pulados).
Regras do contrato: Alta Fidelidade
Cada tela deve parecer um design finalizado: respeite a hierarquia de grade (conteúdo alinhado a um layout de colunas consistente, ou espaçamento livre explícito se justificado), use estilos de texto corretos (pesos, tamanhos, alturas de linha), evite cores de fundo acidentais ou não intencionais, escolha larguras de borda consistentes, ícones precisos (nenhum placeholder, ícone de estoque ou emoji substituto) e espaçamento preciso (paddings, margins, gaps correspondendo ao sistema — use as variáveis do token de espaçamento em vez de valores arbitrários). Os detalhes devem corresponder a um produto de navegador real: bordas de input com cores corretas de foco/erro, sombras de cards ou profundidade (se o sistema tiver elevation tokens), estados de hover, e assim por diante.
Regras do contrato: Aderência à Marca
O sistema de design deve refletir a marca do usuário. Se o usuário forneceu uma
marca (nome, slogan, logotipo – possivelmente em design/design-system.md),
incorpore-a consistentemente: use as cores exatas da marca (dos tokens),
vá para o tom da marca (profissional, lúdico, minimalista) em cópia e estilo,
e incorpore quaisquer elementos visuais fornecidos (logotipo, ícones personalizados).
Se a marca não foi declarada, pergunte antes de se comprometer visualmente. Não
invente uma marca se o usuário não forneceu uma; use uma paleta neutra limpa,
mas esteja pronto para pivotar quando a marca chegar.
Regras do contrato: Navegação Abrangente
Quando uma tela tiver navegação persistente (sidebar, menu superior, abas),
repita EXATAMENTE o mesmo bloco de navegação em CADA tela no canvas,
ajustando apenas o item ativo. Para cada link de navegação, sempre forneça
ambos href= (fallback sem JS, exceto para ações JS como logout) e
data-go= (para o runtime mock). Eles podem apontar para a mesma URL:
<a href="02-cadastro.html" data-go="02-cadastro.html">Cadastro</a>.
Isso garante navegação funcional com e sem JavaScript.
Regras do contrato: Integração Impecável
Este contrato entra em vigor na onda 13 de Contratos. A auditoria
impeccable é uma etapa de verificação obrigatória entre Validar e Apresentar.
Ela verifica: layout responsivo (sem overflow horizontal), acessibilidade
(rótulos, foco, contraste, alvos de toque), e estilização (apenas
utilitários gerados, nenhuma cor literal). Se falhar, corrija os problemas e
então prossiga. O relatório JSON está em
design/<canvas>/.impeccable-audit.json.
Práticas Recomendadas
- Mantenha telas focadas. Uma tela por modo (lista, detalhe, formulário).
- Use
data.jsonpara dados de amostra, não HTML codificado. - Aproveite os cenários nomeados (
data.json scenarios) para cobrir estados de borda sem duplicar arquivos HTML. - Prefira navegação no mesmo canvas para fluxos que não mudam de contexto (ex.: guias de dashboard). Use navegação entre canvases para mudanças de modo fundamental (ex.: login → dashboard).
- Teste com
--checkprimeiro na sincronização de componentes para detectar divergências cedo. - Use a exportação W3C para interoperabilidade com outras ferramentas de design.
Fluxo de trabalho de comentários (contrato)
Quando comentários chegarem:
- Analise a mensagem formatada para extrair
Nome da Tela,ID do Pine o comentário real. - Encontre o
canvas.jsoncorreto correspondendo aoNome da Tela. - Se
ID do Pinestiver presente, localize o pin nos dados da tela e examine o elemento alvo e seu código-fonte. - Responda ao feedback com alterações de design ou explicações.
- Execute
node design/validate.mjs(com--checkpara sintaxe) para verificar se as alterações não introduziram problemas. - Apresente o canvas atualizado (reinicie o visualizador se necessário).
Resolução de problemas
- Visualizador não mostra telas: certifique-se de que
design/index.jsonexiste e contém todos os nomes de canvas. - Erros de sincronização de componentes: execute
sync-components.mjs --checkpara identificar instâncias divergentes das definições de partial. - Falha de validação: corrija cada problema na ordem listada; execute novamente até passar.
- Falha na exportação W3C: certifique-se de que
tokens.jsontem a estrutura de tema correta (consulte a documentação de exportação).