Design tokens como fonte única: dando a um app de Sudoku uma direção de arte de verdade
8 min de leituraEscrito por: Jonathan Reis em
Um grid de Sudoku genérico é fácil de lançar e fácil de esquecer. Dar uma direção de arte ao nosso significou mexer primeiro no sistema de tokens, não nas telas.

A maioria dos apps de Sudoku é igual: grid cinza plano, números Roboto, botões Material genéricos, tudo branco e cinza. É seguro e é esquecível. O nosso tinha escorregado exatamente para essa cara, então demos a ele uma direção de arte de verdade. A parte interessante não foi escolher cores. Foi que o app já tinha um sistema de temas e um orçamento de performance duro, e os dois decidiram até onde o “ousado” podia ir.
Esta é a história desse redesign como ele de fato saiu: uma primeira fatia vertical, não um app pronto.
Batize a direção antes de tocar numa tela
Escolhemos uma direção e demos nome a ela: Editorial Ink. Neutros quentes tipo papel no modo claro; um charcoal quente no modo escuro; um foreground que é preto-tinta em vez de preto puro. A única cor de marca continuou o roxo. As quatro skins pagas (fun, ocean, forest, sunset) seguiram funcionando.
Dar nome cedo importou mais do que parece. “Deixa mais bonito” gera cem decisões pequenas e inconsistentes. “Isso pertence ao Editorial Ink?” gera uma. Toda escolha seguinte (peso de borda, tint de seleção, sombra) passou a ter a quem responder.
Cor é papel, não hex
A regra neste repositório é velha e chata: componente nunca cravar hex. Ele consome um token semântico. primary é a marca e a ação principal. accent é um realce sutil, não uma segunda cor de marca. Cores funcionais como danger são um eixo separado, com o próprio par de foreground para o contraste.
O redesign obrigou a cumprir essa regra onde a gente tinha trapaceado. Dois exemplos:
accenttinha virado, sem alarde, uma segunda cor de marca: um ocre que disputava com o roxo. Reclassificamos para um realce neutro sutil e tiramos o ocre.- O tabuleiro em Skia ainda desenhava erro com um
#dc2626cravado. Aquele vermelho ignorava o tema. Promovemosdanger/dangerForegrounda tokens theme-aware de verdade e apagamos o literal.
Também adicionamos os neutros que o novo visual pedia como tokens de primeira classe (secondary, muted) e renomeamos foregroundMuted para mutedForeground, para o app e o site falarem as mesmas palavras. Cada token foi propagado aos seis temas e às CSS variables, e depois mapeado no Tailwind config para que classes NativeWind como bg-danger ou text-cell-highlight resolvam por tema.
O redesign tinha que sobreviver a seis temas
Editorial Ink são dois dos seis temas. O app também traz quatro skins pagas que jogadores já compraram. Um redesign que só ficasse certo no claro e no escuro quebraria justamente aquilo pelo qual alguém pagou.
Como cada token novo foi definido para os seis temas, a tipografia, a grade, a seleção e o enquadramento do tabuleiro renderizam pelo mesmo código em toda skin. A skin muda os valores; os papéis ficam no lugar. Esse é o retorno prático dos tokens semânticos: uma reforma visual vira uma mudança numa tabela de cores, não uma bifurcação no renderer. E significa que a próxima superfície que levarmos para o Editorial Ink herda o suporte a skins de graça, em vez de cada tela re-deduzir “qual é a cor de seleção no ocean?”.
Um vocabulário só para o app e o site
Token só compensa quando existe exatamente um conjunto de nomes. Nossos sites de marketing tinham o próprio dialeto: ink, mist, line e uma escala accent que na verdade era a marca. No mesmo ciclo, renomeamos tudo para os papéis canônicos: accent virou primary, ink virou foreground, mist virou background/surface, line virou border, muted virou muted-foreground. Mesmos valores, vocabulário compartilhado. Agora uma frase como “seleção usa um tint de primary” quer dizer a mesma coisa no jogo e na landing page.
Por isso a cor de seleção do tabuleiro não é uma decisão de enfeite tomada isolada. É um tint de primary em alpha baixo, um roxo discreto que casa com o ::selection do site a 30%. Tentamos um âmbar quente para ecoar o papel, revisamos no aparelho e descartamos: ele brigava com os números em vez de guiar o olho. O token que saiu é o tint roxo, registrado como fonte única para ninguém reinventar mês que vem.
Tokens que pertencem ao tabuleiro
Nem toda necessidade visual é um papel semântico novo. Três tokens são board-derived: existem para a superfície do Sudoku e ficam no app, não no contrato compartilhado.
boardLine: uma variação deborderpara a grade.boardShadow: a sombra de deboss do frame do tabuleiro.cellHighlight: o tint de seleção, célula relacionada e mesmo número descrito acima.
Mantê-los nomeados e derivados, em vez de hex espalhado dentro do renderer, é o que faz o mesmo tabuleiro ler bem no claro, no escuro e nas quatro skins pagas sem um caminho de código por tema.
O tabuleiro é onde a identidade precisa sobreviver à renderização
O tabuleiro carrega a personalidade do jogo, e renderiza de duas formas: um canvas Skia (o padrão em produção) e um fallback React Native, em paridade. Os dois receberam o mesmo tratamento:
- Hierarquia tipográfica entre os fixos (peso maior) e os palpites do jogador.
- Dígitos tabulares, para os números não tremerem quando mudam.
- Grade hairline com separadores 3×3 mais fortes.
- Erro sinalizado por cor e forma (borda arredondada) e um micromovimento, nunca só por cor. Isso mantém o retorno de “você errou” legível para quem tem daltonismo e acima do piso de contraste 4.5:1.
- Um único frame arredondado com deboss em volta do tabuleiro inteiro, no lugar de uma sombra por célula. (Esse frame causou um bug de borda que deslocou todos os dígitos do centro no renderer Skia.)
Essa última escolha é design e performance ao mesmo tempo. Sombra por célula parece mais rica por um segundo e depois arrasa o orçamento de repaint num aparelho fraco. Um tabuleiro com um frame único e o deboss de boardShadow dá profundidade sem pedir para a GPU compor 81 sombras a cada seleção.
O orçamento de performance foi o teto de verdade
O aparelho de corte é um Redmi Note 7. Selecionar uma célula repinta o tabuleiro, e essa interação não pode regredir. O latency probe vai desligado no envio; a gente liga só para a medição e reverte, então produção nunca paga pela instrumentação.
Seleção de célula com repaint completo do tabuleiro deu mediana de 107ms, P90 de 141ms e máximo de 143ms em quinze amostras. Nenhum input contínuo passou do corte técnico de 180ms. Os únicos picos na faixa de 250–330ms vieram dos fluxos animados de fim de jogo e de erro, não de tocar nas células. É o formato honesto disso: a interação do dia a dia ficou dentro do orçamento, e os momentos de celebração custam mais, mas acontecem uma vez.
Números assim são o motivo de a ambição ser limitada. Um tabuleiro mais bonito que fizesse a seleção parecer mais lenta seria um produto pior, não mais ousado.
O que ainda não fizemos
Chamar isso de “o redesign” seria desonesto. Ele saiu como uma fatia vertical: a fundação de tokens, o tabuleiro e a tela Home (um masthead, um card de retomar jogo, um card de Daily Challenge e um skeleton de carregamento no lugar de spinner cru), com chaves i18n novas adicionadas nos dez idiomas.
O resto está, de propósito, ainda no visual antigo:
- Fim de jogo, o NumberPad e a barra de controles, Perfil, Loja e Configurações ainda não foram para o Editorial Ink. Eles reusam os mesmos tokens, então o que falta é espalhar uma direção, não inventar uma.
- Uma fonte display custom para os dígitos ficou adiada. Ela exige rebuild nativo e mais peso de bundle, então a fatia usa fonte de sistema com peso tabular até essa troca valer a pena.
- Idiomas da direita para a esquerda (árabe, urdu) estão catalogados, e a fatia não introduz layout que quebre em RTL, mas o espelhamento global ainda é tarefa de depois.
A lição
Um redesign ousado num app maduro é, na maior parte, editar o sistema embaixo das telas. Batize a direção para toda decisão seguinte ter a quem responder. Mova cor para tokens semânticos para o app e o site dizerem as mesmas palavras. Deixe o orçamento de performance, não o gosto, definir o teto. Depois entregue uma fatia que você consiga defender, com uma lista honesta do que ainda está no visual antigo.
Isso é menos satisfatório do que anunciar um redesign pronto. Também é a versão que é verdade, e a que deixa a próxima superfície herdar o trabalho em vez de começar do zero.