Marca e Design System
Uma luz só, e ela é âmbar.
Tokens, fundações, componentes e diretrizes para que tudo que a Sunny publica pareça vir da mesma empresa: site, landings de produto, Sunshine, slides, propostas comerciais e posts.
Este guia não substitui as fontes da verdade: ele organiza e aponta para elas. Os valores exatos vivem em tokens/tokens.json; o logo, a paleta e as fontes originais vivem no Drive. Ver Fontes da verdade.
O que é
A marca vigente é a V4 NewBrand26, no ar desde 17 de março de 2026. Ela tem quatro camadas, e cada uma tem um lugar só.
Os valores: cor, tipo, espaçamento, radius, sombra. Vivem em tokens/ em três camadas: primitivo, semântico e de componente.
As regras de uso de cada valor: cores, tipografia, espaçamento, radius, elevação e logo.
Button, badge, card, input e nav item, com variantes, estados, anatomia e acessibilidade.
Acessibilidade, voz, como contribuir, versionamento e quem procurar. Decisões ficam em registro append-only.
O que não cobre
- UI interna dos produtos. Cada produto tem seu design system de componentes e consome os tokens daqui. O brand define a linguagem, não o componente de tabela.
- Copy de produto e conteúdo de marketing. A voz dá o tom, não o texto.
- Ícones customizados e ilustração. Ainda sem padrão. Ver decisões pendentes.
Navegação rápida
Não use #FFDE59, Plus Jakarta Sans ou "inglês-first" como atributos atuais. São da V3, que saiu do ar em 17/03/2026. As explorações Convergence, Aurora e Radiance, de fevereiro de 2026, não foram adotadas e não valem como referência.
Comece aqui
Princípios
Quatro ideias que desempatam qualquer dúvida de marca. Quando duas regras parecerem entrar em conflito, decida por estas, nesta ordem.
Tudo nasce sobre bg.base. O claro existe para papel, slide e e-mail. Por isso este guia abre no escuro e o tema claro é um botão, não o padrão.
O âmbar é a única cor de destaque. Se dois elementos na mesma tela pedem âmbar, um deles não merece.
Sempre text.accent, nunca #FFB61F. É o que faz tema, ajuste de marca e acessibilidade funcionarem de uma vez.
WCAG 2.1 AA é critério de entrada, não polimento. Par de cor que falha não entra no token, componente sem foco visível não entra no índice.
As três camadas
A regra que sustenta o princípio 3. Código e Figma usam semânticos e de componente. Primitivo direto só dentro do arquivo de tokens. É o que permite trocar o tema, ou ajustar o âmbar, em um lugar só.
primitivo color.amber.500 = #FFB61F semântico color.accent.default = {color.amber.500} componente button.primary.bg = {color.accent.default}
Em CSS, var(--sunny-button-primary-bg) resolve para var(--sunny-color-accent-default), que resolve para var(--sunny-color-amber-500).
Status honesto em cada token
Todo token carrega $extensions.sunny.status. Este guia repete o selo em cada valor, porque saber de onde veio o número muda o que você pode fazer com ele.
| Selo | O que significa | O que você pode fazer |
|---|---|---|
| medido | Lido do código do site ou dos arquivos oficiais do Drive | Usar sem pensar |
| derivado | Calculado a partir de valores medidos | Usar, e avisar se ficar estranho na tela |
| proposta | Não existe no site ainda | Não usar em produção sem abrir uma decisão |
Comece aqui
Por onde começar
O caminho mais curto entre a sua dúvida e a resposta, por perfil.
- Precisa de cor, espaçamento ou fonte: use a variável de
tokens/tokens.css. Os nomes antigos do site continuam funcionando pelo bloco de compatibilidade. - Vai montar botão, badge, card, input ou nav item: siga a página do componente.
- Vai mostrar comando, ID ou log:
type.code, fonte mono.
- Logo: regras e versões. Arquivos no Drive, pasta
_Sunny-NewBrand26. - Slides e propostas: fundo
bg.base, títulos em Bricolage Grotesque, corpo em Inter, âmbar só em destaque. - Texto: voz. Direto, técnico, brasileiro, sem travessão.
- Tela nova: comece pelos semânticos e pelos componentes existentes. Cor de estado é
status.*, nunca âmbar. - Cor, fonte ou componente novo: abra uma decisão antes de desenhar.
- "Existe X?": este guia, depois o repositório do site.
- "Quem decide?": quem procurar.
- "Isso ainda vale?": confira o selo do token e a maturidade do componente.
Consumir os tokens
O site importa o tokens.css desde 15/09/2026 e ainda usa os nomes antigos pelo bloco de compatibilidade. O plano de adoção está em versionamento.
# regenera o tokens.css a partir do tokens.json $ node tokens/build.mjs # falha se um par obrigatório não atinge WCAG AA $ node tokens/check-contrast.mjs ✓ 14 pares verificados, 0 falhas
Sem dependências. Node 18 ou mais recente.
Fundações
Cores
Um âmbar, uma escala de neutros e quatro estados. Nada além disso. Os hex desta página são lidos do tokens.css em tempo de carregamento, então não têm como divergir da fonte.
Âmbar, a cor da marca
Como ler a escala: 50 a 200 são brilhos e fundos claros; 300 a 500 são os tons de marca; 600 a 900 são estados pressionados, texto e contraste.
| Token | Uso |
|---|---|
| amber.300 | Amarelo claro oficial. Texto de destaque suave |
| amber.400 | Amarelo oficial. Hover do botão primário, severidade média |
| amber.500 | Âmbar oficial. CTAs, destaques, foco, símbolo do logo |
| amber.800 | Único âmbar aprovado como texto sobre branco. Entra automaticamente no tema claro |
| amber.900 | Escuro oficial. Texto sobre âmbar |
Neutros
| Token | Uso |
|---|---|
| neutral.100 | Texto principal sobre escuro |
| neutral.300 | "SYSTEMS" no wordmark |
| neutral.400 | Texto secundário |
| neutral.500 | Só decorativo. Não passa AA como texto sobre escuro |
| neutral.600 | "SUNNY" no wordmark, bordas fortes, texto secundário no claro |
| neutral.800 | Card sobre escuro |
| neutral.900 | Fundo principal |
| neutral.950 | Fundo de terminal |
Card (neutral.800) sobre fundo (neutral.900) tem contraste de 1.1:1. A separação de superfície depende da borda border.subtle, não da cor. Ela não pode ser removida. Um ajuste do 800 está nas pendências.
Feedback
Três tons por estado: 300 para texto sobre escuro, 500 para ícone e borda, 700 para texto sobre claro. O 500 de cada estado é medido; os 300 e 700 são derivados e precisam de validação visual.
| Estado | 300 texto sobre escuro | 500 ícone e borda | 700 texto sobre claro | De onde veio |
|---|---|---|---|---|
| error | Formulários de lead e --sev-crit |
|||
| success | --sev-ok e "copiado" no DevXOS |
|||
| warning | --sev-high e topologia do RootPilot |
|||
| info | --sev-low |
Por que warning é laranja e não âmbar. O âmbar é a cor da marca e aparece em todo CTA. Se aviso também fosse âmbar, um alerta de custo no Sunshine pareceria um botão. O laranja já é a severidade alta no ScopeWard, então não é cor nova.
Aliases de severidade
Para ScopeWard e RootPilot: severity.critical → error.500, severity.high → warning.500, severity.medium → amber.400, severity.low → info.500, severity.ok → success.500.
Semânticos
Estes são os nomes que você escreve no código. Eles mudam sozinhos quando o tema muda.
| Token | Aponta para | Uso |
|---|---|---|
| bg.base | neutral.900 | Fundo da página |
| bg.card | neutral.800 | Cards |
| bg.elevated | neutral.700 | Popovers, superfícies sobre card |
| bg.terminal | neutral.950 | Mockups de terminal |
| bg.header | alpha.ink-92 | Header ao rolar, com blur |
| text.primary | neutral.100 | Texto corrido e títulos |
| text.secondary | neutral.400 | Descrições, legendas |
| text.accent | amber.500 | Destaque em âmbar |
| text.accent-soft | amber.300 | Destaque suave |
| text.on-accent | amber.900 | Texto sobre botão e badge sólido |
| border.subtle | alpha.white-4 | Borda de card em repouso |
| border.default | alpha.white-8 | Borda de card em hover, inputs |
| border.strong | neutral.600 | Seletor de idioma |
| accent.default | amber.500 | CTAs |
| accent.hover | amber.400 | Hover |
| accent.active | amber.600 | Pressionado |
| accent.soft | alpha.amber-10 | Fundo de badge |
| accent.glow | alpha.amber-7 | Glow do hero |
| focus.ring | amber.500 | Outline 2px, offset 2px |
Tema claro
O escuro é a fundação. O claro existe para documentos, slides e e-mail, e entra com <html data-theme="light">. Use o botão Tema claro no topo desta página para ver a troca acontecer nos exemplos.
| Token | Escuro | Claro |
|---|---|---|
| bg.base | neutral.900 | neutral.0 |
| bg.card | neutral.800 | neutral.50 |
| text.primary | neutral.100 | neutral.900 |
| text.secondary | neutral.400 | neutral.600 |
| text.accent | amber.500 | amber.800 |
| status.*.text | feedback.*.300 | feedback.*.700 |
A troca de text.accent para amber.800 no claro é obrigatória: âmbar 500 sobre branco tem 1.8:1 e não serve para texto. Ver acessibilidade.
Transparências
| Token | Valor | Uso |
|---|---|---|
| alpha.white-4 | rgba(255,255,255,0.04) | Borda de card |
| alpha.white-8 | rgba(255,255,255,0.08) | Borda em hover |
| alpha.amber-7 | rgba(255,182,31,0.07) | Glow radial do hero |
| alpha.amber-10 | rgba(255,182,31,0.10) | Fundo de badge |
| alpha.amber-15 | rgba(255,182,31,0.15) | Linha divisória, drop-shadow da ilustração |
| alpha.amber-30 | rgba(255,182,31,0.30) | Glow forte |
| alpha.ink-92 | rgba(26,26,29,0.92) | Header ao rolar |
Faça e evite
Faça
- Use
text.accentpara âmbar em texto. Ele muda de tom sozinho no tema claro. - Use
status.*para estado. Nunca âmbar para erro ou sucesso. - Use
border.subtlepara separar card de fundo.
Evite
- Hex direto no CSS ou no Figma. Sempre variável.
- Âmbar 500 como texto sobre branco, ou branco como texto sobre âmbar.
- neutral.500 e neutral.600 como texto sobre escuro.
- Criar um quinto tom de amarelo. A história da marca já teve quatro.
Pendências
- Validar visualmente os tons 300 e 700 de feedback.
- Decidir se
bg.cardsobe para algo como #1F2426, para separar debg.basesem depender de borda. - O site importa o
tokens.cssdesde 15/09/2026, mas ainda usa os nomes antigos e tem hex escritos direto no CSS. Ver o passo 3 em versionamento.
Fundações
Tipografia
Três famílias, cada uma com um trabalho. Bricolage Grotesque tem personalidade e fica melhor grande. Inter é neutra e segura o corpo. JetBrains Mono é para qualquer coisa que o leitor possa copiar.
Famílias
| Papel | Família | Pesos | Carregamento |
|---|---|---|---|
| Display, títulos, wordmark | Bricolage Grotesque | 400, 500, 700 | Google Fonts, eixo opsz 12 a 96 |
| Corpo, UI, navegação | Inter | 400, 500, 600, 700 | Google Fonts |
| Código, comandos, IDs, logs | JetBrains Mono | 400, 500, 600 | Google Fonts |
Import único, como o site faz hoje:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,400;12..96,500;12..96,700&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" />
Fallbacks: sans-serif para as duas primeiras, ui-monospace, monospace para a mono. Os arquivos .ttf e .otf estão em Fonts/ na pasta _Sunny-NewBrand26 do Drive, para slides e documentos offline.
Estilos semânticos
Use estes, não os primitivos. Cada um vira um conjunto de variáveis --sunny-type-<nome>-<propriedade>. A amostra à direita é renderizada com o próprio token.
Exemplo de uso:
.hero h1 {
font-family: var(--sunny-type-display-family);
font-size: var(--sunny-type-display-size);
font-weight: var(--sunny-type-display-weight);
line-height: var(--sunny-type-display-line-height);
letter-spacing: var(--sunny-type-display-letter-spacing);
}
Primitivos
Tamanhos em rem sobre raiz de 16px. Os títulos são fluidos com clamp e não trocam por breakpoint.
| Token | Valor | Onde aparece no site |
|---|---|---|
| size.12 | 0.75rem | Badge, cookie, rodapé |
| size.13 | 0.8125rem | Botão pequeno do header, legendas |
| size.14 | 0.875rem | Navegação, labels |
| size.15 | 0.9375rem | Botões |
| size.16 | 1rem | Corpo |
| size.18 | 1.125rem | Descrição do hero |
| size.20 | 1.25rem | Título de card |
| size.22 | 1.375rem | Título de bloco |
| size.fluid-sm | clamp(1.75rem, 3vw, 2.5rem) | Título de seção |
| size.fluid-md | clamp(2rem, 4vw, 3.25rem) | Título de CTA |
| size.fluid-lg | clamp(2.25rem, 4vw, 3.5rem) | Título de produto |
| size.fluid-display | clamp(2.75rem, 5.5vw, 4.25rem) | h1 do hero |
Entrelinha e espaçamento de letras
tight 1.08 display · snug 1.2 títulos · normal 1.6 corpo · relaxed 1.75 descrições longas
tight -0.02em display · snug -0.01em títulos · wide 0.08em overline e badge · wider 0.14em rótulos em caixa alta
Slides e documentos
A escala da doc anterior do site (display 40px, h1 28px, body 12px, caption 9px) era para slides de 16:9 e continua válida só nesse contexto. Em web, use a tabela acima. Em slides: display e títulos em Bricolage Grotesque, corpo em Inter, nunca abaixo de 11px.
Faça e evite
Faça
- Um display por página. Ele é o ponto de luz tipográfico.
- Mono para qualquer texto copiável: comando, ID, trecho de log.
- Mínimo de 16px para corpo em web.
Evite
- Bricolage Grotesque em corpo de texto ou abaixo de 20px.
- Mais de dois pesos na mesma tela além do display.
- Caixa alta fora de overline e do wordmark.
- Recriar o wordmark com texto. Use o arquivo do logo.
Fundações
Espaço, radius e elevação
Base de 4px, radius contido, e sombra só quando há profundidade real. Card em repouso não tem sombra: a separação é por borda.
Espaçamento
Base de 4px. O nome do token é o múltiplo. Toda medida de layout é múltiplo de 4; valores quebrados só em ajuste óptico de ícone, e com comentário.
| Token | Uso típico |
|---|---|
| space.1 | Gap mínimo, entre ícone e texto pequeno |
| space.2 | Gap padrão, padding de badge |
| space.3 | Padding de input, gap de linha |
| space.4 | Padding interno de card pequeno |
| space.6 | Padding de card, gap de grid |
| space.8 | Padding de card grande, gap de navegação |
| space.12 | Separação de blocos |
| space.16 | Gap do grid do hero |
| space.section | Padding vertical de seção |
O Omnibus da ClickBus usa base 8. A Sunny usa base 4 porque o site já é assim e porque 12px aparece muito em UI densa de produto. Os múltiplos de 8 continuam sendo os preferidos para layout.
Radius
A marca é contida: botão com 4px, card com 12px. Não usar 16px ou mais fora de pill.
Isso diferencia a V4 do Sunshine app, que usa arredondamento generoso. É uma decisão a revisitar quando o Sunshine adotar estes tokens.
Elevação
Duas famílias: glow em âmbar para destaque, elevation em preto para profundidade. Glow é raro: um por viewport, no elemento que merece o olhar.
Glass
Receita única: fundo bg.header ou alpha.white-4, backdrop-filter: blur(var(--sunny-blur-card)), borda border.subtle. Texto sobre glass é sempre text.primary, nunca text.secondary, porque o fundo varia.
| Token | Valor | Uso |
|---|---|---|
| blur.header | 20px | Header ao rolar, sobre bg.header |
| blur.card | 24px | Cards translúcidos sobre glow |
Ver o glass aplicado no componente Card.
Movimento
| Token | Valor | Uso |
|---|---|---|
| motion.duration.fast | 0.15s | Transform em hover de botão |
| motion.duration.base | 0.2s | Cor, borda, opacidade |
| motion.duration.slow | 0.3s | Header, cards, revelações |
| motion.easing.default | ease | Tudo |
Regra: particle network no hero, tilt 3D em cards, contadores animados, parallax e shimmer desligam sob prefers-reduced-motion: reduce, e todo efeito novo precisa da mesma cláusula.
Estado real em 14/10/2026: o site cumpre a regra quase toda desde o website#10. Uma regra global no style.css encurta animações e transições dos seis CSS, e cada efeito de effects.ts sai cedo. Faltam três efeitos em JavaScript sem guarda: o contador do gauge do ScopeWard e a rotação automática dos carrosséis do ScopeWard e do RootPilot.
Breakpoints
| Token | Valor | O que muda |
|---|---|---|
| breakpoint.md | 768px | Menu vira mobile, grids viram uma coluna |
| breakpoint.lg | 1024px | Grids de quatro viram dois |
| breakpoint.container | 1200px | Largura máxima do conteúdo |
Ícones
Têm página própria: Ícones. A proposta de Lucide em todos os produtos está na decisão 0008.
Fundações
Logo
Um sol em semicírculo cortado por faixas horizontais, e um wordmark em duas linhas. Sem raios: é isso que separa a V4 das identidades de 2021 e 2023.
As treze versões oficiais (Hor, Vert, Icon e Name) estão em assets/v4/ deste repositório, exportadas da pasta Logo-Sunny26 do Drive e conferidas com os arquivos de lá em 14/10/2026. O símbolo abaixo é o Icon-Positive.svg inline, com o fill trocado para currentColor para herdar o âmbar do tema.
Anatomia
Símbolo. Semicírculo de sol em âmbar cortado por faixas horizontais irregulares. Lê-se como um nascer do sol visto através de listras.
As faixas não são paralelas: são cunhas de espessura variável. As de baixo passam da largura do semicírculo e apoiam em uma base sólida, o que dá ao desenho uma proporção deitada de 380 por 245, não um quadrado.
Wordmark. "SUNNY" em caixa alta bold e "SYSTEMS" em caixa alta light, alinhado à direita sob "SUNNY". No arquivo é desenho em outline, e as letras não são Bricolage Grotesque: o N tem o topo arredondado. Não recrie o lockup em texto.
A moldura tracejada marca a área de proteção: mínimo igual à altura do "S" de "SUNNY" em todos os lados.
Cores medidas em Logo-Hor-Color.svg
| Elemento | Hex | Token |
|---|---|---|
| Símbolo | amber.500 | |
| SUNNY | neutral.600 | |
| SYSTEMS | neutral.300 |
Versões
| Versão | Composição | Fundo |
|---|---|---|
| Logo Hor Color | Símbolo âmbar + wordmark cinza, horizontal | Branco e claros |
| Logo Hor White | Símbolo âmbar + wordmark branco, horizontal | Escuro |
| Logo Hor Positive | Tudo escuro | Claros, impressão P&B |
| Logo Hor Negative | Tudo claro | Escuros, impressão P&B |
| Logo Vert * | Símbolo sobre wordmark, mesmas quatro composições | Quadrados, avatar, capa |
| Icon Color / Positive / Negative | Só o símbolo | Favicon, app icon, avatar pequeno |
| Name Positive / Negative | Só o wordmark | Rodapé, assinatura |
Formatos: .ai, .svg, .pdf e PNG em 1.5x, 2x, 3x e 4x.
Galeria
Os arquivos de assets/v4/, cada um no fundo para o qual existe.
Medido no logo-hor-white.png do site: símbolo âmbar, "SUNNY" e "SYSTEMS" em branco. A documentação anterior do site descrevia essa versão como "totalmente branca"; não é. A versão toda branca é a Negative. Sobre fundo âmbar, portanto, usar Negative ou Positive, nunca a White, porque o símbolo âmbar some.
Regras
Escolha por espaço
Largo usa o horizontal. Quadrado usa o vertical. Pequeno demais para o nome usa só o ícone, e só quando "Sunny Systems" já está no contexto.
Escolha por fundo
| Fundo | Versão |
|---|---|
| Escuro | Logo Hor White |
| Âmbar | Logo Hor Positive ou Negative |
| Branco ou claro | Logo Hor Color |
| Foto ou gradiente | White |
| Impressão monocromática | Positive ou Negative |
Sobre foto: aplicar o White em área com contraste. Se não houver, colocar um bloco de bg.base atrás.
Faça
Não faça
Tamanho mínimo
22px de altura para o horizontal em tela, que é o menor uso no site hoje. Abaixo disso, usar só o Icon. Em impressão, 12mm de altura.
Não faça
- Alterar cores, inclusive trocar o cinza do wordmark por âmbar.
- Distorcer, rotacionar ou espelhar.
- Aplicar sombra, glow, contorno ou gradiente sobre o logo. O glow é do fundo, não do logo.
- Recriar o wordmark com texto ao vivo.
- Usar Logo Hor Color sobre escuro. O cinza neutral.600 some.
- Usar o símbolo V1 ou V2, com raios, em material novo.
- Gerar o logo, ou uma variação dele, com IA.
- Passar a versão Color para cinza. Se a cor precisa sumir, use Positive ou Negative.
Em código
<!-- escuro --> <img src="/images/logo-hor-white.svg" alt="Sunny Systems" width="160" height="42" /> <!-- claro --> <img src="/images/logo-hor-color.svg" alt="Sunny Systems" width="160" height="42" />
alt é sempre "Sunny Systems". Se o logo é link para a home, o alt continua "Sunny Systems" e o link recebe aria-label="Sunny Systems, página inicial".
No site hoje
| Contexto | Arquivo | Altura |
|---|---|---|
| Header | logo-hor-white.png | 28px |
| Rodapé | logo-hor-white.png | 22px |
| Favicon | favicon-32.png | 32px |
| Apple touch | apple-touch-icon.png | 180px |
| Open Graph | og-image.png | 1200×630 |
Em movimento
Loops curtos que ensinam a regra. O arquivo estático continua sendo a fonte; o movimento só demonstra. Cada loop tem botão de pausa e fica parado sob prefers-reduced-motion.
Pendências
- Registrar no Drive a fonte de origem do wordmark.
- Substituir os PNG do repositório do site pelos SVG.
- Um arquivo por versão no site, referenciado de
/images/, em vez de cópia por produto. - O SVG do SunnyNet traz "SYSTEMS" em cinza. O oficial, no Drive, é branco.
- Gerar a imagem Open Graph com acentos corretos. Ver assets digitais.
- Avatar social: proposta na decisão 0009. Ver assets digitais.
Fundações
Ícones
PropostaDois tipos de ícone. O de interface é Lucide, em 16, 20 ou 24px, com a cor herdada de currentColor. O de marca é o sol, nas três versões de ícone.
Depende da decisão 0008. Até ela ser aceita, este é o conjunto para site, landing e chrome, e os produtos seguem como estão. Hoje o site usa SVG inline desenhado à mão, sem biblioteca, e o Sunshine app usa Lucide.
Tamanhos
Traço 1.5px, pontas e junções arredondadas, fill: none. O Lucide vem com traço 2px: passe 1.5 explicitamente. Acima de 128px, ícone de conceito vira ilustração, e Lucide não vai para o hero.
Marca
O sol não ganha versão em traço e não entra na galeria de interface.
Interface
Ação
Status
A cor vem de color.status.*.icon. Nunca âmbar para erro, aviso ou sucesso.
Produto
É o recorte usado no guia, com o nome de cada ícone no Lucide. Precisou de outro, use o do Lucide com as mesmas regras.
Faça e evite
Faça
- Um traço só, 1.5px, com pontas arredondadas e cor herdada.
- Ícone sem texto com
aria-labelno controle. Ícone ao lado de texto comaria-hidden="true". - Status na cor semântica, não no âmbar.
Evite
- Baixar pacote de ícones de outro cliente ou de banco de imagens.
- Juntar dois ícones para inventar um terceiro.
- Rotacionar, preencher, esticar ou gerar com IA.
Fundações
Assets digitais
PropostaFavicon, avatar e ícone de canal usam só o sol, porque o nome já está no contexto da aba ou do perfil. O Open Graph usa o lockup horizontal, porque o card de um link não carrega o nome sozinho.
bg.base. No ar como favicon-32.png. Abaixo de 22px de altura, nunca o horizontal.bg.base, sem wordmark. Quadrado com cantos suaves. Se a plataforma corta em círculo, o sol cabe inteiro nele.bg.base. O do site tem acentos errados e precisa ser gerado de novo.
Não gerar favicon, Open Graph, avatar ou capa com IA. Todo arquivo parte de assets/v4/. Sobre âmbar, Icon Negative ou Positive, nunca Color.
Depende da decisão 0009. O arquivo-fonte da capa do YouTube não foi localizado no Drive.
Componentes
Índice e maturidade
O que existe, onde está implementado e o quanto dá para confiar. Estes são os componentes da camada de marca: o que aparece em site, landings, slides e no chrome dos produtos. Componente interno de produto fica no produto.
| Componente | Categoria | Maturidade | Implementado em | Tokens |
|---|---|---|---|---|
| Button | Atom | Stable | Site, cinco landings | button.* |
| Badge | Atom | Stable | Site, cinco landings | badge.* |
| Card | Molecule | Stable | Site, cinco landings | card.* |
| Input | Atom | Beta | Landings RootPilot e Soberania | input.* |
| Nav item | Atom | Stable | Header do site | nav.* |
| Header | Organism | Stable | Site, cinco landings | header.* |
| Stat | Molecule | Stable | Site, cinco landings | Sem token próprio |
| Terminal mockup | Molecule | Beta | ScopeWard, DevXOS, Sunshine | terminal.* |
| Toast, Alert, Modal, Tabela | Proposta sem código | color.status.* |
Stable em produção com valores medidos. Beta implementado em um lugar, pode mudar. Proposta só documentado.
Regras comuns
- Só tokens semânticos e de componente. Nenhum hex.
- Todo estado interativo tem default, hover, focus-visible, active e disabled.
- Foco é sempre
focus.outlinecomfocus.offset. - Alvo de toque mínimo de 44 por 44px em mobile.
- Transições usam
motion.duration.*; nada anima sobprefers-reduced-motion. - Texto vem de props ou i18n, nunca fixo no componente.
Critérios para entrar no índice
Default, hover, focus, active e disabled, todos desenhados.
Padding, gap, altura e radius em px, ligados a tokens.
Teclado, ARIA, contraste medido e alvo de toque.
Implementado em pelo menos um produto, ou marcado como "sem código".
Detalhe completo em como contribuir.
Componentes · Atom
Badge
StableRótulo curto acima de um título ou ao lado de um item: categoria, novidade, status neutro. Não é botão e não é filtro. Implementado como .badge.
A versão com fundo âmbar sólido e texto escuro, descrita na doc anterior do site, não está em uso e sai.
Anatomia
Tipo: type.overline, Inter 600, 12px, caixa alta, letter-spacing 0.08em, line-height 1 · Padding: 6px 16px · Radius: radius.full
- Display
inline-flex. Com ícone: 12px à esquerda, gapspace.1. - Sem borda. Sem sombra. Sem hover: badge não é interativo.
Uso
<span class="badge">Solution Provider</span> <span class="badge badge-success">Ativo</span>
Acessibilidade
- Contraste medido: âmbar sobre badge sobre card, 9.4:1
- Caixa alta é feita por CSS. O HTML fica em caixa normal, para o leitor de tela ler palavras e não letras
- Status nunca só por cor: o texto diz o estado
- Badge decorativo que repete o título recebe
aria-hidden="true"
Componentes · Molecule
Card
StableSuperfície que agrupa título, texto e, às vezes, uma ação sobre um mesmo assunto. Um card é um bloco de leitura, não um botão gigante. Implementado como .pillar-card, .service-card e .product-card.
Playground
card.*Passe o mouse no card para ver o hover dos tipos interativos.
Observabilidade
O RootPilot lê métricas, logs e custos da sua stack e responde perguntas de engenharia em um só lugar.
<article class="pillar-card"> <h3>Observabilidade</h3> <p>O RootPilot lê métricas, logs e custos…</p> </article>
Tipos
| Tipo | Interação | Uso |
|---|---|---|
| Estático | Nenhuma | Pilares, serviços |
| Com ação | Um link ou botão dentro | Produto com "Saiba mais" |
| Inteiramente clicável Beta | O card todo é um <a> | Lista de produtos no menu |
Anatomia
- Fundo
card.bg. Bordacard.border, 1px branco a 4%. Radiuscard.radius, 12px. - Padding
card.padding, 32px, em.service-carde.product-card. Em mobile,space.6, 24px. - O
.pillar-cardusa 48px 32px, medido. Diverge do token e ainda não foi decidido se o token sobe ou se o card desce. - Ordem interna: ícone ou glifo 40px, título
type.heading-5, textotype.bodyemtext.secondary, ação. - Gap entre título e texto
space.3; entre texto e açãospace.6. - Sem sombra em repouso.
- Faixa de acento de 3px no topo: existe, medida em 14/09/2026. O
.pillar-cardusa um dos três amarelos por posição; o.product-cardusa--accent, injetado inline por produto. A documentação anterior afirmava que a faixa não existia, e estava errada.
Estados
| Estado | Mudança |
|---|---|
| Default | Borda border.subtle |
| Hover, só nos clicáveis | translateY(-4px) e borda âmbar a 12% no .pillar-card, medido. A documentação anterior dizia -2px e branco 8%, e estava errada |
| Focus-visible, só nos clicáveis | focus.outline no card inteiro |
| Tilt 3D | Efeito do site. Desliga com reduced motion e não é obrigatório |
Glass
Sobre glow ou imagem, o card vira glass: fundo alpha.white-4, backdrop-filter: blur(var(--sunny-card-blur)), mesma borda. Texto sempre text.primary, porque o fundo varia. Ative o controle no playground acima para ver.
Grid
Quatro colunas em desktop, duas abaixo de breakpoint.lg, uma abaixo de breakpoint.md. Gap space.6. Cards da mesma linha têm a mesma altura.
Acessibilidade
- Título do card é heading real, na hierarquia da página
- Card inteiramente clicável é um único
<a>com o título como texto principal. Nada interativo dentro dele - Contraste medido: texto principal sobre card 12.3:1, secundário sobre card 5.1:1
A separação entre card e fundo é 1.1:1 por cor. A borda é o único limite visual, então ela não pode ser removida.
Componentes · Atom
Input
BetaCampo de texto de uma linha com rótulo acima e mensagem de erro abaixo. Implementado em sovereign.css e rootpilot.css como .lead-field. Único formulário do site: captação de lead.
Playground
input.*O campo é real: clique nele para ver o foco de verdade, com a borda âmbar.
Digite um e-mail válido
<div class="lead-field">
<label for="email">E-mail corporativo</label>
<input id="email" name="email" type="email"
autocomplete="email" placeholder="voce@empresa.com.br" required />
</div>
Anatomia
| Parte | Especificação |
|---|---|
| Rótulo | input.label: JetBrains Mono 600, 0.7rem, caixa alta, letter-spacing 0.12em, text.secondary. 6px acima do campo |
| Campo | Fundo input.bg, borda 1px border.default, radius radius.md, padding 12px 14px, texto branco 0.95rem em Inter |
| Placeholder | text.secondary com opacidade 0.65 |
| Erro | input.error.fg, 12px, abaixo do campo, aparece só com .invalid |
Dois valores medidos fogem da escala: padding horizontal 14px e fonte 0.95rem. Proposta: 16px e font.size.15. Muda quase nada na tela e alinha com o botão.
Estados
| Estado | Mudança |
|---|---|
| Default | Como na anatomia |
| Hover | Fundo input.bg-hover, branco a 5.5% |
| Focus | Borda accent.default, fundo input.bg-focus, âmbar a 4%. O site remove o outline nativo; a borda âmbar faz o papel de foco |
| Invalid | Borda status.error.border, fundo status.error.bg, mensagem visível |
| Disabled proposta | Opacidade 0.5, cursor: not-allowed |
Variantes
Só texto de uma linha hoje: nome, e-mail, empresa, telefone. Textarea, select e checkbox são proposta. O checkbox de consentimento do formulário já existe como .lead-check, com foco visível por focus.outline na caixa.
Acessibilidade
<label for>sempre, mesmo com placeholder. Placeholder não é rótuloautocompletecorreto em cada campo:name,email,organization,tel- Inválido:
aria-invalid="true"earia-describedbyapontando para a mensagem - A mensagem diz o que fazer, não só "inválido"
- Erro nunca só por cor: a borda vermelha vem com texto
- Foco: a borda âmbar dá 9.9:1 sobre o fundo e substitui o outline. Se o fundo mudar, voltar ao
focus.outline
Contraste medido
| Par | Contraste | Situação |
|---|---|---|
| Texto branco sobre campo | 17:1 | passa |
| Placeholder a 65% de neutral.400 | < 4.5:1 | Aceitável: placeholder não é conteúdo, o rótulo é |
| Rótulo mono 0.7rem | 11px | No limite. Não reduzir mais |
Componentes · Organism
Header
StableBarra fixa do site. Logo à esquerda, navegação com o CTA, e à direita o seletor de idioma e, no mobile, o botão de menu. Transparente no topo, opaca e com blur depois de rolar.
Estado rolado
header.*Anatomia
position: fixedno topo,z-index: 100. Padding verticalspace.4(16px), conteúdo em container de 1200px comspace.6(24px) nas laterais. Perto de 73px de altura, calculado.- Logo: Logo Hor White, 28px de altura, link para a home. No rodapé, 22px. Hoje é PNG; o SVG está em
assets/v4/. - Navegação: itens de Nav item com
nav.gap(32px). O CTA é.btn-primarycompacto, padding 10px 24px e 0.813rem, dentro do<nav>. - Ações: seletor de idioma e, abaixo de 768px, o botão de menu, com gap
space.4.
Estados
| Estado | Fundo | Borda inferior | Quando |
|---|---|---|---|
| Topo | Transparente | Nenhuma | scrollY até 50px |
| Rolado | header.bg-scrolled + header.blur | header.border-bottom, âmbar 8% | Acima de 50px, classe .scrolled |
| Menu aberto | Painel em tela cheia, ink a 98% com blur 20px | Mobile, aria-expanded="true" |
Fundo e blur fazem transição em motion.duration.slow; a borda entra sem transição. O ink a 98% do painel mobile não tem token.
Mobile
Abaixo de breakpoint.md (768px), hambúrguer de três barras de 24×2px que vira X ao abrir. O painel ocupa a tela, com itens em coluna, gap de 32px e texto de 20px. Clicar em um link fecha o menu.
Acessibilidade
- Skip-link "Pular para o conteúdo" antes do header, para
#main-content. Desce para 16px do topo no foco, fundoamber.500, textoamber.900. <header role="banner">e<nav aria-label="Navegação principal">.- Logo com
alt="Sunny Systems". O link da home ainda não temaria-label; o padrão de Logo pede "Sunny Systems, página inicial". - O Logo Hor White passa sobre o header nos dois estados. O Hor Color some no escuro.
- O CTA é o único botão primário da barra.
O botão de menu ainda não tem: aria-controls, fechar com Esc, levar o foco para o menu e devolver ao botão, travar a rolagem do fundo. São pendências, não opções.
Pendências
- Trocar o PNG do logo pelo SVG.
- Os atributos
widthdo logo no HTML (180 e 140) não batem com a largura renderizada, perto de 107 e 84px. - A home não marca o item ativo da navegação com
aria-current. - Confirmar no navegador se o
backdrop-filterdo estado rolado prende o painel mobile à altura do header.
Componentes · Molecule
Stat
StableNúmero de destaque com rótulo curto, em uma faixa âmbar. Um stat não é um gráfico: é um número que o leitor guarda.
Vitrine com o rótulo já corrigido para text.on-accent sólido. O site usa amber.900 a 65% ou 70%, que falha AA. Ver Acessibilidade.
Anatomia
- Faixa:
color.amber.500com gradiente animado atéamber.600. Padding vertical de 80px, 60px no mobile. - Número: Bricolage Grotesque 700, line-height 1,
text.on-accent. - Rótulo: Inter 500,
space.2abaixo do número.
| Home | Landings | |
|---|---|---|
| Número | clamp(2.25rem, 4vw, 3.5rem) | clamp(1.8rem, 3.5vw, 2.75rem), -0.02em |
| Rótulo | 14px, alpha 65% | 0.8rem, alpha 70% |
| Layout | Flex centralizado, gap space.16 | Grid de 4 colunas, gap space.8 |
| Até 768px | Uma coluna, gap 32px | Duas colunas, gap de 16 ou 24px conforme a landing |
As landings não concordam entre si nos breakpoints. Alinhar é pendência.
Estados
Nenhum. O stat não é interativo. Na home e no RootPilot o número conta de 0 até o valor em 1,8s quando aparece na tela, uma vez só, e não conta sob prefers-reduced-motion: reduce.
Regras
- Número com unidade e contexto: "5 min de MTTR típico em incidente", não "5". Nunca abreviar como "48.2k".
- Faixa âmbar, texto escuro. Número e rótulo em
text.on-accent. - A variante com número âmbar sobre fundo escuro não existe no código. Se for desejada, entra como proposta.
Acessibilidade
- Número: 7.9:1 sobre amber.500 e 6.3:1 sobre amber.600. Passa.
- Rótulo falha AA. A 65% dá 3.5:1 e 3.2:1; a 70%, 4.0:1 e 3.5:1. Texto de 13 a 14px pede 4.5:1. Correção:
text.on-accentsólido. - O título da faixa da home está fixo em inglês, "The Sunny Facts", inclusive no
aria-label. Deve vir do i18n.
Componentes · Molecule
Terminal mockup
BetaJanela falsa que emoldura uma saída de terminal ou um relatório. Serve para dizer “isto é output real de ferramenta”, não para ser interativo: nenhum dos três dots faz nada.
$ scopeward audit # 80 checks, 0 falhas
$ sunshine report # custo por nó, 30d
Os três dots não são as cores da janela do macOS. Eram, nas três landings, e o amarelo do macOS era um quinto amarelo na tela. Passaram a vir da paleta da marca na decisão 0007.
Os três dots
São posicionais, não semânticos: esquerda, meio e direita de um chrome de janela. Fecham nada, avisam nada, confirmam nada.
| Token | Valor | Vem de |
|---|---|---|
| terminal.dot-close | #FF5D5D | color.feedback.error.500 |
| terminal.dot-min | #FFB61F | color.amber.500 |
| terminal.dot-max | #6FCF97 | color.feedback.success.500 |
Reusar as cores de feedback aqui não contraria a regra da decisão 0004 de que âmbar nunca significa estado. Essa regra vale para o que comunica estado ao usuário; o dot do meio não comunica nada. O proibido continua sendo o inverso — âmbar dizendo “atenção” numa mensagem real.
Anatomia
Barra: padding 11px space.4, borda inferior 1px branco 5% · Dots: terminal.dot-size (11px), radius.full, gap 7px · Corpo: JetBrains Mono 0.8rem (12,8px), line-height 1.75, padding space.6, medido no ScopeWard · Janela: radius.lg, borda color.alpha.white-6, sombra shadow.elevation.lg
- A variante quente não é decoração:
terminal.bg-warmé um preto com âmbar dentro, e trocá-lo pelo neutro muda a página de forma perceptível (ΔE 5.2 no corpo, 7.6 na barra). - Use a neutra por padrão. A quente só onde o fundo da página já é quente — hoje, só o Sunshine.
Uso
<div class="term">
<div class="term-bar" aria-hidden="true">
<span class="term-dot"></span>
<span class="term-dot"></span>
<span class="term-dot"></span>
</div>
<pre class="term-body">$ scopeward audit</pre>
</div>
Acessibilidade
- Os três dots são decorativos:
aria-hidden="true"na barra. Um leitor de tela não deve anunciar “vermelho amarelo verde” antes do conteúdo - Contraste medido do texto primário sobre o corpo: 14.2:1 na neutra, 14.1:1 na quente. Os dois passam AAA
- Barra e corpo se separam por 1.09:1 (neutra) e 1.04:1 (quente) — por isso a borda inferior da barra é obrigatória: é ela que dá o limite, não a diferença de fundo
- O corpo é texto de verdade, nunca imagem de texto. Saída longa rola no corpo, não na janela
Padrões
Acessibilidade
WCAG 2.1 nível AA em tudo que a Sunny publica. Não é polimento: par de cor que falha não vira token, componente sem foco visível não entra no índice.
Contraste mínimo
| Nível | Texto normal | Texto grande | Componentes e ícones |
|---|---|---|---|
| AA, obrigatório | 4.5:1 | 3:1 | 3:1 |
| AAA, desejável em títulos | 7:1 | 4.5:1 |
Texto grande é 24px, ou 19px em bold.
Checagem automática
node tokens/check-contrast.mjs lê os tokens semânticos e falha o PR se um par obrigatório não atinge o mínimo. Resultado em setembro de 2026: todos passam.
| Par | Contraste | Mínimo |
|---|---|---|
| Texto principal sobre fundo | 13.0:1 | 4.5 |
| Texto principal sobre card | 12.3:1 | 4.5 |
| Texto secundário sobre fundo | 5.4:1 | 4.5 |
| Texto secundário sobre card | 5.1:1 | 4.5 |
| Texto âmbar sobre fundo | 9.9:1 | 4.5 |
| Texto sobre botão primário | 7.9:1 | 4.5 |
| Texto sobre botão primário em hover | 8.6:1 | 4.5 |
| Badge sobre card | 9.4:1 | 4.5 |
| Link sobre header | 13.0:1 | 4.5 |
| Anel de foco sobre fundo | 9.9:1 | 3 |
| Feedback: texto sobre fundo | 7.5 a 11.2:1 | 4.5 |
| Feedback: ícone sobre fundo | 5.8 a 9.1:1 | 3 |
| Tema claro: amber.800 sobre branco | 6.2:1 | 4.5 |
| Tema claro: feedback 700 sobre branco | 5.0 a 6.3:1 | 4.5 |
O texto secundário sobre card está perto do limite, em 5.1:1. Qualquer clareamento do card ou escurecimento do cinza quebra o par.
Pares proibidos
Medidos e reprovados. Não usar como texto.
| Par | Contraste |
|---|---|
| Âmbar 500 sobre branco | 1.8:1 |
| Branco sobre âmbar 500 | 1.8:1 |
| Neutral 500 sobre fundo escuro | 2.6:1 |
| Neutral 600 sobre fundo escuro | 1.5:1 |
Em fundo claro, âmbar em texto é sempre amber.800. Sobre botão âmbar, texto é sempre amber.900.
Limites conhecidos
- Card sobre fundo tem 1.1:1. A borda
border.subtleé o único limite visual e não pode ser removida. - Borda do seletor de idioma tem 1.5:1. Aceitável porque o botão tem texto. Não reutilizar em controle sem texto.
- Placeholder de input fica abaixo de 4.5:1. Aceitável porque placeholder não é conteúdo; o rótulo é.
Checklist geral
Vale para qualquer página, slide exportado para web ou e-mail.
- Contraste de texto e ícone conforme a tabela
- Navegação completa por teclado, na ordem visual
- Foco sempre visível:
focus.outline2px âmbar, offset 2px - Skip-link antes do header
- Todo controle com rótulo; ícone sem texto com
aria-label - Estado nunca só por cor: ícone ou texto junto
- Formulário com
label for,autocomplete,aria-invalidearia-describedby - Imagem informativa com
altque descreve; decorativa comalt="" - Logo com
alt="Sunny Systems" <html lang>correto e atualizado ao trocar idioma- Um
h1por página, hierarquia sem pulos prefers-reduced-motiondesliga partículas, tilt, parallax, shimmer e contadores- Zoom a 200% sem perda de conteúdo
- Reflow a 320px sem scroll horizontal
- Alvo de toque de 44px em mobile
- Vídeo e GIF de demo com descrição textual ao lado
Faça e evite
Faça
- HTML semântico
<button>para ação e<a>para navegaçãoaria-expandedno menu mobilearia-current="page"no item ativoaria-live="polite"no retorno do formulário
Evite
divclicável- Esconder conteúdo só com opacidade
- Comunicar erro só com borda vermelha
- Animação sem alternativa
- Texto em imagem sem equivalente em HTML
Padrões
Voz
Como a Sunny Systems escreve. Vale para site, landings, propostas, e-mails, posts e mensagens de produto.
Princípios
Vai ao ponto. Frases curtas. O leitor é ocupado.
Fala com CTO e com CFO na mesma frase. Sigla sempre com explicação na primeira vez.
Mostra expertise com fato e número, não com superlativo.
Português do Brasil natural. Sem tradução literal de inglês, sem "performar", sem "endereçar problema".
Idioma
pt-BR é o idioma primário. Inglês é a versão alternativa do site e de materiais para parceiros globais. Termos técnicos consagrados ficam em inglês: observability, FinOps, platform engineering, on-premises. Não traduzir "deploy" nem "pipeline". Traduzir "monitoring" para monitoramento e "cost" para custo.
Evite e prefira
| Evite | Prefira |
|---|---|
| Travessão em texto corrido | Dois-pontos, vírgula ou nova frase |
| "Soluções inovadoras" | O que a solução faz, em verbo |
| "De ponta a ponta" | Lista do que está incluso |
| "Somos os melhores" | "X% de economia em Y dias" |
| "Alavancar", "endereçar", "performar" | "Usar", "resolver", "rodar" |
| Voz passiva | "Implementamos", "entregamos", "medimos" |
| Ponto de exclamação | Ponto final |
| Emoji em texto institucional | Nenhum |
Exemplos
"Oferecemos soluções inovadoras de ponta a ponta para modernização de infraestrutura."
"Migramos sua infraestrutura para a nuvem, do planejamento ao go-live, com foco em disponibilidade e custo."
"Nossa plataforma alavanca IA para endereçar os desafios de observabilidade."
"O RootPilot lê métricas, logs e custos da sua stack e responde perguntas de engenharia em um só lugar."
Nomes
- Sunny Systems, sempre com S maiúsculo nos dois, nunca "Sunny" sozinho em texto institucional. "Sunny" sozinho só em conversa informal e no wordmark.
- Produtos: RootPilot, ScopeWard, DevXOS, Sunshine, Soberania de IA. Grafia fixa, sem espaço, sem hífen.
- Tagline: "Seu parceiro estratégico em tecnologia, do produto à operação." Em inglês: "Your strategic partner in technology, from product to operations."
Microcopy de produto
- Botão diz o que acontece: "Falar com a Sunny", não "Enviar"
- Erro diz o que fazer: "Digite um e-mail válido", não "Campo inválido"
- Estado vazio diz o próximo passo, em uma frase
- Número sempre com unidade e período: "R$ 48,2 mil este mês", não "48.2k"
Governança
Como contribuir
Fluxo para mudar ou adicionar algo na marca: token, componente, regra ou asset. Sem SLA de revisão nem reunião fixa.
Fluxo
- Já existe? Procure neste guia e no
tokens.json. Se existe, use como está. Não sobrescreva com estilo local. - É ajuste ou é novidade? Ajuste de valor medido errado, texto ou exemplo: abra PR direto. Cor, fonte, componente, regra ou mudança visual grande: abra uma decisão primeiro, com contexto, opções e recomendação.
- Faça no token, não no CSS. Se a mudança é de valor, ela entra em
tokens.json, roda o build e o check de contraste, e otokens.cssgerado vai junto no PR. - PR para
maincom um approval de alguém com contexto de marca. Mudança visível para usuário avisa no PR o que muda na tela e onde. - Registre. Mudança que altera decisão anterior ganha uma nova decisão, nunca edita a antiga.
Critérios de entrada
- Tem uso em pelo menos dois lugares, ou é semântico obrigatório para tema
- Passa no check de contraste nos pares em que será usado
- Tem status honesto: medido, derivado ou proposta
- Variantes, estados, anatomia com medidas e API ou classes
- Seção de acessibilidade: teclado, ARIA, contraste, alvo de toque
- Só tokens semânticos ou de componente
- Implementado em pelo menos um produto, ou marcado como "sem código"
Regra nova entra se resolve uma dúvida que apareceu de verdade. Regra preventiva vira ruído.
Checklist do PR
node tokens/build.mjsrodou etokens.cssestá atualizadonode tokens/check-contrast.mjspassa- Nenhum hex novo fora de
tokens.json - Texto em pt-BR, sem travessão em prosa
- Se muda visual: screenshot ou link antes e depois
- Se muda decisão: arquivo novo em
decisoes/ CHANGELOG.mddos tokens atualizado, se tocou em token
O que fica fora deste repositório
- Componentes internos de produto: tabelas, gráficos, drawers do Sunshine. Ficam no produto, consumindo tokens daqui.
- Copy final de marketing.
- Configuração de build dos sites.
Governança
Versionamento e adoção
O pacote tokens/ segue Semantic Versioning. A versão fica em tokens/CHANGELOG.md. Hoje: 0.2.0.
Semver dos tokens
| Nível | Quando | Exemplo |
|---|---|---|
| MAJOR | Token removido ou renomeado, valor de marca trocado, tema padrão alterado | accent.default deixa de ser amber.500 |
| MINOR | Token novo, tema novo, alias novo, componente novo | color.status.* adicionado |
| PATCH | Correção de valor medido errado, doc, exemplo, comentário | space.section de 96 para 100px |
Mudança de status de um token, de proposta para medido, é PATCH se o valor não mudou e MINOR se mudou.
Maturidade
Em produção em pelo menos um produto, valores medidos.
Documentado e implementado em um lugar, pode mudar.
Só documentado, sem código.
Sai na próxima MAJOR. O substituto está indicado.
Breaking change
Nunca sem alternativa. Token renomeado mantém o nome antigo como alias por uma MAJOR inteira, no bloco de compatibilidade do tokens.css. Mudança visual grande é avisada no PR antes de mergear, não só no changelog.
Plano de adoção pelo site
A migração é em três passos, sem big bang. Os passos 1 e 2 estão feitos desde o website#14, em 15/09/2026. O passo 3 está em andamento.
- Copiar (feito) o
tokens.csspara o site e importar antes dostyle.css. O bloco de compatibilidade garante que--color-amber,--space-lge os demais nomes atuais continuem funcionando. Nada muda na tela. - Remover (feito) os
:rootduplicados destyle.csse dos seis CSS de produto. Os--sev-*do ScopeWard passam a vir dotokens.css. - Trocar (em andamento) gradualmente os nomes antigos pelos semânticos novos, arquivo por arquivo, e apagar o bloco de compatibilidade na MAJOR seguinte.
Depois do passo 1, este repositório é a origem. O site consome uma versão fixa e atualiza por PR.
Esta página já está no passo 1: ela importa o tokens.css deste repositório e não define nenhum valor de cor próprio. Todo hex que você vê aqui é lido do arquivo em tempo de carregamento.
Sunshine e outros produtos
Mesmo caminho, com um passo extra: mapear os tokens OKLCH do Sunshine app para os semânticos daqui. O radius contido da V4 é a diferença mais visível e pede uma decisão antes da adoção.
Governança
Quem procurar
Direcione a dúvida por assunto. Assíncrono, por PR ou issue no repositório.
| Dúvida sobre | Procure |
|---|---|
| Decisão de marca, aprovação de mudança visual, prioridade | Fabio Trentini, mantenedor do repositório |
| Tokens, build, contraste, adoção pelo site | @sunnysystems/engineers |
| Arquivos de logo, fontes e paleta no Drive | Fabio Trentini |
| Voz e copy | A definir |
| Design system do Sunshine app | Time do Sunshine |
Este quadro reflete setembro de 2026, quando há um mantenedor. Ao entrar mais gente, atualize aqui e no CODEOWNERS no mesmo PR.
Perguntas frequentes
Posso usar #FFB61F direto no CSS?
Não. Use var(--sunny-color-accent-default) ou o alias --color-amber. Hex direto quebra tema e auditoria.
Preciso de uma cor que não existe.
Abra uma decisão em docs/decisoes/ com o caso de uso. Quase sempre a resposta é um semântico novo apontando para um primitivo que já existe.
O site ainda não usa o tokens.css. Onde eu mudo uma cor hoje?
No tokens.json daqui, e depois espelha no style.css do site no mesmo dia. Depois da adoção, só aqui.
Qual logo uso em slide escuro?
Logo Hor White. Em slide claro, Logo Hor Color. Ver logo.
As propostas Convergence, Aurora e Radiance valem?
Não como referência. São explorações não adotadas, de fevereiro de 2026. Ver a decisão 0002.
Quero mostrar um comando de instalação.
type.code, JetBrains Mono, sobre bg.terminal.
Referência
Decisões
Registro append-only de decisões de marca. Uma decisão nunca é editada depois de aceita. Se muda, entra uma nova que substitui a anterior e aponta para ela.
Formato: NNNN-titulo-curto.md com as seções Status, Contexto, Decisão, Consequências e Alternativas. Status possíveis: Proposta, Aceita, Substituída por NNNN, Rejeitada.
| Nº | Título | Status |
|---|---|---|
| 0001 | Adoção da NewBrand26 como marca vigente | Aceita |
| 0002 | Destino das explorações de fevereiro de 2026 | Proposta |
| 0003 | Tokens em três camadas como fonte da verdade | Proposta |
| 0004 | Cores de feedback e severidade | Proposta |
| 0005 | Cor de acento por produto | Proposta |
| 0006 | Posicionamento e site-beta | Proposta |
| 0007 | Chrome do terminal e superfície escura quente | Proposta |
| 0008 | Lucide como biblioteca de ícones | Proposta |
| 0009 | Assets digitais saem dos arquivos oficiais | Proposta |
O que está em aberto agora
Convergence, Aurora e Radiance não foram adotadas. A recomendação é arquivar, com a porta aberta para trazer só o sistema de glow do Radiance como token de sombra.
Site em produção usa âmbar para tudo. Site-beta usa um dos três amarelos por página. Decks comerciais usam paletas próprias. O mesmo produto aparece com cor diferente dependendo de onde está.
Existem duas taglines em código: a do site no ar e a do site-beta. Precisa de decisão do mantenedor antes de qualquer outra coisa.
Lucide em todos os produtos, traço 1.5px. A decisão está escrita e espera aceite; até lá, a página de ícones é proposta.
Favicon, avatar e ícone de canal com o sol, Open Graph com o lockup, nada gerado com IA. O avatar sai de pendência solta e vira regra proposta.
Decisão 0001, aceita de fato em 17/03/2026 e registrada só em 14/09/2026: a marca passou seis meses no ar sem constar no repositório. É por isso que a governança existe.
Referência
História da marca
Quatro identidades em cinco anos. Saber o que ficou para trás evita trazer de volta um amarelo aposentado.
V1 — Identidade original
Logo "SUNNY☀SYSTEMS" com símbolo de sol de raios integrado entre as palavras. Space Grotesk e Tajawal. Amarelo #FFC700 com azul royal e cinzas. Mascote robô Sunny e grafismos de losangos em dissolução.
V2 — Branding 2.0
O símbolo do sol foi isolado e ampliado, virando ícone independente. O amarelo evoluiu para #F8D347, mais quente. Paleta expandida para 12 cores em pares light e dark.
V3 — Site Framer
Dark premium em Framer. Plus Jakarta Sans e Geologica, amarelo #FFDE59 sobre #171E20, ilustração isométrica wireframe, inglês-first. Saiu do ar em 17/03/2026. Nada daqui vale como referência atual.
Explorações não adotadas
Convergence, Aurora e Radiance. Partiam de premissas que a marca lançada não seguiu: amarelo #FFDE59, hierarquia por opacidade de branco, arredondamento generoso, inglês-first. Ficam em docs/propostas/ como registro do processo.
V4 — NewBrand26
Sol em semicírculo de faixas horizontais, sem raios. Wordmark SUNNY SYSTEMS. Âmbar #FFB61F sobre #1A1A1D. Bricolage Grotesque, Inter e JetBrains Mono. Tom de voz brasileiro, pt-BR primário. No ar desde 17/03/2026.
O que sobreviveu às quatro versões
O sol e o amarelo. Tudo o mais mudou: a fonte, a forma do símbolo, o tom do amarelo, o idioma. Por isso a regra de não criar um quinto tom.
Referência
Fontes da verdade
Em caso de divergência, a fonte da verdade vence, nesta ordem.
| # | O que | Onde | Observação |
|---|---|---|---|
| 1 | Tokens | tokens/tokens.json | tokens.css é gerado a partir dele |
| 2 | Logo, paleta e fontes originais | Drive _Sunny-NewBrand26 | .ai, .svg, .pdf, PNG, .ttf |
| 3 | Implementação de referência | website/src/style.css | Importa o tokens.css desde o website#14, em 15/09/2026. Ainda usa os nomes antigos pelo bloco de compatibilidade |
| 4 | Decisões | docs/decisoes/ | Append-only |
| 5 | História | docs/historia-da-marca.md | V1 a V4 e explorações |
Estado em setembro de 2026: os tokens deste repositório foram medidos no site, então hoje os dois batem. A partir da adoção do tokens.css pelo site, este repositório passa a ser a origem. Plano em versionamento.
Links
Para agentes e LLMs
O mesmo conteúdo desta página existe em markdown, gerado das mesmas fontes. Um agente que precise escrever código ou texto na marca deve ler isso em vez de raspar o HTML.
| Arquivo | O que é | Tamanho |
|---|---|---|
| /llms.txt | Índice no formato llmstxt.org, com as regras duras e os pares de cor proibidos inline. Para quem vai ler um arquivo só e decidir o que buscar depois | 6 KB |
| /llms-full.txt | Tudo em um arquivo: regras, tabela dos 276 tokens com valor resolvido e status, as quatro fundações, os cinco componentes, padrões, governança, as seis decisões e a história | 131 KB |
| /tokens.css | As custom properties prontas para importar, com tema claro e aliases de compatibilidade | 26 KB |
Os dois primeiros são gerados por node site/build.mjs a partir de tokens/tokens.json e de docs/. Não há cópia escrita à mão: se um valor muda no token, ele muda nos três arquivos no mesmo comando.
No llms-full.txt os aliases já vêm resolvidos: button.primary.bg aparece como #FFB61F junto com o token para o qual aponta. O agente não precisa seguir a cadeia de três camadas para saber a cor final.
Os cinco produtos
RootPilot, ScopeWard, DevXOS, Sunshine e Soberania de IA. Grafia fixa, sem espaço, sem hífen. Nenhum tem cor própria hoje: ver decisão 0005.