tAIlly

Sistema visual do tAIlly

O mapa é o produto. Esta página é o espécime vivo dos tokens, componentes, estados e regras de movimento — a mesma folha (application.css) que serve o app e os artefatos 3D. A especificação escrita fica em docs/04-DESIGN.md.

Todo número desta página é fictício. Nenhum dado do TSE foi ingerido aqui: as alturas, percentuais e nomes existem só para exercitar o componente. Os únicos valores reais são os hex, as razões de contraste e os ΔE — medidos pelo validador do método, não escolhidos no olho.

01

Cinco princípios que governam cada pixel

Ausência de dado é buraco

Nunca altura zero, nunca cor de escala. Hachura a 135° + rótulo “sem registro no TSE”.

Todo número tem procedência

Ao lado do valor, de onde veio e quando o arquivo foi gerado.

TSE · votacao_secao_2022_SPdt_geracao 2026-02-13

O tempo é o eixo

Nenhuma tela é fotografia solta: tudo responde “e antes, como era?”.

Cor nunca sozinha

Identidade sempre tem um segundo canal: legenda, rótulo direto, textura ou tabela.

atingido parcial divergente

O dado não faz overshoot

Marca de dado só anima em curva monotônica (--ease-dado). Mola é para cromo. Ver §08.

02

Política de cor partidária

a decisão mais carregada do projeto

O TSE não publica cor de partido. Logo, toda cor partidária numa tela do tAILly seria invenção nossa — e cor de partido é propaganda, não dado. A política abaixo existe para que o mapa mostre quem ganhou sem parecer que está torcendo.

1Cor de partido não é dado, é convenção. Onde ela aparecer, aparece declarada como convenção do tAILly, com a fonte no rodapé da tela.

2O padrão é a paleta neutra. Partido recebe um dos 8 slots categóricos, não a cor da sua marca. Um modo “cores partidárias” só pode ser ligado quando existir tabela explícita de cores com procedência — enquanto não existir, o botão fica desabilitado com o motivo na tela.

3A cor segue a identidade, nunca o ranking. O slot é preso ao partido_canonico_id e congelado num arquivo versionado: filtrar não repinta ninguém, e PFL→DEM→União Brasil mantém a mesma cor em 1998 e em 2022.

4Os slots 1–4 são politicamente neutros no Brasil (turquesa, laranja, violeta, âmbar). Verde, azul e vermelho ficam no fim da fila de propósito: assim o partido mais votado não ganha, por acaso, a cor da própria propaganda.

5Nada de 9ª cor. Do 9º em diante é “Outros”, cinza. Cor gerada em tempo de execução é proibida — quebra a separação sob daltonismo.

6Sem slot atribuído = cinza + legenda “sem cor atribuída”. Nunca uma cor plausível.

7Swing nunca é vermelho↔azul nem vermelho↔verde. O primeiro seria lido como placar partidário brasileiro; o segundo é o par que a dicromacia mais destrói. O tAILly usa violeta↔âmbar.

Como isso fica em tela

Vencedor por município, dado fictício. A legenda carrega o nome — a cor sozinha nunca identifica.

Partido A Partido B Partido C Outros (9º+) sem cor atribuída sem registro no TSE

Teto de séries, medido

  • 8séries em barra, pilha e linha (só vizinhos se tocam)
  • 3séries no mapa, no scatter e em small multiples — lá qualquer par pode ficar lado a lado. Do 4º em diante: “Outros”, facetas ou small multiples.

Medido com --pairs all: o prefixo de 3 slots passa com ΔE 14,0 (claro) e 14,2 (escuro) sob deuteranopia. O melhor subconjunto de 4 cai para ΔE 7,3 / 6,9 — banda de piso, que exigiria rótulo direto em cada mancha. Num mapa de 5.570 municípios isso não existe, então o teto do mapa é 3.

03

Paleta

todo hex passou pelo validador; nenhum foi escolhido no olho

Categórica — identidade de série · ordem fixa, nunca ciclada

turquesa slot 1 claro #1b9a8e escuro #1da195
laranja slot 2 claro #ad5611 escuro #c26215
violeta slot 3 claro #7b57c8 escuro #8a66d9
âmbar slot 4 claro #aa7e17 escuro #b98918
magenta slot 5 claro #b23e88 escuro #c34e97
verde slot 6 claro #148227 escuro #1d9330
azul slot 7 claro #1270c4 escuro #167edd
vermelho slot 8 claro #c13c36 escuro #d24d45

Medido, pares adjacentes: pior ΔE sob protanopia/deuteranopia 11,5 no claro e 12,1 no escuro (alvo ≥ 8); pior ΔE de visão normal 23,0 e 23,4 (piso ≥ 15); os 8 slots ficam ≥ 3:1 contra a superfície nos dois modos.

Por que esta ordem: foram enumeradas as 5.040 ordens possíveis com a turquesa da marca no slot 1; ficaram só as que passam em todos os portões nos dois modos; entre elas, escolhemos a de maior separação mínima com verde, azul e vermelho fora dos quatro primeiros slots.

Sequencial — intensidade (comparecimento, votos, densidade) · uma matiz, claro→escuro

100200300400500600700

No escuro a âncora inverte: perto de zero é o degrau mais próximo da superfície. Para escala ordinal (faixas discretas) o começo seguro é o degrau 400 no claro (2,24:1) e 300 no escuro (2,16:1) — antes disso o degrau some na superfície. Há uma segunda rampa (laranja, --seq2-*) para quando dois contextos sequenciais dividem a tela.

Divergente — swing (mudança entre eleições) · violeta ↔ âmbar, meio cinza

−20 pp−15−10−5 sem mudança+5+10+15+20 pp

Dois polos que leem como opostos (frio ↔ quente) sobre o eixo azul-amarelo, o único que protanopia e deuteranopia preservam. Medido: polos a ΔE 23,4 (claro) e 26,5 (escuro) sob deuteranopia; e — o que mais importa — o par mais difícil da escala, o primeiro degrau de cada lado, fica a ΔE 26,1 e 25,0. Uma virada mínima para cada lado nunca se confunde. O meio é cinza, porque “não mudou” tem de parecer nada; “não tem dado” continua sendo hachura, não cinza.

Status — reservado · nunca vira “série 4”, sempre com ícone e rótulo

critério atingido parcial divergência bloqueia a onda sem registro no TSE

Quatro papéis, três de severidade e um de ausência. Contraste medido no modo escuro: 8,44 · 9,48 · 6,24 · 5,22 contra a superfície de gráfico; no claro, 6,02 · 5,00 · 6,87 · 4,66. O papel “grave” do método foi fundido em “crítico”: com quatro níveis quentes não dava para manter ΔE ≥ 15 entre eles e distância dos slots categóricos, e dois vermelhos indistinguíveis são pior do que um. Como status sempre vem com ícone e rótulo, a cor nunca carrega o significado sozinha.

04

Tipografia

serifada só em prosa; todo número em sans ou mono
--t-3xl · 64px
herói cheio
5.570
--t-2xl · 48px
figura-herói
1.337 pesquisas registradas
--t-xl · 34px
título de página · serifada
A votação do Brasil, 1933–2026
--t-lg · 26px
título de seção · serifada
Quem está pesquisando o Brasil
--t-md · 21px
título de cartão · sans
Presidencial 2022, 2º turno
--t-corpo · 17px
prosa
O TSE publica uma fotografia por eleição; nada nela liga uma eleição à seguinte.
--t-base · 15px
corpo de UI
Comparecimento por município, 2º turno, cargo presidente.
--t-menor · 13px
UI densa, tabela
Campo Grande · MS · zona 001 · 412 seções
--t-mini · 12px
legenda, meta
margem de erro 2,2 pp · confiança 95%
--t-micro · 11px
rótulo de eixo, crédito
cdn.tse.jus.br · last-modified 2026-07-26T05:46Z

Figuras: número grande e isolado usa figuras proporcionais — tabular-nums deixa 121 frouxo em corpo de display. tabular-nums fica reservado para coluna que alinha na vertical: linha de tabela e marca de eixo.

05

Espaço e forma

base 4px
--e-1 · 4px
--e-2 · 8px
--e-3 · 12px
--e-4 · 16px
--e-5 · 24px
--e-6 · 32px
--e-7 · 48px
--e-8 · 64px
--e-9 · 96px

Forma das marcas

  • ≤24espessura máxima de barra/coluna (--barra-max); o resto da faixa é ar
  • 4pxarredondamento só na ponta do dado; quadrado na linha de base
  • 2pxespessura de linha, vão de superfície entre marcas que se tocam e anel de superfície nos pontos
  • 1pxgrade e eixo, sempre sólidos — tracejado vira ruído e sugere projeção
  • ≥8diâmetro do marcador; alvo de ponteiro de ≥24px, sempre maior que a marca

Quem separa é o vão na cor da superfície, nunca uma borda desenhada.

06

Componentes

mapa · scrubber · painel · legenda · dica · comparador

Alvo de toque: piso de 44 px, com uma isenção só

Todo controle — botão, pílula de filtro, item de sumário, play, trilho do scrubber, chamada da home — mede pelo menos 44 × 44 px em qualquer rota (/, /mapa, /estilo, /status) e em qualquer largura. Não é recomendação: a régua research/perf/medir_alvos.mjs reprova quem estiver abaixo.

Isenção única, e é a da WCAG 2.5.8: link dentro de uma frase (/status, ver no mapa) herda a altura da linha e fica em ~14 px de caixa. Aumentá-lo empurraria o texto ao redor — o remédio seria pior. Onde isso acontece, o elemento carrega data-alvo-excecao com o motivo, e a régua só aceita a exceção que está declarada assim no DOM.

Consequência prática: um link que não está dentro de frase (a chamada Abrir o mapa 3D da home, as pílulas do sumário desta página) não é isento — vira caixa de 44 px por min-height, sem mexer no corpo do texto.

demonstração · dado fictício

Comparecimento · 2022

campo abstrato — não é a malha do IBGE

projeção isométrica

valor
variação vs. pleito anterior

valor também está na tabela — a dica nunca é o único caminho

Scrubber de tempo

Cada marco é um pleito real — o vazio entre eles também é dado. Marco vazado = ano sem granularidade de seção publicada pelo TSE (1994 e 1996). Arraste, use ← → ou aperte play: as colunas interpolam em --dur-cena com --ease-dado.

199420102026
2022

Comparador

Duas eleições no mesmo enquadramento, cortina arrastável. Nunca dois eixos no mesmo gráfico: quando as medidas têm escalas diferentes, são duas telas, não dois eixos.

2018 2022
07

Estados

o que a tela faz quando não tem o que mostrar

Primeira carga — esqueleto

Só quando não existe render anterior nenhum. Mantém a geometria final para não haver pulo de layout.

Recarga — segura o quadro

Trocar filtro não mostra esqueleto: o render anterior fica a 45% até o novo chegar.

Drill-down assíncrono

Consulta remota em Parquet leva segundos e a UI diz isso — não trava e não mente.

buscando seção em SP · 2022

62% · 18.761.482 linhas no Parquet remoto

Ausência declarada

Nunca zero. O buraco tem legenda e diz de quem é o limite.

granularidade máxima disponível em 1996: município × zona — o TSE não publica seção antes de 1998.

Nenhuma pesquisa registrada neste recorte Roraima teve 5 registros em 2026. Amplie o período ou tire o filtro de instituto.
A reconciliação seção → munzona divergiu 14 linhas com diferença em (município, zona, cargo). Divergência não explicada bloqueia a onda — o mapa não é publicado com número que não fecha.
08

Movimento

clique em qualquer caixa para repetir

✕ mola numa marca de dado

0,0%

A barra ultrapassa e volta. Por alguns frames a tela exibe um número que não existe no banco. Veja o pico.

--ease-dado, monotônica

0,0%

Cresce sem nunca passar do valor final. Todo frame intermediário é um número plausível e menor — nunca um número falso.

É esta a única regra de motion que é regra de integridade, não de gosto.

Curvas

Durações — a que serve cada uma

TokenmsServe paraCurva
--dur-toque90hover, press, foco — resposta tátil--ease-padrao
--dur-rapido160chip, selo, aba, dica aparecendo--ease-saida
--dur-medio240painel, popover, troca de tema--ease-saida
--dur-lento420barra crescendo, comparador abrindo--ease-dado
--dur-cena700voo de câmera, morph entre dois pleitos--ease-dado
--dur-passo-tempo1100um pleito por passo no play da linha do tempolinear entre marcos

prefers-reduced-motion corta toda animação para 1ms — inclusive a interpolação do mapa, que passa a saltar direto para o estado final. O produto continua inteiro sem movimento nenhum.

Dados eleitorais: Tribunal Superior Eleitoral — dados abertos (CC-BY). Malha geográfica: IBGE. Nesta página, todos os valores são fictícios; só cor, contraste e ΔE são medidos. Método de cor: skill dataviz · validador OKLab ΔE ×100 · Machado-Oliveira-Fernandes 2009.