Diretrizes de design
Como aplicar o ranui numa tela real: escolha um papel e um estado, e deixe os tokens darem os valores.
As regras em si ficam em dois lugares, e esta página aponta para eles em vez de repeti-las: o
guia de design, para o método que vale em qualquer produto, e o
adaptador de implementação do ranui,
para os tokens, níveis e regras de componentes do ranui. Os dois são distribuídos em node_modules/ranui/docs/DESIGN.md. O
design system lista cada token e o seu valor, a
tematização cobre as sobrescritas em tempo de execução e a
arquitetura da informação cobre a estrutura da página.
Use quando for escolher cor, espaço, tipografia, profundidade ou movimento para uma tela feita com elementos
<r-*>.
Princípios
- Clareza antes de personalidade. Primeiro, a tarefa principal e a ação principal precisam ser inconfundíveis.
- Reutilize os controles existentes.
r-button,r-input,r-selecter-modaljá trazem o comportamento de formulário, teclado e acessibilidade; mude o estilo deles em vez de recriá-los. - Decida por papel e estado. "O que é este texto?" tem resposta; "que tamanho fica bom?" não tem. O token do papel dá o valor, e esse valor acompanha o tema.
- Projete todos os estados alcançáveis e olhe o resultado. O estado padrão é um entre oito, e uma sombra que ninguém vê só aparece num navegador.
São pontos de partida. Afaste-se de um quando a tela ficar melhor com isso, e diga por quê.
Escolher uma cor
A escada já decide como ficam o hover e o estado ativo; o seu trabalho é nomear o papel.
| O elemento é… | Use |
|---|---|
| O fundo de uma página ou superfície | --ran-color-bg / -bg-subtle / -bg-elevated / -bg-muted |
| Algo sob o ponteiro ou sendo pressionado | --ran-color-bg-hover / -bg-active |
| Texto | --ran-color-text / -text-secondary / -text-disabled |
| Uma borda | --ran-color-border / -hover / -active |
| A ação para a qual a tela existe | --ran-color-primary (com --ran-color-primary-text em cima) |
| Um estado | --ran-color-success / -warning / -danger |
| Um link | --ran-color-link |
Cada destaque tem um único significado. O primário é monocromático, então o azul fica para os links e o anel de foco; verde é sucesso, âmbar é aviso, vermelho é perigo. Usar vermelho para dar ênfase deixa você sem nada para dizer "perigo" depois.
Um hexadecimal cru, um valor de fallback que não muda com o tema ou um que nomeia um token que não
existe quebra em silêncio no modo escuro ou derruba a declaração inteira; as
regras de cor do adaptador
explicam cada caso, e o verify:design os detecta no código-fonte do próprio ranui.
Espaço e ritmo
Tire os espaços da escala de 4px e deixe a distância significar alguma coisa:
- 8px entre elementos dentro de um grupo.
- 16px entre grupos.
- 24–32px entre regiões.
Um espaço menor significa uma relação mais próxima, então basta um espaço fora da escala para quebrar o ritmo. Dê a cada espaço um único responsável: conte a margem do filho e o padding do pai antes de acrescentar um terceiro espaço entre eles.
Escolher a tipografia
Pergunte que papel o texto cumpre (título, rótulo, corpo, botão, monoespaçado); a fonte, o tamanho, o peso e a altura de linha saem da escala tipográfica. Um texto de fato excepcional, como o aviso de um gesto sobre um vídeo, fica melhor com o próprio token de componente do que forçado ao papel mais próximo.
Profundidade: sombra e empilhamento
Escolha o nível de sombra pelo que o elemento é: uma superfície no fluxo, uma camada flutuante ou um diálogo que bloqueia. Uma camada que cai para o nível dos cartões parece pregada na página.
Embutir camadas do ranui na sua própria moldura. A escada de z-index
começa em 1000, então uma camada portalizada passa sozinha por cima da moldura comum da página. Uma camada com position: fixed
que fica dentro do próprio shadow DOM (o diálogo do r-modal) só escapa até o
contexto de empilhamento ancestral mais próximo. Se você envolver o conteúdo embutido em algo que crie um
(isolation, opacity < 1, transform, filter, will-change), suba esse invólucro só enquanto uma
camada estiver de fato aberta:
.embed {
isolation: isolate; /* cheap: no z-index of its own, so nothing is promoted */
}
/* Escalate only while a real overlay is open — never "just in case" */
.embed:has(r-modal[open]),
.embed:has(r-modal[closing]) {
position: relative;
z-index: 100;
}Um z-index permanente no invólucro eleva tudo o que está dentro dele, conteúdo estático incluído, acima do seu
cabeçalho fixo durante toda a rolagem; este site chegou a ser publicado assim uma vez. Combine closing além
de open: a máscara continua sendo pintada durante a transição de fechamento.
Movimento
O feedback frequente (hover, foco, pressionar) é imediato. Quando o movimento explica uma mudança, o feedback fica
em 0–100ms, a entrada leva 250–400ms e desacelera, e a saída leva 150–200ms e acelera.
Permita interrompê-lo e respeite prefers-reduced-motion.
Nunca deixe uma propriedade de cor fazer transição. O CSS não sabe por que uma cor mudou, então uma transition
em background-color, color, border-color, box-shadow, fill ou stroke também dispara quando o
tema vira: cada elemento desbota no próprio ritmo enquanto a página já trocou. Anime
transform e opacity em vez disso. transition: all e um transition: 0.2s pelado também incluem a cor.
Estados e textos
Todo estado alcançável faz parte do design: hover, ativo, foco, desabilitado, carregando, vazio, erro.
O hover corresponde a bg-hover / border-hover, o ativo a bg-active e o foco ao anel de foco. Nada que não
seja clicável deve parecer clicável: o r-card só reage ao hover com hoverable.
O texto também é parte do sistema:
- Os botões nomeiam o resultado, com o objeto quando o contexto não o fornece: "Excluir membro". Um diálogo com objeto claro pode dizer "Excluir"; evite um "OK" genérico.
- Os erros dizem o que aconteceu e depois como resolver. ✅ "A compilação falhou: o pacote passou do limite de tamanho. Reduza-o ou aumente o limite." ❌ "A operação falhou, tente de novo."
- As confirmações descrevem a mudança, não o sucesso, e só aparecem depois que ela é confirmada. ✅ "Projeto excluído" ❌ "Operação bem-sucedida".
- Deixe o contexto tirar a redundância: um diálogo intitulado "Excluir projeto" não precisa de um botão escrito "Excluir o projeto permanentemente, para sempre".
Acessibilidade
- Atenda ao contraste WCAG AA do texto contra o fundo dele.
- Nunca sinalize um estado só com cor: acompanhe-a de um ícone, um rótulo ou texto.
- Todo elemento interativo mantém um anel de foco visível (
--ran-focus-ring, ououtline: 2px solid var(--ran-color-focus); outline-offset: 2px). - Tudo é alcançável pelo teclado.
- Respeite
prefers-reduced-motioneprefers-color-scheme.
Mouse e toque, estreito e largo
Nem a forma de apontar nem o tamanho da janela é o alvo secundário.
- Arrastos, sliders e gestos usam Pointer Events, com
touch-action: nonena superfície exata de arrasto. Umtouch-action: nonesem nenhum manipulador de ponteiro por trás é um controle quebrado. - O que só aparece no hover precisa de uma alternativa por toque.
trigger="hover"nor-selectou nor-popovervira um clique em dispositivos de toque; tudo o que você construir deve fazer o mesmo. - Prefira tamanhos relativos ao viewport (
min(560px, calc(100vw - 32px)),clamp()) a inventar um breakpoint: o ranui não tem token de breakpoint, então cada breakpoint fixo é um número que alguém mantém. - Nunca esconda no celular a única forma de fazer algo. Reorganize em vez disso.
- Uma posição medida só está certa até o próximo reflow. Tudo o que vem de
getBoundingClientRect()fica desatualizado ao redimensionar, quando o contêiner se reorganiza e, num painel portalizado, ao rolar. Carregar numa largura estreita não testa redimensionar até ela, que é onde isso quebra.
O que a biblioteca cobra de forma mecânica
pnpm -F ranui verify:design verifica nove regras no código-fonte do próprio ranui: fallbacks de cor que não
mudam com o tema, literais de cor crus, as escalas de espaço e de tamanho, arrastos só de mouse, regras de :host que quebram
hidden, fallbacks que nomeiam tokens não declarados, componentes que buscam na própria árvore shadow e árvores shadow
construídas fora do construtor. Uma linha que quebra uma regra de propósito diz isso com
design-ok: <rule> <reason>. As verificações cobrem só as raízes de código configuradas; uma aplicação que
usa o ranui roda as próprias verificações e olha as próprias páginas.
Exemplos de design
Esquemas derivados dos tokens base do ranui, não componentes reais.
Alinhe as linhas
Quando uma linha recebe mais conteúdo, mantenha o texto alinhado com as demais e as ações na mesma coluna.
Coordene os cantos internos e externos
Quando as duas bordas forem necessárias, subtraia o recuo do raio externo: 16 − 4 = 12. As curvas compartilham o centro e mantêm uma distância uniforme.
--ran-radius-lg − --ran-space-1 = --ran-radius-mdFacilite o clique em ícones pequenos
O ícone mede 16px, e a área de clique se amplia para 32px para facilitar o uso. Escolha o tamanho conforme a entrada por mouse ou toque e mantenha as áreas vizinhas separadas.
--ran-size-1 · --ran-size-7Evidências e aceitação
A seção verificar uma mudança do guia diz o que conferir num navegador real e o que relatar: o que você observou, o que só deduziu e o que não conseguiu conferir. A revisão de um agente não é a aceitação do usuário.