O que Pixel HUD UI faz?
Um framework de UI, não apenas um tema de cores. Possui três camadas, e um bom resultado usa todas elas:
- Fundações: uma grade de 4px, uma escala tipográfica ajustada para uma face pixel de 12px, papéis de cores (cada cor significa uma coisa), regras de 1px em vez de sombras, movimento em passos.
- Controles: painéis e barras de título, teclas (botões) com intenções, teclas de ícone, abas, controles segmentados, linhas de lista, campos de formulário, entradas, selects, caixas de seleção e rádios quadrados, interruptores de lâmpada, controles deslizantes de medidor, medidores de progresso, lâmpadas, tags, badges, teclas, menus, tooltips, diálogos, toasts, tabelas, blocos de código, prosa, carregadores, estados vazios. Cada um tem tamanhos fixos e um modelo de estados compartilhado (hover, pressionado, foco, selecionado, desabilitado, carregando, erro).
- Paletas: tokens
--hud-*, para que o framework funcione com qualquer cor, incluindo a própria marca do aplicativo.
Arquivos
| Arquivo | O que é |
|---|---|
references/design-system.md | A especificação. Princípios, fundações e a anatomia de cada controle, tamanhos, estados, quando usar e acessibilidade. Leia antes de projetar. |
assets/pixel-hud.css | A implementação: tokens, globais claras sob [data-skin="pixel"] e as classes de controle hud-* |
assets/palettes.css | starward (espaço profundo, escuro), terminal (cinza-esverdeado, escuro), paper (areia quente, claro) |
assets/fonts.css | Fusion Pixel 12px (OFL), fixado no jsDelivr; ou auto-hospedado via @fontsource |
assets/pixel-caret.js | Cursor de bloco de 3px opcional para campos de texto (data-pixel-caret) |
assets/demo.html | Todos os controles em todos os estados, com um alternador de paleta: a referência visual |
references/integration.md | Receitas por stack: mapeamento das cores de um app, Tailwind, shadcn/ui, React/Next, Vue, escopo, alternância sem flash, fontes auto-hospedadas |
scripts/check-contrast.mjs | Verificação WCAG para qualquer paleta: node scripts/check-contrast.mjs my.css |
Fluxo de trabalho
1. Leia a especificação e o demo
Leia references/design-system.md (pelo menos Princípios, Fundações e os controles que a tarefa precisa) e veja assets/demo.html. A especificação diz por que cada controle se parece daquela forma; segui-la é o que faz uma tela ser lida como este framework em vez de "um tema escuro com uma fonte pixel".
2. Analise o projeto
Antes de copiar qualquer coisa, descubra:
- a stack e onde o CSS global é carregado (arquivo de layout,
main.ts,index.html, entrada do Tailwind); - como as cores são definidas atualmente (propriedades customizadas CSS, tema Tailwind, variáveis HSL do shadcn, hex em componentes);
- se é uma nova UI ou um restilo, se é a única aparência do app ou um tema alternável, a página inteira ou uma área.
Isso determina o mapeamento de cores (passo 4) e evita que você lute contra os estilos do aplicativo.
3. Adicione o kit
Copie pixel-hud.css, fonts.css, palettes.css (se uma paleta empacotada for usada) e pixel-caret.js (se o app tiver campos de texto) para o projeto. Ordem de carregamento: fonts → paletas → pixel-hud.css, após os estilos base do próprio app.
4. Escolha as cores
- Uma paleta empacotada:
data-hud-palette="starward" | "terminal" | "paper". - As próprias cores do app: um bloco mapeia suas variáveis para
--hud-*(references/integration.md› Mapeando as cores de um app). Mantém a marca, adiciona o framework. - Uma nova paleta: siga "新建一套配色" na especificação.
Em seguida, execute node scripts/check-contrast.mjs <arquivo> em qualquer paleta que você escreveu ou mapeou, e corrija cada FALHA: os controles dependem das cores barra, texto e verde serem legíveis em todas as superfícies.
5. Ative-o
<html data-skin="pixel" data-hud-palette="starward">
Um tema alternável define estes antes da primeira pintura (references/integration.md › Alternância sem flash). Para estilizar apenas uma área, coloque ambos os atributos em seu contêiner.
6. Construa com os controles
Os globais já lidam com tipo, cantos quadrados, inputs nativos, selects, range sliders, checkboxes, scrollbars, anéis de foco, seleção e scanlines. Dê a cada elemento seu papel com uma classe, seguindo a especificação para tamanho e estado:
| Necessidade | Controle (classe) |
|---|---|
| Agrupar informações relacionadas | .hud-panel + .hud-titlebar (+ .hud-titlebar__actions), corpo .hud-panel__body, seções .hud-subhead |
| Ação principal | .hud-btn.is-solid (intenção: accent, go, warn, info, danger) |
| Ação secundária | .hud-btn |
| Ação apenas com ícone | .hud-icon-btn + aria-label |
| Alternar visualizações | .hud-tabs > .hud-tab[aria-selected] |
| Escolher um entre 2 a 5 valores | .hud-segmented > button[aria-pressed] |
| Lista navegável | .hud-row[aria-current] |
| Entrada rotulada | .hud-field > .hud-label + input/select + .hud-help / .hud-error |
| Dropdown | .hud-select > select |
| Sim/não, um de muitos | .hud-check, .hud-radio (marcas quadradas) |
| Ligar/desligar instantâneo | button.hud-switch[role=switch][aria-checked] > .hud-switch__knob |
| Nível / progresso | .hud-gauge + --value (data-state warn/alert) |
| Status | .hud-lamp[data-state] |
| Valor, ID, parâmetro | .hud-tag; contagens .hud-badge; teclas kbd |
| Menus, dicas, modal, feedback | .hud-menu, .hud-tooltip, .hud-backdrop > .hud-dialog, .hud-toasts > .hud-toast |
| Dados, código, artigos | table.hud-table, .hud-code, .hud-prose |
| Entrada de comando / chat | .hud-input + data-pixel-caret |
| Aguardando, nada a mostrar | .hud-loader, aria-busy em uma tecla, .hud-empty |
Coloque as classes no código-fonte do componente (JSX, templates), passando-as através da propriedade className/class de uma biblioteca de componentes, em vez de escrever seletores contra elementos internos do framework: elas sobrevivem a refatorações e são lidas claramente.
Ao fazer restilo de um aplicativo existente, primeiro mapeie cada componente existente para a tabela acima (uma lista curta em sua resposta ajuda o usuário a acompanhar), depois aplique.
7. Verifique o resultado
- Tire um print da página (ou abra-a) e compare com
assets/demo.html. - Confirme que a fonte pixel carregou (
document.fonts, aba Network); uma CSP pode bloquear o jsDelivr, então auto-hospede. - Navegue por tab: todos os controles alcançáveis, anéis de foco verdes de 1px visíveis.
- Percorra o modelo de estados nos controles principais: hover, pressionado, desabilitado, carregando, erro.
- O script de contraste passa para a paleta em uso.
As regras que mais importam
A especificação tem a explicação completa; estas são as mais frequentemente quebradas:
- Quadrados e planos. Sem raio, sem sombras de desfoque, sem gradientes exceto scanlines. Apenas sobreposições recebem a sombra de deslocamento rígida.
- As cores mantêm seus trabalhos. Barra = estrutura e seleção; verde = ligado, ênfase, foco; amarelo = valores; laranja = notas e avisos; vermelho = perigo. Verde usado como decoração deixa de significar "ligado".
- Selecionado = invertido. Preenchimento da barra com texto escuro; linhas adicionam uma borda verde de 3px. Em um fundo de cor de barra, hover inverte ao contrário.
- Uma ação principal sólida por área; ações lado a lado recebem cada uma sua própria cor de intenção e mantêm-na quando desabilitadas (esmaecer, não contornar).
- Barras de título encabeçam apenas painéis. Cabeçalhos de tabela e código usam o tom suave
--hud-bar-soft. - Os tamanhos vêm da escala: controles 24/28/32px, espaçamento na grade de 4px, texto 12/14/16/24/36px.
Armadilhas
- O framework força
border-radius: 0 !importantem seu escopo. Mantenha algo redondo (um avatar) delimitando o skin a um contêiner que o exclua. color-mix()precisa Chrome/Edge 111, Safari 16.2, Firefox 113; para navegadores mais antigos, defina--hud-bar-soft/--hud-bar-linecomo cores sólidas.- Uma classe que define
displaypode mostrar elementoshidden; o framework re-oculta[hidden]dentro de seu escopo, então prefira o atributohiddenpara alternar. - Frameworks que definem o valor de um campo por código não disparam
input; chamefield.__pixelCaret.update()após tal mudança se o cursor precisar se mover imediatamente. - Scanlines ficam em um z-index muito alto com
pointer-events: none; desligue-as comdata-hud-scanlines="off"onde elas atrapalharem (prints, aplicações canvas).