---
fonte: 01-canonicos/seed-dataviz.md
versao_da_fonte: v0.22
secao: 04d
titulo: "Sub-bloco DP — mapas de atuação MG-ES-BA (DP1–DP14)"
sequencia: 9 de 12
bytes_do_corpo: 47287
md5_do_corpo: 517d7342e490919c05d9075ebbf7ac83
gerado_por: 06-validacao/geradores/gen-camada-ia.py
nota: fatia GERADA — o corpo abaixo é byte a byte o trecho do canônico; edite o canônico, nunca esta fatia. Canônico inteiro em https://ds.seed.eng.br/01-canonicos/seed-dataviz.md
---
## 4d. Sub-bloco DP — mapas de atuação MG-ES-BA (DP1–DP14)

> **Estado:** **`estável` desde 2026-08-11, e SEM PENDÊNCIAS ABERTAS desde o mesmo dia.** O
> consolidado de decisões foi aprovado pelo Rafael ("aprovo" explícito sobre DP1–DP14) e a
> promoção veio depois do **gate visual** sobre o preview. As seis pendências nominais que o
> sub-bloco abriu — **DP-P1 a DP-P6** — **fecharam todas**: as três primeiras por medição de
> contraste e de forma; as três últimas quando a **malha oficial do IBGE, edição 2025**, entrou
> no lugar da malha sintética. O gate visual sobre o preview **v0.4**, já com a geografia real,
> foi aprovado em 2026-08-11. *Fronteira honesta do que o gate cobriu, registrada porque a diferença importa:* o
> Rafael inspecionou visualmente o preview **v0.2** e respondeu os cinco pontos do protocolo
> (formas legíveis em escala de cinza · fronteira visível no tema escuro · malha completa
> ilegível a 360px · impressão correta · malha sintética aceita). A **v0.3** difere da v0.2 em
> **um único ponto** — a tinta da contagem de agrupamento, corrigida pelo DG12 —, verificada por
> medição de contraste e por inspeção de captura de render, e aprovada por ele sobre esse
> relato. **DP** = sub-bloco de **mapas** da Fase 5; é o
> último dos seis (DF · DT · DG · DM · DI · DP) e o seu fechamento dispara o marco da fase.
>
> **Por que este sub-bloco tem insumo que nenhum outro teve.** DF, DT, DG, DM e DI operam
> sobre geometria que o Design System inventa (uma barra tem a altura que o dado mandar).
> O DP opera sobre **geometria geográfica real**: o contorno de Minas Gerais não é decisão
> de design, é um dado externo, com fonte, licença, data de publicação e erro declarado.
> Isso põe no sub-bloco duas classes de decisão que os outros não tiveram — **de onde vem a
> forma** (DP8, DP9) e **como ela é achatada num plano** (DP7).

### 4d.0 Escopo, decidido em briefing com o Rafael antes de qualquer pesquisa

As seis perguntas de escopo foram feitas e respondidas em 2026-08-11, antes da primeira
rodada de pesquisa, exatamente porque nenhuma delas é derivável do canônico — todas dependem
do uso real da empresa. **Fato (respostas do Rafael), não inferência:**

| # | Pergunta | Resposta |
|---|---|---|
| a | Obras como **pontos** ou municípios pintados por intensidade (**coropleto**)? | **Pontos.** O coropleto fica **escrito** na spec como caminho pronto, sem ser implementado agora |
| b | Onde o mapa aparece? | **Nos três destinos**: laudo/proposta impressa, ERP (tela) e site institucional |
| c | Zoom/pan/tooltip ou figura fixa? | **Figura fixa** como norma; tooltip permitido no ERP como enriquecimento |
| d | Quantos níveis geográficos? | Estado + **município** + ponto. O Rafael recusou o recorte de dois níveis: *"eu tenho que ter todos os municípios"* — o território do estado nunca aparece recortado, e a seleção incide sobre a **linha de fronteira**, não sobre o território |
| e | Carrega dado de cliente identificável? | Sim no ERP; **não** em peça externa — vira regra dura (DP12) |
| f | Fonte de malha já em uso na empresa? | Não há. Decisão livre (DP8) |

**Glossário mínimo, porque o vocabulário de cartografia não aparece em nenhum outro arquivo
deste sistema:**

- **Malha** — o arquivo com as coordenadas que desenham os contornos (estados, municípios).
- **Coropleto** — mapa em que cada região é preenchida com uma cor que representa um número.
- **Marcador** — o símbolo que marca um ponto (uma obra) sobre o mapa.
- **Projeção** — a regra matemática que achata a superfície curva da Terra num plano. Toda
  projeção deforma alguma coisa; escolher a projeção é escolher **o que** deformar.
- **Simplificação** — reduzir o número de pontos de um contorno para o arquivo caber na web,
  aceitando perda de detalhe.
- **TopoJSON / GeoJSON** — formatos de arquivo de geometria. TopoJSON é a variante compacta,
  que armazena fronteiras compartilhadas uma única vez em vez de duas.
- **SIRGAS 2000** — o sistema geodésico de referência oficial brasileiro; define a partir de
  que modelo da Terra as coordenadas são medidas.

**O DP entrega DIRETRIZ DE MAPA.** Não orquestra tela (isso é Fase 6), não implementa
comportamento dependente de dado vivo (isso é produto — Lovable/Supabase, mesma fronteira do
DM10), e não vira SIG/GIS: não faz análise espacial, não calcula rota, não mede distância.

---

### 4d.1 DP1 — Um mapa é um gráfico: herda o DG1 inteiro, e o fallback textual é o mapa

**Decisão:** todo mapa SEED é um `<figure>` com as **cinco partes do DG1** (§4.1): título em
`figcaption`, descrição curta, **fallback textual sempre presente**, legenda, e a área com
`role="img"` + `aria-labelledby`. O fallback textual de um mapa é uma **tabela município →
obras**, com as colunas: Município · UF · Tipo de solução · Quantidade. Em destino interno
acrescenta-se a coluna de identificação permitida pelo DP12; em destino externo, nunca.

**Racional:** o W3C classifica gráfico como imagem complexa e exige alternativa textual em
duas partes, e a orientação específica para mapas vai além do que vale para um gráfico comum
— ela pede, além da tabela, **navegação alternativa por lista de localidades**, porque num
mapa a informação é *onde*, e "onde" não se lê por varredura de eixo. Num mapa da SEED a
lista de municípios **é** o mapa para quem não o enxerga. E é também o que sobra quando o
laudo é lido em preto e branco, ou quando o PDF é aberto num leitor que não renderiza SVG.

**Alternativa descartada:** `alt` textual curto como cumprimento do 1.1.1. Insuficiente para
imagem complexa — a mesma razão já registrada no DG1, agravada aqui: um `alt` que diz "mapa
de atuação da SEED em MG, ES e BA" identifica o objeto e **não entrega nenhum dado**.

---

### 4d.2 DP2 — Consumidor técnico: SVG projetado sobre `d3-geo`; mapa de tiles é VETADO

**Decisão:** o mapa canônico da SEED é **SVG projetado**, gerado por `d3-geo` +
`topojson-client`. O invólucro `react-simple-maps` é **permitido** (é um wrapper fino sobre
exatamente essas duas dependências, com API declarativa), mas o que o Design System exige é a
camada de baixo — para que a diretriz sobreviva ao abandono do wrapper. **Mapa de tiles
(Leaflet, MapLibre, Google Maps, Mapbox) é vetado dentro do escopo do DS.**

**Racional do veto, com três motivos independentes:**
1. **Identidade.** Tile traz base cartográfica de terceiro, com estética própria — ruas,
   pontos de interesse, tipografia alheia. O mapa deixa de ser uma peça SEED e passa a ser
   uma captura de tela do produto de outra empresa com uns pinos por cima.
2. **Impressão.** Tile é imagem raster carregada por rede. Num PDF de laudo vira mancha, e
   sob a regra do **DI4** (§4c.4) nada disso é superfície de dado protegida.
3. **Custo de render.** A abordagem de tiles paga custo de performance na renderização
   durante pan e zoom, ao contrário do SVG — e nós nem usamos pan e zoom (DP13).

**Alternativa descartada:** D3 puro sem wrapper — é o que o DF2 já descartou para os
gráficos core ("poder máximo que os tipos core não exigem"). Aqui a decisão é diferente
**por um motivo declarado**: mapa **não tem** equivalente ao shadcn Chart, então a camada
`d3-geo` é obrigatória de qualquer forma; o que é opcional é o wrapper acima dela.

> **EMENDA FORMAL AO DF2 (§2), nascida neste sub-bloco.** O DF2 declara o consumidor canônico
> web como **shadcn Chart sobre Recharts v3**. **Recharts não desenha mapa** — não há
> componente geográfico na biblioteca. O DF2 permanece vigente para os sete tipos core, o
> monitoramento e o que vier deles; **a família mapa consome outra cadeia**, declarada neste
> DP2. Isso não é supersede do DF2: é o preenchimento de uma lacuna que ele tinha sem saber,
> porque foi escrito quando mapa ainda não era escopo. Registro no §6.

---

### 4d.3 DP3 — Num mapa existem TRÊS cinzas, e cada um precisa de papel declarado

Esta é a decisão mais importante do sub-bloco, porque é onde a regra com mais reincidências
do projeto — **posição categórica nunca serve de neutro** (erratas E3, E14, E15) — tem a
maior superfície de erro. Num gráfico de barras existem duas coisas cinzas ("sem dado" e
"contexto"). **Num mapa existem três**, e as três parecem a mesma mancha:

| Estado do território | Significado | Tinta |
|---|---|---|
| **Contexto** | não é objeto de medição (o resto do estado) | **`chart-geo-base`** — token próprio, novo na v1.8 dos gêmeos |
| **Sem medição** | é objeto de medição e **não temos o dado** | `chart-no-data` + hachura diagonal a 45° em `chart-no-data-hatch`, **obrigatória** |
| **Com dado** | medido | escala **sequencial** (§3c) — no coropleto do DP14 |

**Regra dura:** nenhum dos três consome `cat-N`. Nunca. Território não é série.

**Racional do caso perigoso — o do meio.** Sem a hachura, "não medimos aqui" e "aqui não
interessa" viram a mesma mancha cinza, e a diferença entre as duas afirmações, num laudo de
engenharia, é a diferença entre lacuna declarada e território fora do escopo. É exatamente a
estrutura do erro da errata **E3**, transposta para outra forma: um papel de desenho existindo
sem token próprio e tomando emprestado o de outro papel. A hachura a 45° permanece
**exclusiva** do `chart-no-data` (§4.4), e a tinta dela é o `chart-no-data-hatch` (v1.7 dos
gêmeos), nunca `chart-axis` e nunca `cat-N-stroke`.

> **DP-P1 FECHADA na v0.15, por medição.** O instrumento é o `contraste-dp.py` v1, que extrai
> os hex do `seed-tokens.css` canônico em vez de digitá-los (lição das erratas E4/E16).
> **Veredito:** nasce o token **`chart-geo-base`** (`#F2F6F9` light / `#141D23` dark), com papel
> próprio, na v1.8 dos três gêmeos. **Por que token novo se o valor já existe** (é idêntico ao
> `surface-subtle` vigente): o que muda não é a cor, é a responsabilidade de mantê-la — mesmo
> racional que criou o `chart-no-data-hatch` na v1.7 depois da errata **E3**, que provou que
> papel de desenho sem token próprio acaba tomando emprestado o de outro papel.
> *Alternativa descartada:* consumir `surface-subtle` diretamente — repetiria a estrutura da E3
> num papel novo. Medições completas na §3c do `seed-tokens.md` v1.8.

---

### 4d.4 DP4 — Fronteira no mapa: PRECISÃO DE ESCOPO do DG14, não supersede

**Decisão:** o **DG14** (§4.6) determina que superfície de dado não leva contorno, e resolve
a separação entre vizinhos por **vão de 2px na cor do cartão** — espaço negativo, fronteira
por geometria e não por contraste. Isso **não se aplica ao território**, porque território é
**contíguo**: não existe vão entre Governador Valadares e Alpercata sem que se invente um. No
mapa vale o **princípio** da condição (b) da §3c do `seed-tokens.md`, já `estável` desde o
sub-bloco DT e escrita junto com a isenção do WCAG 1.4.11 para heatmap — *a fronteira entre
regiões é desenhada, nunca deixada por conta da diferença de cor*. **A tinta, porém, não é a
que aquela condição nomeia.** Ver a errata **E19** logo abaixo: a fronteira do mapa consome
**`chart-geo-boundary`** (`#788F9D` light / `#90A6B3` dark, token novo na v1.8), não
`chart-grid`.

> **ERRATA E19 — contra a redação original do DP4 na v0.14 (nascida e corrigida no mesmo dia).**
> A v0.14 mandava a fronteira consumir `chart-grid`, por leitura direta da condição (b) da §3c.
> A medição do `contraste-dp.py` derrubou: **`chart-grid` e `chart-no-data` têm o MESMO HEX nos
> dois temas** — `#E3EBF0` no light e `#38464F` no dark. Sobre um município sem medição a
> fronteira mede **1,00** contra o preenchimento: ela desaparece. Contra o território de
> contexto ela mede **1,11**, também muito abaixo do piso de 3:1.
> *Por que o defeito nunca apareceu no heatmap, que é o consumidor para o qual a condição (b)
> foi escrita:* lá a célula sem medição é hachurada e as vizinhas são sequenciais saturadas, de
> modo que a fronteira nunca precisa separar dois cinzas. **Num mapa, onde metade do território
> pode ser "sem medição", separar dois cinzas é o caso normal.**
> *Candidatas medidas contra o território de contexto no light:* `chart-grid` **1,11** ·
> `border-default` **1,37** · `border-strong` **2,33** · a tinta adotada **3,11** — única a
> passar. No dark a adotada mede **6,74**.
> *Por que não emprestar `chart-axis`, que tem o mesmo valor:* **no tema escuro `chart-axis` é o
> mesmo hex do `chart-no-data-hatch`** (`#90A6B3`). Emprestar faria a linha da fronteira e a
> tinta da hachura de "sem medição" serem o mesmo token por acidente — literalmente a estrutura
> da errata E3, num arquivo que a registra três vezes.
> **Classe de defeito:** *regra herdada de outro consumidor sem remedir o novo contexto.* É
> parente da E7 (herdar um número medido antes de um supersede de paleta).

**Consequência:** o DG14 permanece intacto e **ganha escopo declarado** — vale onde a
superfície de dado é **separável por espaço negativo** (barra, segmento de pilha, fatia,
área). Onde a geometria é contígua (mapa, heatmap), a fronteira é desenhada e consome
`chart-grid`.

> **E19-b — EXCEÇÃO DECLARADA POR VEREDITO (2026-08-24, gate F7.7-P1, saída (a):
> *"aceito sua sugestao, A"*).** O porte da camada de validação revelou o que a E19
> não havia medido: no tema claro a tinta adotada mede **2,80 sobre o sem-medição**
> (`chart-no-data`/`surface-sunken`, #E3EBF0) — abaixo do piso 3,0 que ela cumpre
> sobre o contexto (3,11). A razão é do PAR, não da tinta: o mesmo ci-500 sobre um
> fundo um degrau mais escuro rende menos. **A casa decidiu ACEITAR como exceção
> declarada**, porque a hachura já é o segundo separador da região (a SC 1.4.11 só
> cobra o par quando ele é o ÚNICO identificador) — mesma lógica da isenção do
> heatmap na §3c. O mesmo veredito cobre o `cat-2-stroke × sunken` (2,89), cujo
> segundo portador é a FORMA (E20). *Alternativas medidas e descartadas no gate:*
> **ci-600** passa todos os pares (4,37/3,93) mas **colide em valor com a tinta da
> hachura** (#617683) — a estrutura E3 que esta própria errata usou para recusar o
> `chart-axis`; **ci-700** passa com folga (6,03/5,43) sem colisão, mas dobra o
> peso do traço num desenho aprovado — recusada pelo custo visual. No tema ESCURO
> nada disso se aplica (a adotada mede 3,84–7,35). A exceção vive como código no
> `contraste-dp.py` (categoria própria `[exceção]`, com o número IMPRESSO a cada
> execução para a decisão poder ser re-julgada); placar do sub-bloco: **27 PASS ·
> 0 FAIL · 3 exceções por veredito**.
>
> **Fronteira honesta do alcance, medida na prova visual de 2026-08-24:** HOJE o par não é
> consumido por artefato nenhum — o único mapa com sem-medição é a demo do coropleto, e ela
> **não desenha fronteira** (pendência nova **DP-P7**). O par passa a ser real no momento em
> que o coropleto for ligado com dado real, porque aí o DP4 obriga a fronteira. Ou seja: a
> exceção não perdoa uma dívida existente — ela **DESTRAVA o conserto do DP-P7**, que sem ela
> nasceria com dois FAIL. Provado no navegador real, lupa 12× por captura em escala 1:1: com
> 2,80 a fronteira SEPARA os municípios sem medição e mantém a discrição que a E19 escolheu.

**Alternativa descartada, com o racional que a derruba:** erodir cada polígono para fabricar
o vão de 2px, que seria a leitura literal do DG14. É geometricamente possível e foi
considerada. Cai por dois defeitos medíveis: (i) em municípios estreitos a erosão de 2px por
lado consome a própria área, e o polígono some ou vira filete; (ii) onde não há vizinho — na
borda externa do estado — a erosão abre uma canaleta clara contra o fundo, **inventando uma
fronteira que não existe**. Um mapa que desenha limite onde não há limite é pior que um mapa
sem contorno.

**Fato vs. inferência:** que a §3c exige a fronteira desenhada é **fato** (texto vigente e
`estável`). Que a tinta dela no mapa é o `chart-geo-boundary` e não o `chart-grid` também é
**fato medido** desde a v0.15 (E19). O que permanece **não medido** é a largura mínima de
renderização da variante malha completa — pendência DP-P2, que é geometria e não cor.

---

### 4d.5 DP5 — Duas variantes de malha, e a segunda tem trava de largura

**Decisão:** o território do estado aparece **sempre inteiro**, sem recorte. O que varia é
**quais fronteiras municipais são desenhadas**:

- **Variante BASE** — padrão nos três destinos. Silhueta completa do estado; fronteira
  desenhada **apenas nos municípios com obra**. Traço: **estrutura, 1px**, em `chart-grid`.
- **Variante MALHA COMPLETA** — todas as fronteiras municipais desenhadas em **apoio, 0,5px**.
  Permitida **somente no ERP** e **acima de uma largura mínima de renderização a medir**.
  **Vetada** a 360px e em figura pequena de papel.

**Racional:** MG tem 853 municípios, BA 417 e ES 78 — **1.348 polígonos**. Desenhar 1.348
fronteiras numa figura que precisa caber num A4 de proposta e num celular de 360px não
informa: vira uma textura cinza uniforme, e o marcador da obra — que é o dado — se perde
dentro dela. A fronteira só ajuda quem já sabe qual município procurar, e o leitor de uma
proposta não sabe. **A variante base inverte isso:** a linha aparece onde há informação, e
por isso a linha *é* informação.

**Achado colateral que esta decisão resolve:** o §4c.3 registrou que o piso de **0,5px não
tem consumidor** — a grade do preview do DG está toda em 1px — e que "valor que existe na lei
sem ser exercido deriva", deixando a verificação para a Fase 6. **A fronteira municipal da
variante completa é o primeiro consumidor real do 0,5px.**

**Fronteira do instrumento, herdada do DI6 e registrada de propósito:** a folha de prova
impressa mediu **sobrevivência** da linha de 0,5px (a impressora consegue depositá-la?), não
**adequação** dela aplicada num desenho. A largura mínima da variante completa é medição de
adequação e é **pendência nominal DP-P2**.

**Alternativa descartada:** malha municipal completa e permanente em todos os destinos —
pedida no briefing e revista na mesma conversa. Cai por legibilidade, não por peso de arquivo:
mesmo simplificada e leve, ela piora o mapa nos três destinos, e piora mais no menor deles.

---

### 4d.6 DP6 — O piso de claridade NÃO se herda para polígono de município

**Decisão:** o piso de **6 pontos percentuais de espalhamento de claridade** — o número que
decide quando duas superfícies adjacentes se distinguem — **não vale para polígono de
município**, e não será herdado. Fica declarado como **calibração pendente**, a pagar quando
o coropleto (DP14) existir com dado real.

**Racional, que é aplicação direta da regra vigente e não decisão nova:** o supersede de
2026-08-11 (§4c.3 e §6) estabeleceu que **o piso é calibrado por FORMA de apresentação e vale
para aquela forma em qualquer meio** — e que forma nova exige recalibração por gate mesmo no
meio de sempre. Polígono de município é forma nova por três atributos simultâneos, nenhum
deles presente na forma em que o piso foi calibrado (barras altas adjacentes): é
**irregular**, tem **área muito variável** (dois vizinhos podem diferir em uma ordem de
grandeza) e tem **vizinhança imprevisível** (um município pode tocar dois ou onze outros).

**Por que não calibrar agora:** calibrar piso exige medir contra caso real. Sem dado por
município, o caso seria inventado — e um piso calibrado contra exemplo inventado é pior que
piso ausente, porque parece medição. Precedente direto: o `contraste-dg.py` v1 media três das
seis séries, dava verde, e **o verde impediu a procura por dois sub-blocos**.

**Pendência nominal DP-P3.**

---

### 4d.7 DP7 — Projeção: cônica EQUIVALENTE. Mercator é vetado

**Decisão:** o mapa SEED usa **projeção cônica equivalente (Albers)** — em `d3-geo`,
`geoConicEqualArea` com paralelos padrão calculados para o recorte MG-ES-BA. Datum de
referência: **SIRGAS 2000**, que é o que a malha de origem já traz (DP8). **Mercator, em
qualquer variante, é vetado.**

**Racional:** um coropleto compara áreas pintadas; se a projeção deforma área, o polígono
**mente sobre o dado antes de qualquer cor entrar**. A orientação técnica é explícita: ao
mapear valores num coropleto, usa-se projeção equivalente para que as áreas fiquem corretas
umas em relação às outras. A projeção de Albers é cônica equivalente com dois paralelos
padrão e é a usada no Brasil pelo IBGE; a referência técnica do próprio IBGE recomenda, para
cálculo de área no país inteiro, os parâmetros **longitude de origem -54°, latitude de origem
-12°, paralelos padrão -2° e -22°**.

**Racional do veto ao Mercator, com o número que o decide:** Mercator é o padrão de fato de
todo tutorial de mapa em React e de toda biblioteca de tiles, e deforma área em função da
latitude. Nosso recorte vai de aproximadamente **-8°** (norte da Bahia) a **-22°** (sul de
Minas). A deformação seria **sistemática e direcional**, inflando a Bahia contra Minas — num
mapa de atuação, isso é mentira visual da empresa sobre si mesma, e ela cresce justamente no
estado onde a SEED tem a operação mais recente.

**Fronteira declarada:** os parâmetros do IBGE citados acima são calibrados para o **Brasil
inteiro**. Para o recorte MG-ES-BA os paralelos padrão devem ser **recalculados**, por script,
com o valor resultante declarado no arquivo canônico e no asset. **Pendência nominal DP-P4.**

**Alternativa descartada:** projeção Policônica, usada pelo IBGE no mapeamento oficial em
escala geográfica. Cai porque não é equivalente nem conforme — só se aproxima disso perto do
meridiano central — e o DP precisa da propriedade de área preservada de forma garantida,
não aproximada.

---

### 4d.8 DP8 — Malha: IBGE, com o ANO declarado, versionada como asset do DS

**Decisão:** a fonte da geometria é a **Malha Municipal Digital (MMD) do IBGE**, publicada em
Shapefile e agrupada por estado, com **SIRGAS 2000** e codificação **UTF-8**. É convertida por
script para **TopoJSON** e versionada como **asset do próprio Design System** — não como
dependência de runtime instalada no ERP.

**Duas advertências do próprio IBGE entram no canônico, porque num laudo de engenharia elas
importam mais que a estética:**
1. Os limites da MMD devem ser entendidos como **aproximados**, e o IBGE se isenta de
   responsabilidade por usos que não sejam a compilação de dados estatísticos.
2. O IBGE **não tem atribuição legal** para definição e demarcação de limites territoriais.

**Consequência dura, que precisa estar escrita e não apenas sabida:** o mapa da SEED **não
serve como peça de definição de limite territorial**. Serve para localizar obra e comunicar
atuação. Se um dia um documento da empresa precisar afirmar de que município é um ponto para
efeito legal ou regulatório, a fonte é a documentação do imóvel e da concessionária — não este
mapa.

**Terceira consequência, operacional:** a MMD é **republicada anualmente**, e municípios
mudam de limite entre publicações. O asset **declara o ano no nome do arquivo e no
MANIFESTO**. Sem isso, dois mapas da empresa produzidos com seis meses de diferença podem
discordar sem que ninguém saiba por quê — a classe de defeito "artefato que mente sobre si
mesmo" já custou uma nota permanente no §3.1 do `MANIFESTO.md`.

**Alternativas descartadas:**
- *Pacote npm de malha brasileira.* O desenho poderia mudar numa atualização de dependência,
  sem pedido e sem gate — exatamente o risco que o **DF7** existe para evitar (tokens de dado
  têm uma fonte). Malha é geometria de dado; o argumento é o mesmo.
- *Base comercial editável (mapas de município vendidos como objeto de PowerPoint).* Existem e
  custam por estado. Caem porque devolvem geometria **digitada/desenhada** no lugar de
  geometria **calculada**, contra a regra de método do projeto, e porque a licença de
  redistribuição num PDF de cliente teria de ser auditada peça a peça.
- *Serviço de mapa hospedado (Google/Mapbox).* Já vetado no DP2 por identidade e impressão;
  soma-se aqui o custo por carregamento e a dependência de rede num documento que precisa
  funcionar off-line.

---

### 4d.9 DP9 — Simplificação por script, tolerância declarada, dois níveis de asset

**Decisão:** a malha é **simplificada por script** (algoritmo de Visvalingam, via `mapshaper`),
com **tolerância declarada no arquivo**, e o asset é publicado em **dois níveis de resolução**:

- **Nível FIGURA** — para o laudo, a proposta e o site; otimizado para larguras pequenas e
  para impressão a 300 dpi.
- **Nível ERP** — mais detalhado, para telas grandes e para a variante malha completa (DP5).

**Racional:** a malha municipal cheia dos três estados é inviável na web por peso, e
simplificar "no olho" produz um desenho que ninguém consegue reproduzir. Regra herdada e não
negociável do projeto: **geometria é calculada por script, nunca digitada**, e o script leva
asserção que falha se qualquer rótulo estourar o `viewBox` — o defeito de 9px do DM nasceu
exatamente da ausência dessa asserção.

**Pendência nominal DP-P5:** *qual* tolerância. Isso é **gate, não pesquisa** — a medição é
ver o desenho quebrar: o valor certo é o maior que ainda preserva a silhueta reconhecível do
estado e a identidade dos municípios de fronteira recortada.

**Alternativa descartada:** um único nível de asset servindo os três destinos. Cai porque os
requisitos são opostos — o que sobrevive a 300 dpi no papel é pesado demais para o site, e o
que é leve o bastante para o site perde detalhe visível na impressão.

---

### 4d.10 DP10 — Marcador: cor até 3 categorias, FORMA acima disso. Textura não se aplica

**Decisão (REESCRITA na v0.15 pela medição — ver errata E20):** a categoria de um marcador
(tipo de solução: fotovoltaico, subestação, GMG, projeto elétrico, consultoria) é codificada
pela **FORMA**, sempre; a **cor é redundância**, nunca o portador. Vocabulário de três
posições, e o teto é **3 categorias por mapa**:

| Posição | Forma |
|---|---|
| 1 | círculo |
| 2 | quadrado |
| 3 | triângulo |

**Teto de 3 categorias por mapa.** Acima disso, o mapa se reestrutura: um mapa por tipo de
solução (facetas), ou destaque × contexto no padrão do **DG17**.

**Paleta do marcador: `cat-1` (turquesa) · `cat-3` (magenta) · `cat-4` (azul).** O dourado
(`cat-2`) **fica de fora, e isso não é regra nova**: a regra do dourado da §3c já o veta como
*fill solitário sem rótulo direto*, e um marcador de mapa é precisamente um preenchimento
pequeno e solitário. Medido: `cat-2` contra o território mede **1,54–1,85** no light.

**O marcador leva contorno na variante `cat-N-stroke`.** Não é ornamento: o *fill* sozinho
reprova o piso de 3:1 contra o território no light — `cat-1` mede **2,97** e `cat-4` **3,05**.
Com o contorno: **4,23 · 5,23 · 3,05**. A variante `cat-N-stroke` existe no sistema exatamente
para isto, e a descrição dela nos gêmeos já nomeia o caso: *"traço fino (linha ≤3px, marcador
pequeno — o pior caso do 1.4.11)"*. **Isto não contraria o DG14**, que trata de superfícies
adjacentes separáveis por espaço negativo; o marcador é objeto solto sobre o território.

> **ERRATA E20 — contra a redação original do DP10 na v0.14.** A v0.14 dizia *"cor até 3
> categorias; acima de 3, forma"*, e **descartava explicitamente** a redundância cor+forma desde
> a primeira categoria, alegando ruído. **A medição inverte a decisão.** Espalhamento de
> claridade entre os marcadores, que é a métrica certa para distinguir superfícies (§4.4):
>
> | Par | Light | Dark |
> |---|---:|---:|
> | `cat-1` × `cat-3` | 6,8 pontos | **3,6** |
> | `cat-1` × `cat-4` | **0,9** | **3,7** |
> | `cat-3` × `cat-4` | 6,0 pontos | **0,2** |
>
> Piso de 6 pontos (calibrado pelo gate, **não** derivado de norma). **No tema escuro as três
> cores colapsam** — 0,2 a 3,7 pontos —, e mesmo no light o par `cat-1 × cat-4` mede **0,9**.
> Como o mapa vai obrigatoriamente para impressão (mono é grayscale por definição) e para o ERP
> (que tem tema escuro), **não existe cenário em que a cor sustente a categoria sozinha**.
> Logo a forma não é o plano B: é o portador. *A alternativa que a v0.14 descartou por "ruído"
> era a correta, e o que a derrubou foi eu ter raciocinado em vez de medir* — o mesmo erro
> registrado no §7 da v0.11 ("não diagnostique por raciocínio: meça").
> **Consequência sobre o gatilho:** em mapa não há gatilho condicional de forma como há para a
> textura (DI2). A forma é **permanente** a partir da 2ª categoria; com uma única categoria o
> marcador é círculo e não há o que distinguir.

**Racional, e este é o único ponto do DP que inventa vocabulário em vez de herdar.** O
**DI2** (§4c.2) manda texturizar por série quando `grayscale ∩ (escuro OU ≥4 séries)`. A
regra é boa e permanece vigente — **mas o veículo dela não existe aqui**. Textura precisa de
área para ser lida: quadriculado, pontilhado ou linhas verticais dentro de um marcador de
8–12px não produzem padrão, produzem sujeira, e em impressão a laser ou fotocópia produzem um
borrão. O DI2 não é contrariado; ele é **atendido por outro vocabulário**, porque a forma de
apresentação mudou — que é precisamente a lógica do supersede da regra do piso (§4c.3): o
instrumento vale para a **forma** em que foi calibrado.

**Consequência que é melhor descobrir agora:** o teto útil de categorias num mapa é **3**, e
não os 6 da categórica estendida. Um mapa da SEED não consegue mostrar os cinco pilares da
empresa como cinco marcadores distintos e continuar legível em escala de cinza. Isso é
restrição real e está declarada.

**Alternativas descartadas:**
- *Reduzir a hachura proporcionalmente ao tamanho do marcador.* É a mesma armadilha já
  rejeitada na extensão do vocabulário de textura (§4.4): a distinção viraria **densidade**,
  frágil no papel e pior ainda em fotocópia.
- *Losango, estrela e cruz como 4ª, 5ª e 6ª formas.* Caem porque perdem identidade a 8–12px:
  losango lê como quadrado girado e estrela lê como mancha. Círculo, quadrado e triângulo
  diferem em **número de vértices**, que é o atributo que sobrevive à redução.
- ~~*Cor + forma redundantes desde a 1ª categoria.*~~ **Esta alternativa foi descartada na v0.14
  e READMITIDA na v0.15 como a decisão vigente** — a medição mostrou que a premissa do descarte
  ("com uma ou duas categorias a cor resolve sozinha nos dois temas") é falsa: no dark os pares
  medem 0,2 a 3,7 pontos de claridade. Registro mantido à vista de propósito, porque descarte
  errado que some do arquivo volta a ser proposto.
- *Codificar a categoria pelo TAMANHO do marcador.* Cai porque tamanho já tem dono declarado
  (magnitude, ver regra de tamanho abaixo), e um atributo com dois donos é a estrutura do
  defeito que o DM3 corrigiu no medidor.

**Regra de tamanho:** o marcador tem **um papel de tamanho por vez**. Se o tamanho carrega
magnitude (potência instalada, por exemplo), ele não carrega também contagem de agrupamento
(DP11) no mesmo mapa. **Alvo de toque:** no ERP, a área clicável do marcador é de no mínimo
**44×44px**, independentemente do tamanho desenhado — o marcador visual pode ter 12px com área
de toque invisível maior.

---

### 4d.11 DP11 — Agrupamento, colisão e o halo

**Decisão:** município com **mais de uma obra** exibe **um marcador com contagem numérica**,
não vários pinos sobrepostos. O marcador leva **halo na cor do fundo do território** —
o mesmo mecanismo de espaço negativo do DG14.

**Racional:** pinos empilhados em município pequeno viram uma mancha cuja área não significa
nada, e a contagem que o leitor tentaria fazer visualmente estaria errada. O halo é legítimo
aqui — e não contraria o DG14 — porque o marcador é um objeto **solto sobre** o território,
não uma superfície adjacente a outra superfície de dado: existe espaço para o vão, que é
exatamente a condição que o DP4 declarou faltar entre municípios.

**A contagem exata vive no fallback textual do DP1.** O número no marcador é conveniência de
leitura; a tabela é a fonte.

---

### 4d.12 DP12 — LGPD: destino externo e destino interno são mapas diferentes

**Decisão:**

- **Destino externo** (site institucional, proposta comercial, material de marketing, qualquer
  peça que sai da empresa): o marcador comunica **município + tipo de solução + faixa de
  porte**. **Nunca** nome de cliente, **nunca** número de unidade consumidora (UC), **nunca**
  endereço, **nunca** razão social.
- **Destino interno** (ERP, atrás de autenticação): identificação permitida. A
  responsabilidade passa a ser do controle de acesso, não do desenho.

**Racional:** um pino rotulado com o nome do cliente num mapa de atuação exibido a um
**terceiro** expõe a carteira da empresa a quem não deveria vê-la, e o dado é pessoal
identificável quando o cliente é pessoa física ou produtor rural — o que é o caso comum na
carteira de irrigantes. Aqui a questão é de conformidade antes de ser de design, e o custo de
errar não é estético.

**Regra de fechamento, sem a qual a anterior não vale nada:** o **fallback textual do DP1
obedece à mesma separação**. Não adianta omitir o nome no mapa e vazá-lo na tabela ao lado —
e a tabela é justamente a parte que é copiada, exportada e colada em outro documento.

---

### 4d.13 DP13 — Impresso e interação

**Impresso — herança direta do sub-bloco DI, sem regra nova:**
- **DI4:** nenhuma informação do mapa pode viver em `background-color` de CSS. Território,
  fronteira e marcador são `<path>`/`<rect>`/`<circle>` com `fill`/`stroke` de SVG. Medido no
  DI: sob impressão econômica, o `background` de CSS **some** e o `fill` de SVG sobrevive.
- **DI5:** `break-inside: avoid` no `<figure>` inteiro — o mapa e a sua legenda nunca se
  partem entre páginas. Proteger o bloco **atômico**, nunca o contêiner que o agrupa (E18).
- **`@page` declara a orientação.** Um mapa dos três estados é mais alto que largo; se a
  figura pedir paisagem, a orientação vai em CSS. Precedente registrado: uma rodada de prova
  saiu em paisagem por opção herdada do driver e gerou 11 páginas no lugar de 6.
- **`vector-effect: non-scaling-stroke`** aplicado por **seletor universal** (`.plot svg *`),
  nunca em `<g>` — a propriedade **não é herdada** em SVG 2 (errata E17). Num mapa isso é
  crítico: o `viewBox` de um mapa escala muito mais que o de um gráfico de barras, e sem o
  atributo a hierarquia de traço de 1px e 0,5px do DP5 é destruída pelo layout responsivo.

**Interação:**
- **Figura fixa é a norma.** O mapa completo não depende de nenhuma interação para ser lido.
- **Tooltip** é permitido no ERP como **enriquecimento** e **nunca** como portador único de
  informação. Mesma lei do DG1: tooltip não existe no papel, e o que só vive nele não existe
  no laudo.
- **Zoom e pan estão FORA do escopo do DP.** São comportamento de tela, logo produto — mesma
  fronteira que já separou tempo real e websocket no DM10.
- **Teclado:** herda o **DG2** — o mapa inteiro é **um** tab-stop. O caminho de acesso real é
  a lista/tabela de municípios do DP1, não a navegação por marcadores.

---

### 4d.14 DP14 — O coropleto fica ESCRITO, não implementado

**Decisão:** o coropleto (mapa com municípios preenchidos por intensidade de cor) **não é
implementado neste sub-bloco**, mas fica especificado ao ponto de quem o implementar não
precisar tomar nenhuma decisão nova de design. O que já está decidido e vale quando ele for
ligado:

| Questão | Já decidido em |
|---|---|
| Escala de cor | **§3c do `seed-tokens.md`** — sequencial `chart-seq-1…7`, 100→900 no light e 800→100 no dark. A §3c já nomeia "mapa coroplético" como consumidor desde o DT |
| Condições obrigatórias da isenção 1.4.11 | §3c: (a) valor acessível por rótulo, tooltip ou tabela-fallback · (b) fronteira por `chart-grid` · (c) legenda com os limites numéricos das classes |
| Fronteira entre polígonos | **DP4** |
| Papel dos três estados do território | **DP3** |
| Projeção equivalente | **DP7** |
| Malha municipal completa e simplificação | **DP8**, **DP9** |
| Piso de claridade | **DP6** — pendente de calibração por gate |

**Racional de não implementar agora:** o coropleto pinta um **número por município**. A
empresa não tem hoje esse número organizado para os 1.348 municípios dos três estados, e um
coropleto sem dado real pinta ar. Implementá-lo agora custaria a calibração de piso do DP6 —
que só pode ser feita contra caso real — para produzir um artefato que ninguém consegue
alimentar.

**Alternativa descartada:** entregar ponto e coropleto em camadas sobrepostas desde já.
Cai por custo desproporcional: o marcador teria de ser legível por cima de **sete** tons de
fundo diferentes nos dois temas, o que é o pior caso de contraste do sistema inteiro, e
obrigaria a resolver dois problemas novos ao mesmo tempo — sem que o dado do coropleto
exista.

---

### 4d.14b DP15 — Ilhas oceânicas saem do DESENHO, nunca do dado

**Decisão (2026-08-11, aprovada pelo Rafael):** o arquipélago de **Trindade e
Martim Vaz**, administrativamente parte do município de **Vitória (ES)** e a cerca
de 1.100 km da costa, é **recortado do desenho** do mapa. O município de Vitória
permanece no mapa, na tabela e em qualquer agregação — o que sai é somente a
geometria das ilhas.

**Medição que motivou:** com as ilhas, a extensão de longitude do recorte vai a
**22,20°**; sem elas, a **13,70°**. São **8,5° de oceano vazio** — cerca de 40% da
largura da figura sem informação nenhuma, com os três estados espremidos no canto.
A variante malha completa do DP5 deixaria de funcionar e a leitura a 360px ficaria
inviável. **5 anéis removidos, 901 vértices, nenhum município removido.**

*Regra operacional:* o corte é por longitude declarada (**-35°**), valor que cai no
vazio entre o litoral continental do ES (≈ -39,7°) e o arquipélago (≈ -29,5°) — não
há ambiguidade possível.

*Alternativa descartada:* **inset com quebra de escala**, no padrão que os atlas usam
para Alasca e Havaí. Exigiria um componente novo — moldura, escala própria, marca de
descontinuidade — que o DP não especifica. Fica registrada como caminho.

**A exclusão é DECLARADA no asset e no preview, nunca silenciosa.** O espelho de
GitHub que serviu de fonte provisória fazia exatamente o mesmo corte **sem dizer**,
e isso só apareceu porque a extensão foi medida. *Fronteira já escrita no DP8 e que
sustenta esta decisão:* este mapa não é peça de definição de limite territorial.

---

### 4d.15 Matriz de render do DP — uma dimensão a mais

A matriz de render se **cruza, não se amostra** (regra da fase). O DP acrescenta uma dimensão
que nenhum sub-bloco anterior teve: **largura de renderização**, porque um mapa legível a
1200px pode ser ilegível a 360px e a malha exige simplificação diferente em cada faixa.

| Dimensão | Valores |
|---|---|
| Tema | claro · escuro |
| Grayscale | não · sim |
| **Largura** | **360 · 768 · 1200** |
| Impressão | tela · impresso (A4, com orientação declarada) |

O par que historicamente esconde defeito é **escuro × grayscale** (foi ali que morava o
colapso de séries do DG13). No DP, o par novo a vigiar é **360px × malha completa** — que o
DP5 já veta, e o teste existe para provar que o veto é real e não decorativo.

> **REGRA NOVA, nascida do gate visual de 2026-08-11 e mais geral que o DP: simular uma
> dimensão da matriz só vale se a simulação dirigir as MESMAS regras que a realidade dirige.**
> O preview v0.1 tinha um controle de largura que mudava o `max-width` do contêiner, enquanto as
> regras responsivas de layout respondiam à largura da **janela**. As duas coisas nunca se
> encontravam: ao escolher "360", as duas figuras do DP5 continuavam lado a lado, com cerca de
> **170px cada** — e o que estava na tela não era a célula 360 da matriz, era uma célula que não
> existe. **A dimensão largura nunca havia sido exercida.** Correção no preview v0.2: o contêiner
> vira *container de consulta* (`container-type: inline-size`) e as regras de layout passam a ser
> `@container`, de modo que o controle e a janela real disparem exatamente o mesmo conjunto de
> regras. Guardas permanentes `LARG-01` a `LARG-05` na `suite-dataviz-dp.mjs`; *prova de que são
> reais:* contra o preview v0.1, reprovam em **3**.
>
> *Classe de defeito:* **instrumento ancorado no lugar errado** — a mesma família de "teste
> ancorado no seletor errado" (DG7-03, `contraste-dg.py`, DI6-02), aqui aplicada não ao teste e
> sim ao **simulador**. E o achado é do olho humano: nenhuma das 68 verificações automatizadas
> via, porque jsdom não resolve layout e a suíte conferia a presença da regra, não quem a
> dispara. *Fronteira honesta:* isto é gate visual fazendo o que a automação não faz — o Rafael
> mandou uma captura da tela a 360px e a captura mostrava duas figuras onde deveria haver uma.

---

### 4d.16 Pendências nominais abertas pelo DP

Nenhuma bloqueia a escrita da spec; todas bloqueiam a promoção a `estável`.

| Id | Pendência | Como fecha |
|---|---|---|
| ~~**DP-P1**~~ | ~~Token do território de contexto e contraste contra a fronteira e o marcador~~ | **FECHADA na v0.15, no mesmo dia em que nasceu.** Instrumento: `contraste-dp.py` v1. Resultado: **dois** tokens novos (`chart-geo-base`, `chart-geo-boundary`) na v1.8 dos três gêmeos, mais as erratas **E19** (fronteira não é `chart-grid`) e **E20** (a forma é o portador da categoria, não a cor). *O que o episódio prova:* a pendência foi declarada como "medir na edição" e a medição **mudou duas decisões já aprovadas** — declarar pendência em vez de chutar valor foi o que impediu que as duas entrassem no preview |
| ~~**DP-P2**~~ | ~~Largura mínima de renderização para a variante malha completa~~ | **FECHADA em 2026-08-11, por medição sobre a malha real: a variante malha completa exige ≥ 640px de largura de renderização.** *Instrumento:* a fronteira de 0,5px é constante (`non-scaling-stroke`); o que varia com a largura é o **tamanho do município em pixels**. Medida a menor dimensão de cada um dos 1.348 municípios no viewBox de 640 — p5 **3,33** · mediana **7,42** · p75 **10,75** — e escalada por largura. *Piso declarado, calibrado aqui e **não** derivado de norma:* mediana ≥ **6px** e p5 ≥ **2px**, porque entre duas fronteiras de 0,5px precisa sobrar interior para o olho separar linha-interior-linha. Resultado: **360px** (mediana 4,17 · p5 1,87) e **480px** (5,56 · 2,50) reprovam; **640px** (7,42 · 3,33) passa. O veto do DP5 a 360px, que era inferência, passa a ser **fato medido**. Instrumento em `validacao/medir-dpp2.mjs` |
| ~~**DP-P3**~~ | ~~Piso de claridade para polígono de município~~ | **FECHADA em 2026-08-11 como DECISÃO, não como medição — e a distinção é o ponto.** O piso **não foi calibrado**: foi declarado **não herdável** (§4d.6) e adiado até existir coropleto com dado real. *Racional:* calibrar piso exige medir contra caso real; sem dado por município o caso seria inventado, e piso calibrado contra exemplo inventado é **pior que piso ausente**, porque parece medição. Precedente direto: o `contraste-dg.py` v1 media três das seis séries, dava verde, e **o verde impediu a procura por dois sub-blocos**. A pendência sai da lista do DP e entra como **pré-requisito declarado do DP14** — quem implementar o coropleto calibra o piso por gate antes de ligar |
| ~~**DP-P4**~~ | ~~Paralelos padrão da projeção para o recorte MG-ES-BA~~ | **FECHADA em 2026-08-11.** Calculados por script a partir da extensão real da malha oficial, pela regra de Deetz & Adams (paralelos a 1/6 e 5/6 da faixa de latitude): **-20,52°** e **-10,93°**, origem -15,73° / -44,19°. *Descartados:* os parâmetros que o IBGE recomenda para o Brasil inteiro (origem -54°/-12°, paralelos -2° e -22°) — são calibrados para um recorte 6× maior e jogariam os dois paralelos padrão para fora da área de interesse |
| ~~**DP-P5**~~ | ~~Tolerância de simplificação por nível de asset~~ | **FECHADA em 2026-08-11, e o resultado SUPERSEDIU o DP9** (§6): nível único a **2%**, com piso declarado de erro de área p99 ≤ 2%. Sete tolerâncias varridas e medidas |
| ~~**DP-P6**~~ | ~~Ano da Malha Municipal Digital do IBGE adotado~~ | **FECHADA em 2026-08-11: edição 2025**, baixada do portal oficial pelo Rafael e anexada em três pacotes Shapefile (MG, ES, BA), SIRGAS 2000, UTF-8. *Registro do que foi descartado:* antes disso a malha veio do espelho `tbrugz/geodata-br` no GitHub, porque o domínio do IBGE não é acessível da máquina de execução. As contagens batiam (853 · 78 · 417), mas a medição de vértices expôs a diferença — **143.319 no espelho contra 4.251.625 no oficial**: o espelho já era uma malha ~30× simplificada e não declarava isso |
| ~~**DP-P7**~~ | **A demonstração do coropleto (fig-dp3, "Os três estados do território") não desenha fronteira nenhuma — 1.404 polígonos, ZERO traço (MEDIDO em 2026-08-24, no navegador real, durante a prova visual da E19-b).** O DP4 é explícito em contrário: *"a fronteira entre regiões é desenhada, nunca deixada por conta da diferença de cor"*. Consequência visível na lupa 12×: dois municípios sem medição adjacentes **se fundem numa mancha só** — o leitor não sabe se é um ou três. | **FECHADA em 2026-08-24, veredito dele: "opção B é melhor".** O `gen-dp.py` passou a desenhar fronteira na variante `coropleto` como já fazia na `completa` — **medido depois: 1.348 fronteiras, `#788F9D`, espessura 0,5** (tinta vigente, espessura de apoio). O que tornou o conserto possível sem criar FAIL foi a própria **E19-b**: sem a exceção declarada, cumprir o DP4 aqui produziria dois pares abaixo do piso. Nada regrediu: suíte do DP 82·0, render 22·0, contraste 27·0 com as 3 exceções, escala-figura 93·0, paridade 235·0. *Registro do estado anterior:* não bloqueava nada (o coropleto é DP14 = escrito, não implementado), e por isso não é errata: é a demo que ilustra menos do que a spec manda. Fecha dando fronteira `chart-geo-boundary` (espessura `.5`, a `.fronteira.apoio` da própria bancada) aos polígonos do fig-dp3 — e é EXATAMENTE isso que a **E19-b torna possível sem criar FAIL**: sem a exceção declarada, cumprir o DP4 aqui produziria dois pares abaixo do piso. |

---

