← Biblioteca CLAUDE.md CatálogoContratoManualLeia-me
contrato

Contrato da biblioteca

As regras duras, e só elas. O porquê de cada uma, os casos que custaram uma noite e os fluxos passo a passo estão no MANUAL.md — leia antes de construir, não antes de consultar.

Regra de ouro: antes de inventar um componente, procure no catalogo.json.


1. Stack fixa

Camada Decisão Não use
Markup HTML semântico estático template engine, JSX
Estilo CSS puro, custom properties Tailwind, SCSS, CSS-in-JS
Script JS vanilla, ES5-safe, dentro de IIFE jQuery, bundler, imports
Libs nenhuma por padrão GSAP só quando a ficha declarar
Fontes @font-face local Google Fonts em produção

Alvo: um snippet que cola em três lugares sem adaptação — página estática, .astro, ou bloco HTML do Elementor.

GSAP só com timeline encadeada ou ScrollTrigger com scrub. Reveal, parallax simples e entrada de seção já estão no core/motion.js.

Fontes: woff2 + woff para fonte estática; woff2 sozinho quando for variável — woff não carrega fonte variável, e todo navegador que entende uma entende a outra. Nunca declare @font-face para arquivo que não está no repositório — 404 de fonte não cai no fallback de graça (MANUAL §1).


2. Idioma


3. Tokens — a interface do componente

Componente nunca escreve cor, fonte, espaçamento de seção ou curva de easing na mão. Só lê token.

O que Regra
Token global (--accent, --sec-gap, --ease…) criar um é decisão de arquitetura — discuta antes
Custom property do próprio componente (--cine-dur, --wheel-radius) livre, desde que prefixada como as classes

A segunda linha é o que permite parametrizar sem inflar o vocabulário global: o número que só aquele componente entende mora dentro dele.

Globais (em core/tokens.css)

--display  --sans           famílias
--pad  --max  --nav-h       coluna e menu
--sec-gap                   respiro entre dobras
--ease                      curva única do projeto
--radius-pill  --radius-media
--accent  --accent-2        marca
--veil  --z-overlay         véu e degrau de sobreposição
--alta  --baixa               estado: alta e baixa

--alta/--baixa são o par de mercado, e o nome fala do papel, não do pigmento — um tema pode trocá-los por âmbar e azul sem que o componente fique mentindo no próprio código. Os valores são redefinidos por escopo de tom, porque nenhum verde único alcança 4,5:1 contra #0a0a0a e contra #ffffff ao mesmo tempo. Cor nunca é o único portador da direção: quem usa o par diz a direção também por forma (seta, sinal) e por texto para o leitor de tela.

De escopo de tom (definidos pela classe da seção)

--bg  --fg  --fg-2  --fg-muted  --rule  --rule-2  --accent-ink
--alta  --baixa                                     (calibrados por escopo)

--accent-ink é a tinta do realce, e existe porque --accent é cor de marca, não cor de texto. Em escopo escuro ela é o próprio --accent; em escopo claro é o accent misturado com a tinta do escopo, porque o accent puro não fecha contraste sobre fundo claro — medido 1.36:1 com o sage da Liberta, contra um mínimo de 3:1. Quem escreve realce lê --accent-ink, nunca --accent (MANUAL §3).

Escopos: .sec-dark, .sec-deep, .sec-paper, .sec-light. A seção declara, os componentes dentro herdam.

Componente não faz override de --fg por conta própria — com uma exceção nomeada: escopo de tom no markup. Um bloco pode declarar .sec-dark ou .sec-deep na própria marcação para inverter o tom dentro de uma dobra de tom oposto. Ele está entrando num escopo, não sobrescrevendo o de fora — a diferença é que continua lendo os mesmos nomes, sem redefinir nenhum. Precedente: conteudo/bento-recursos-expansivel.

Tom vizinho: fundos escuros adjacentes têm de ser quase idênticos (#0a0a0a / #131313). Contraste real se faz com uma seção .sec-paper inteira, e a seguinte volta ao escuro.


4. Grid

.wrap é a única regra que controla a coluna:

.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--pad)}

Nenhum componente mexe em padding-inline, max-width de página ou margin lateral. Para sangrar até a borda, o elemento sai do .wrap — não ganha margem negativa.

Ritmo vertical: .sec-pad (padding: var(--sec-gap) 0). Não invente clamp solto para separar seções.


5. Movimento

Ganchos globais servidos por core/motion.js. Componente usa esses — não escreve observer próprio para entrada de elemento.

Gancho Uso Efeito
data-rv qualquer bloco fade + blur + subida
data-d="1..3" junto do data-rv escalona o delay
data-split frase de destaque revela palavra a palavra
.ttl título de seção reveal próprio, com blur

Nada entra seco. Toda entrada carrega blur indo a zero.

data-rv e transform próprio não moram no mesmo nó. O core termina o reveal com [data-rv].in{transform:none}, seletor que vence sua classe por especificidade e apaga o transform em silêncio quando a dobra entra. A saída é sempre a mesma: o data-rv vai num invólucro, e o elemento que se move fica por dentro. Precedente: efeitos/inclinacao-3d.

prefers-reduced-motion: reduce desliga tudo — já tratado no core. ?motion=on na URL força a animação para gravar vídeo ou apresentar.


6. CSS por componente

  1. Um prefixo, sempre. Toda classe começa pelo prefixo declarado no componente.json. Nada de .n, .full, .veil soltos.
  2. Zero !important. Se precisou, o token está errado.
  3. Sem seletor de elemento solto. Um h3 do componente vira .fan-title. Permitido como descendente do próprio prefixo, em conteúdo de prosa que o autor do texto escreve livre — .fan-body p, .fan-body li, .fan-body strong. Fora daí, classe.
  4. Nenhuma dependência de ordem de carregamento. O CSS funciona colado em qualquer posição da folha.
  5. Quem dá display a algo que às vezes é [hidden] desliga à mão: .meu-bloco[hidden]{display:none}. Qualquer regra de autor com display vence o [hidden] do navegador. Já foi preciso em quinze componentes.
  6. Media queries de largura no fim do próprio bloco, nunca em arquivo separado. @media(prefers-reduced-motion) é exceção e fica colada à regra que desliga.

Quem confere é python bin/conformidade.py. Um alerta pode ter explicação legítima — quando tem, ela vira comentário no próprio arquivo.

Primitivas do core — não recopie

.wrap · .sec-pad · .eyebrow · .btn/.btn-primary/.btn-ghost · .grain · .glass/.glass-hover · h2.sec-title/.sec-lead · .sec-head · .pill/.pill-accent · .display-xl

Regra que aparece em três ou mais componentes é candidata a primitiva. Promova ao core antes de recopiar pela terceira vez.

Três regras de forma


7. JS por componente

(function () {
  var raizes = document.querySelectorAll('[data-meu]');
  if (!raizes.length) return;                               // guard
  [].forEach.call(raizes, function (raiz) {                  // cada instância
    /* tudo parte de `raiz`; scroll da página via LIB.onScroll */
  });
})();
  1. IIFE fechada. Nada no escopo global.
  2. Guard clause. Ausência do elemento é saída silenciosa, nunca erro.
  3. passive: true em scroll e resize.
  4. requestAnimationFrame para qualquer coisa presa ao scroll.
  5. Respeita reduce. Leia a flag do core antes de animar.
  6. Parta da raiz do componente, nunca do documento — ele pode repetir na página.

8. Anatomia

componentes/<categoria>/<nome-kebab>/
├── componente.json   metadados lidos pelo índice
├── ficha.md          o que é, quando usar, padrão editorial, histórico, gotchas
├── markup.html       só o bloco da seção, sem <html> nem <head>
├── estilo.css        só as classes do prefixo
├── script.js         opcional — ausente se for CSS puro
└── preview.html      GERADO do markup.html — nunca escreva à mão

preview.html importa o core/ por caminho relativo, usa os placeholders de showroom/demo/ e tem de abrir com duplo-clique, sem servidor.

destaque no componente.json decide a ordem dentro da categoria: 3 vitrine · 2 forte · 1 normal (padrão) · 0 bastidor. É julgamento seu, não métrica — a complexidade entra só como desempate. Quem decide o bloco é a ordem de bin/categorias.json.

Cinco arquivos opcionais controlam o preview (preview-antes.html, preview-extra.html, preview-tema.txt, preview-css.txt, preview-js.txt) — o que cada um faz está no MANUAL §8.


9. Os quatro comandos

python bin/indice.py        # catalogo.json + tabelas + cards do showroom + fichas HTML
bash   bin/previews.sh      # preview.html de cada componente, a partir do markup.html
python bin/conformidade.py  # audita o componente contra este contrato
python bin/valida.py        # confere caminho relativo: href, src e url() de CSS

E um quinto, que lê o navegador em vez do código — obrigatório depois de mexer no core/, porque uma primitiva atinge dezenas de peças de uma vez:

node   bin/varredura.js     # os 80 previews no Chrome: console, 404, estouro, texto sem JS

catalogo.json, as tabelas do CATALOGO.md, os cards do showroom e os preview.html são gerados. Editar qualquer um à mão é trabalho perdido na próxima execução — a fonte é o componente.json e o markup.html.

Fluxo completo de catalogação, passo a passo: MANUAL §9.


10. Consumir num site novo

  1. Escolha as seções no CATALOGO.md.
  2. Copie core/tokens.css, base.css, motion.css, motion.js e a pasta core/temas/fontes/biblioteca/.
  3. Duplique core/temas/_modelo.css para o tema do cliente e preencha só os valores.
  4. Cole markup.html, estilo.css e script.js de cada componente escolhido.
  5. Nunca edite o componente para caber no cliente — edite o tema. Se o tema não resolve, o componente precisa de uma variação nova na ficha, não de um hack local.

11. Status e caminhos de entrada

Status Quer dizer
estavel sem pendência aberta — copie
revisar funciona, mas a ficha tem pendência aberta
experimental a forma ainda pode mudar entre versões

O status fala do código, não do histórico: a biblioteca não registra o que já rodou em produção. Cada projeto pede uma peça diferente, e "já foi usado" não prevê se serve no próximo. Em variacoes[], experimental marca a variante que ainda não foi exercitada.

Três caminhos de entrada, detalhados no MANUAL §11:

Caminho Registro consolidado origem[].projeto
Clone de referência — um site no ar, reescrito do zero projetos/referencias-externas.md "referência: <site>"
Origem externa de código — autor nomeado, licença explícita idem, seção própria nome do registro
Autoral — padrão comum, sem referência única projetos/autorais.md "autoral"

Componente extraído de site nosso: projetos/<projeto>.md.

Duas regras que não se negociam:

Não atravessam a tradução, mesmo que o original tenha: fonte de terceiro, ícone proprietário, logo, foto e qualquer asset com direito de imagem.