


Manter uma biblioteca CSS-in-JS que funciona no navegador, no servidor e no nativo
Use quando uma IA de programação trabalha numa biblioteca CSS-in-JS baseada em padrões. Limita os estilos a CSS padrão, evita falhas em cada ambiente, escreve antes os testes pela especificação e define como fazer notas de versão, documentação e demos com código real.
Para usar estas regras de IA
## Aceitar só CSS padrão nos estilos e dar prioridade aos valores padrão configurados
Mantenha a superfície de estilos criada alinhada ao CSS real e compatível com os padrões. Isso mantém o modelo mental portátil e evita que a API derive para um dialeto idiossincrático.
- Aceite apenas nomes, grafias e valores de propriedades padrão nos estilos criados. Nunca invente aliases não padronizados (por exemplo, nomes em kebab-case para props exclusivas de uma plataforma). As chaves de estilo específicas de plataforma pertencem a uma válvula de escape explícita (um objeto de estilo inline, ou suporte de plataforma upstream), não à linguagem de template.
- A função da camada nativa é mapear CSS idiomático para primitivas equivalentes da plataforma e aplicar polyfill no que for possível até que o runtime nativo se atualize. Ela não existe para expandir a gramática de entrada aceita.
### Precedência dos padrões configurados
- Os padrões de atributo configurados pelo autor sempre prevalecem sobre as props passadas pelo chamador, por design. Este é um contrato deliberado, não um bug.
- A válvula de escape é a forma de função da configuração de padrões: ela recebe as props de entrada e pode recorrer condicionalmente a um valor alternativo (manter o valor do chamador ou fornecer um padrão).
- Exceção: quando o chamador passa explicitamente `undefined` para uma prop, isso suprime o padrão configurado para essa prop.
## Usar o gerenciador de pacotes e o formato de commit do projeto
- No início de cada sessão, leia o resumo atual dos recursos voltados ao consumidor, para trabalhar em cima da superfície suportada hoje, e não de um comportamento lembrado de memória.
- Use o gerenciador de pacotes designado pelo projeto e seus comandos associados; não o substitua por outro.
- Nunca inicie o servidor de desenvolvimento por conta própria. Peça ao mantenedor para iniciá-lo, caso seja necessário.
- Use prefixos de commit convencionais (`feat|fix|chore|refactor|test|docs|style|perf|build|ci`). Prefira mensagens curtas: apenas o título, ou o título mais uma frase enxuta.
- Mantenha uma convenção de grafia em inglês consistente para toda a prosa (comentários, documentação, títulos de testes, strings visíveis ao usuário). Preserve a grafia original apenas dentro de citações literais de especificações ou padrões.
## Distinguir servidor, navegador e nativo, e manter código de DOM fora do nativo
Código distribuído para múltiplos runtimes não deve presumir um único ambiente. Detecte o ambiente a partir de vários sinais independentes e isole código incompatível na fronteira do ponto de entrada.
- Não reduza a detecção de ambiente a uma única flag universal. Distinga pelo menos: uma constante de servidor em tempo de build (verdadeira apenas no build de servidor), uma condição de componente de servidor em tempo de execução (alguns frameworks servem um build sem APIs de contexto exclusivas de cliente) e uma flag de servidor por requisição definida pelo ponto de entrada SSR. Cada decisão deve depender do subconjunto mínimo de sinais que cobre os cenários relevantes. Armadilha comum: suprimir trabalho de DOM baseando-se apenas na constante de servidor em tempo de build quebra o caminho de teste de build de servidor sob jsdom, onde mutações de DOM ainda ocorrem. Em vez disso, condicione decisões de DOM aos sinais de runtime/SSR.
- O ponto de entrada nativo nunca deve importar transitivamente código de DOM/navegador por meio de imports de valor. Use imports somente de tipo (type-only) e marcadores de runtime (um registro de símbolos compartilhado) em vez de `instanceof`. Verifique com um grep que confirme zero referências a `document.` no bundle nativo compilado; alguns runtimes nativos falham no momento de avaliação do módulo diante de qualquer referência a `document`.
- Hooks do framework que não existem em todos os runtimes (por exemplo, um hook de ref que é undefined em componentes de servidor) devem ser protegidos pela constante de servidor em tempo de build, para eliminação de código morto. Nunca os proteja com uma verificação em tempo de execução do tipo `typeof hook === 'function'`, o que se torna uma chamada de hook condicional.
- Mantenha um único caminho canônico de emissão de saída. Ao alterar a saída, estenda as suítes de teste de emissão e de parser/compilador, em vez de adicionar um caminho paralelo.
## Remover código com constantes de build e fixar com testes o mapeamento dos pontos de entrada
Separe o que o bundler pode eliminar em tempo de build daquilo que só existe em tempo de execução, e seja deliberado quanto ao mapeamento dos pontos de entrada.
- Constantes em tempo de build (build de servidor, build nativo, variante native-web, modo dev) são substituídas por literais para que os bundlers eliminem o ramo morto por dead-code elimination. Prefira envolver toda a região contígua exclusiva de dev mais externa em uma única guarda de dev; não confie apenas em um helper de aviso para pular trabalho, e nunca construa strings de mensagem ou argumentos de aviso fora da guarda de dev.
- Uma verificação em tempo de execução como `typeof window !== 'undefined'` não pode ser removida por tree-shaking. Use constantes em tempo de build, não verificações em tempo de execução, quando precisar que o código seja fisicamente removido de um bundle.
- O mapeamento de entradas/subcaminhos é uma fonte frequente de quebras silenciosas. A resolução por extensão de plataforma (deixando o bundler nativo escolher um arquivo específico por plataforma) é mais segura do que um mapa de objeto `browser` que alguns bundlers nativos aplicam em todas as plataformas, o que pode rotear silenciosamente uma bridge web para o nativo. Um fallback `.js` deve ser a bridge segura e multiplataforma, nunca o engine específico da plataforma. Trave essas resoluções com um teste de resolução/tree-shake.
- Prefira um campo `browser` a `exports` condicionais quando este último quebrar a resolução de tipos em projetos compostos. Adicione todo diretório de subcaminho publicado à lista `files` do pacote.
## Escrever primeiro um teste que falha e medir otimizações com cargas reais
- O desenvolvimento orientado a testes (TDD) estrito é aplicado em todo o repositório. Antes de alterar código de produção, adicione ou estenda um teste que falhe e que codifique o contrato desejado; em seguida, implemente apenas o necessário para deixá-lo verde. Nenhum comportamento visível ao usuário é lançado sem um teste que falharia sem a mudança. Siga a mesma disciplina red-green também para trabalhos que não são features.
- Sempre faça microbenchmark das otimizações contra uma carga de trabalho realista, não um melhor caso sintético. Reverta qualquer mudança que piore o caminho percorrido por chamadores reais, mesmo que ela vença isoladamente.
- Otimize para baixa pressão de memória e funções monomórficas.
- Fundamente qualquer comportamento baseado em especificação no draft editorial atual da especificação oficial, não em resumos, sites de referência ou memória. Rebusque a seção relevante para a sessão, cite a cláusula normativa literalmente como comentário acima do teste que a trava, e escreva um teste por regra dentro de um bloco de conformidade com a especificação claramente nomeado. Se a especificação for omissa ou ambígua, documente o desvio ao lado do teste e vincule o issue de acompanhamento. Isso se aplica a toda mudança que toque em especificação.
## Transformar cada regra da especificação em teste antes de criar um polyfill nativo
Quando o engine de estilos do runtime nativo não conseguir entender um recurso de CSS, aplique um polyfill, mas trave o comportamento de acordo com a especificação antes de refatorar os internals.
Procedimento para um polyfill novo ou revisitado (também para qualquer bloco de validação baseado em especificação):
1. Busque o draft editorial atual para a sessão. Os números de cláusula e a redação mudam ao longo do tempo, então nunca trate um extrato antigo como autoritativo.
2. Traduza cada regra da especificação em exatamente um teste, com o texto da especificação citado literalmente acima dele, dentro de um bloco de conformidade nomeado na suíte relevante.
3. Escreva os testes primeiro e registre quais falham atualmente.
4. Implemente até que passem. Não remodele testes que já passam para se ajustarem à implementação; a especificação é a fonte da verdade.
5. Execute as suítes completas nativa e principal para verificar regressões.
Assim que o bloco de especificação estiver verde, os internals (tokenização, AST, avaliador) ficam livres para refatoração; o bloco trava o comportamento observável pelo usuário.
- Mantenha atualizado o registro de compatibilidade nativa voltado ao consumidor sempre que versões de runtime forem lançadas, o suporte mudar, ou polyfills forem adicionados, removidos ou alterados.
- Um recurso sem alternativa nativa viável deve emitir um aviso deduplicado com um código estável que nomeie a construção problemática, explique por que ela não pode ser executada e ofereça uma alternativa concreta; em seguida, descarte a declaração (recorrendo a null) em vez de entregar algo sem sentido.
- Paridade entre variantes: onde o navegador já oferece um recurso, repasse o CSS bruto sem alterações; nunca emita uma propriedade que o navegador ainda não oferece; condicione elevações de props exclusivas do nativo e extensões de enum à constante de build exclusiva do nativo. Dê a cada bloco de especificação de polyfill uma sub-suíte de paridade que alterne a variante web e trave sua saída visível, e dispense explicitamente (com o mesmo rigor de um comentário de desvio) qualquer regra normativa que não se aplique a uma determinada variante.
## Escrever nas notas de versão só o que o usuário vê e colocar cada documento no lugar certo
Ajuste o registro e o conteúdo de cada artefato ao seu público.
- Textos voltados ao consumidor (notas de versão, entradas de changelog, descrições de PR, documentação pública) descrevem apenas comportamento observável pelo usuário, em palavras que alguém que não leu o código-fonte consiga entender. Indique o que é e o que não é suportado, e os próprios limites da mudança; vincule a matriz de compatibilidade em vez de catalogar lacunas não relacionadas. Sem nomes de APIs internas, mecanismos ou caminhos de código; isso pertence ao corpo do commit e ao guia do contribuidor.
- Descreva o comportamento como ele é atualmente. Evite narrativas de jornada ("anteriormente", "não mais", "agora", "substitui") para estados que nenhuma versão lançada chegou a distribuir; incorpore uma correção em um recurso ainda não lançado à nota de versão desse próprio recurso.
- Crie notas de versão apenas para mudanças visíveis ao usuário (correções, recursos, mudanças que quebram compatibilidade). Omita refatorações internas, ferramentas, testes e correções em código introduzido na mesma versão ainda não lançada.
- Não edite arquivos gerados automaticamente (changelogs, mapas de erro gerados); regenere-os por meio de sua ferramenta.
- Não use nomes específicos de provedores de IA na documentação voltada a contribuidores; use expressões neutras como "um assistente de codificação com IA".
- Não quebre linhas manualmente na prosa de corpos de PR, corpos de issue ou comentários; parágrafos em linha única se reajustam automaticamente, e quebras manuais parecem quebradas em visualizações mobile e citadas. Os corpos de mensagens de commit podem manter a convenção de 72 colunas.
### Posicionamento da documentação
- O guia do contribuidor reúne regras transversais, invariantes e conhecimento adquirido que não têm um lugar natural nos comentários do código-fonte; mecanismos bem descritos não pertencem a ele.
- Documentos de conhecimento independentes registram armadilhas e conhecimento adquirido, não explicações passo a passo do mecanismo dos recursos; o código-fonte é a autoridade sobre o mecanismo.
- O "porquê" em nível de código vive em comentários/JSDoc junto ao código. Não repita citações de especificação no código de produção ou em mensagens de aviso; âncoras, citações normativas e justificativas ficam no teste que trava o comportamento. Mensagens de aviso nomeiam apenas a construção problemática e a alternativa concreta, e nada além disso.
## Usar padrões de performance medidos e criar demos que rodam o código real
Padrões validados por microbenchmark em um engine JavaScript convencional (trate como hipóteses de partida; remeça no contexto):
- A concatenação de string com `+=` supera `array.push()` + `join()` em todas as escalas.
- O spread `{...props, extra}` supera `Object.assign` ou uma cópia com `for..in`.
- `for..in` supera `Object.keys()` combinado com um loop.
- Armazene em cache RegExps compiladas em um map; uma pré-verificação com `indexOf` para pular o trabalho completamente traz um ganho ainda maior.
- A concatenação manual com `+` supera template literals em loops apertados.
- Construir objetos de elemento brutos (com a tag de elemento do framework) é muito mais rápido do que a factory de elementos do framework.
- `new Array(n)` cria arrays com buracos (holey arrays) que contaminam o type feedback; evite pré-dimensionar arrays quentes (hot arrays).
Pegadinhas do engine e da linguagem:
- Um modificador `private` não é permitido em uma expressão de classe anônima atribuída a uma const.
- Um import de estrela somente de tipo (type-only) ainda pode disparar a resolução de módulos do bundler, mesmo que o sistema de tipos o remova.
Integridade de demos e QA visual (para qualquer vitrine que afirme provar um comportamento):
- Tolerância zero para demos falsas. Todo widget deve exercitar o caminho de runtime real que afirma demonstrar. Se um recurso não puder ser executado em uma plataforma, deixe que a célula falhe de forma visível (layout quebrado, aviso, glifo ausente); essa falha é a demo. Nunca substitua por um mock que imite a especificação, e nunca fixe (hardcode) uma cor de aprovado/reprovado como substituto do disparo do caminho real.
- Use componentes onipresentes (omniplatform), sem ramificações por plataforma na vitrine; contornos para diferenças entre plataformas pertencem à biblioteca, não à aplicação.
- Torne o funcionando-versus-quebrado perceptível à distância, por meio de diferenças macro (deslocamentos de layout, inundações de cor, presença/ausência), e faça com que todo widget seja lido corretamente tanto no modo claro quanto no escuro.
