---
version: alpha
name: Dataland Landbank
description: >-
  Design system do Landbank, produto de viabilidade de terreno para
  incorporadora. Gerado de estilo/00-tokens.css por ds/gera.py: NÃO
  editar à mão. O analista desafia número, então todo valor na tela
  declara de onde vem.
colors:
  primary: "{colors.acao}"
  acao: "#3D2177"
  acao-2: "#2C1758"
  acao-fraco: "rgba(61,33,119,.06)"
  acao-borda: "rgba(61,33,119,.28)"
  marca-ouro: "#FCB830"
  tinta: "#16161C"
  ink: "#2A2A34"
  ink-2: "#4A4A57"
  t2: "#494954"
  t3: "#71717D"
  t4: "#666670"
  decor: "#B0B0BA"
  ok: "#007A55"
  ok-tx: "oklch(0.448 0.119 151.328)"
  at: "#BB4D00"
  at-tx: "oklch(0.553 0.195 38.402)"
  no: "#C10007"
  no-tx: "oklch(0.505 0.213 27.518)"
  info: "#1B5FB8"
  info-tx: "oklch(0.488 0.243 264.376)"
  ok-t: "#F2F8F6"
  at-t: "#FCF8F5"
  no-t: "#FCF2F3"
  info-t: "#E5EEFB"
  off: "#54545F"
  off-t: "#F1F1F3"
  dourado: "#846014"
  c1: "#5B63A8"
  c2: "#B08430"
  c3: "#AB5252"
  c4: "#3F8069"
  c5: "#6E7480"
  papel: "#FFFFFF"
  shell: "rgba(255,255,255,.94)"
  mundo: "#F2F2F6"
  linha: "rgba(20,20,34,.10)"
  linha-2: "rgba(20,20,34,.055)"
  linha-3: "rgba(20,20,34,.20)"
  veu-modal: "rgba(20,20,34,.32)"
  sup: "#FFFFFF"
  sup-tinta: "{colors.tinta}"
  sup-2: "rgba(20,20,34,.05)"
  sup-2-tinta: "{colors.t2}"
  sup-3: "rgba(20,20,34,.08)"
  flutua: "rgba(255,255,255,.98)"
  flutua-tinta: "{colors.ink}"
  calada: "{colors.t3}"
  borda: "{colors.linha}"
  borda-forte: "{colors.linha-3}"
  anel: "rgba(73,73,84,0.65)"
  marca: "{colors.acao}"
  marca-tinta: "#fff"
  forte-neutro: "{colors.tinta}"
  cheio-tinta: "#fff"
  sombreia: "#000"
  r-g: "{colors.r}"
typography:
  display:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 40px
    fontWeight: 600
    lineHeight: 1.05
    letterSpacing: "-.03em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  titulo1:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 32px
    fontWeight: 600
    lineHeight: 1.1
    letterSpacing: "-.03em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  titulo2:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 24px
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: "-.015em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  titulo3:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 19px
    fontWeight: 600
    lineHeight: 1.3
    letterSpacing: "-.015em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  destaque:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 15px
    fontWeight: 400
    lineHeight: 1.65
    letterSpacing: "0em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  corpo:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.7
    letterSpacing: "0em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  pequeno:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 13px
    fontWeight: 400
    lineHeight: 1.6
    letterSpacing: "0em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  mono:
    fontFamily: "'Geist Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace"
    fontSize: 12.5px
    fontWeight: 400
    lineHeight: 1.65
    letterSpacing: "0em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
  rotulo:
    fontFamily: "'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif"
    fontSize: 12px
    fontWeight: 600
    lineHeight: 1.4
    letterSpacing: ".06em"
    fontFeature: "cv11, ss03"
    fontVariation: "wght"
rounded:
  xs: 3.0px
  md: 4.02px
  lg: 6px
  full: 999px
spacing:
  linha: 20px
  gutter: 16px
  rail: 162px
components:
  button-primary:
    backgroundColor: "{colors.acao}"
    textColor: "{colors.marca-tinta}"
    rounded: "{rounded.md}"
    typography: "{typography.pequeno}"
  button-outline:
    textColor: "{colors.t2}"
    rounded: "{rounded.md}"
  button-ghost:
    textColor: "{colors.t2}"
    rounded: "{rounded.md}"
  button-danger:
    textColor: "{colors.no-tx}"
    rounded: "{rounded.md}"
  badge-neutral:
    backgroundColor: "{colors.sup-2}"
    textColor: "{colors.t2}"
    rounded: "{rounded.md}"
  badge-primary:
    backgroundColor: "{colors.acao-fraco}"
    textColor: "{colors.acao}"
  badge-success:
    backgroundColor: "{colors.ok-t}"
    textColor: "{colors.ok-tx}"
  badge-success-solid:
    backgroundColor: "{colors.ok-tx}"
    textColor: "{colors.cheio-tinta}"
  badge-warning:
    backgroundColor: "{colors.at-t}"
    textColor: "{colors.at-tx}"
  badge-danger:
    backgroundColor: "{colors.no-t}"
    textColor: "{colors.no-tx}"
  badge-muted:
    backgroundColor: "{colors.off-t}"
    textColor: "{colors.off}"
---

<!-- GERADO por ds/gera.py a partir de estilo/00-tokens.css. Editar aqui não serve: o próximo `python3 ds/gera.py` sobrescreve. A prosa mora em ds/gera.py (PROSA/ESTILOS/COMPONENTES). -->

## Overview

Prancheta de urbanista: papel, grafite, carimbo de processo. O grafite carrega o **dado**; o indigo de marca marca **três coisas por tela** e nada mais — a marca, a ação primária e o objeto em foco no mapa; o semântico (verde, âmbar, vermelho) carrega o **veredito**.

O dourado de marca aparece em **um lugar só**, a marca no rail: âmbar nesta interface já significa "atenção", e dourado em qualquer outro lugar colidiria de sentido.

A regra que governa tudo: **nenhum número órfão**. Todo valor na tela declara se vem de dado público, de referência Dataland, de premissa do cliente, ou se é derivado dos três. Vale pra tela, pra documentação e pra este arquivo.

## Colors

**Cada papel semântico é um PAR, não uma cor.** Uma entrada para componente — borda, rail, ícone, preenchimento — que precisa de 3:1 pela WCAG 1.4.11; e outra `-tx` para texto, que precisa de 4,5:1. Usar o tom de componente como texto reprova AA. Nunca escolha um tom semântico sem escolher o par certo para o papel.

Contraste **medido no navegador**, compondo a pilha real de fundos translúcidos — nunca calculado de cabeça:

| par | sobre a folha | sobre o fundo da janela |
| --- | --- | --- |
| `ok` (componente) | 3,22:1 | **2,88:1 — reprova o 3:1** |
| `ok-tx` (texto) | 7,13:1 | 6,39:1 |
| `t2` (secundário) | 8,90:1 | 7,95:1 |
| `t3` (terciário) | 4,82:1 | **4,31:1 — reprova o 4,5:1** |
| `anel` (foco) | 3,47:1 | 3,32:1 |

Consequências práticas: **não use `t3` nem `t4` sobre o fundo da janela** — use `t2` e faça hierarquia por tamanho e peso, não clareando até sumir. E **borda ou ícone verde de 1px direto sobre o fundo da janela não é acessível**; sobre a folha, é.

**Foco é cinza neutro, nunca a marca.** O roxo chama atenção pro campo em vez do conteúdo que a pessoa está lendo ou digitando.

**Tema escuro** existe como sobreposição em `:root[data-tema="escuro"]`, e **só troca papel** — nenhum componente sabe que ele existe. Duas inversões importam pra quem gera código: o token de escurecimento de hover **inverte** (escurecer sobre canvas escuro faz o elemento desaparecer), e a tinta sobre preenchimento cheio vira **escura**, porque os preenchimentos passam a usar tons claros. Canvas é quase preto e **nunca preto puro**.

## Typography

**'Inter'** para interface e **'Geist Mono'** para código e dado tabular. As duas são variáveis, servidas do próprio repositório em `estilo/fontes/`, subset latin.

Nove tamanhos, **dois pesos de texto corrido**, cinco valores de tracking. Um terceiro peso entre 400 e 600 fica ambíguo de longe, então 500 é reservado para tecla (kbd) e nunca para parágrafo.

**Tracking anda com o tamanho**: negativo forte no display, zero no corpo, positivo em caixa alta. Não escolha tracking por gosto — use o estilo nomeado do bloco acima.

As features `cv11` e `ss03` ficam ligadas globalmente e são funcionais: `cv11` desambigua **1** de **l** e **I**, `ss03` dá o cedilha desenhado do português. Numa coluna de dado, "111" e "Illl" quase idênticos e o pior lugar possível para ambiguidade. **Se sobrescrever `font-feature-settings`, repita as duas** — a propriedade substitui, não acumula.

## Layout

**Tudo alinha pela primeira linha do bloco, nunca pelo centro.** A altura do bloco varia com o conteúdo (uma linha tem aviso, a outra não), e centralizar faz o mesmo elemento flutuar em alturas diferentes de linha pra linha. `spacing.linha` (20px) é a altura dessa primeira linha: todo elemento-líder de coluna se centra dentro dela, não do bloco inteiro. Centro só vale quando o elemento **é** a linha inteira.

A grade de coluna da fila é uma variável única compartilhada pelo cabeçalho e pelas linhas (`22px minmax(0,1fr) 96px 296px 28px`). Se cabeçalho e corpo divergirem, a coluna do header deixa de bater com a do dado e não existe erro que avise.

**Camada que aparece não empurra conteúdo.** Popover, tooltip e painel flutuam por cima; se for inline, o espaço é reservado antes. Salto de layout é bug. Toda tela é conferida em 320, 768, 1024 e 1440px.

## Elevation & Depth

Uma estratégia só: **sombra em camadas**, não sombra e borda escolhidas separadamente por tela. Três degraus neutros (card, popover, modal) mais **um realce colorido, e só a ação primária o usa** — as outras três são profundidade, esta é ênfase, então é papel diferente e não um quarto degrau da mesma escala.

**No tema escuro os quatro mudam de natureza**: sombra quase não aparece sobre canvas escuro, e o degrau passa a ser feito por hairline e superfície mais clara.

## Shapes

**Uma base, o resto derivado por cálculo.** `--r` vale 6px e os outros degraus saem dele: "menos arredondado" é mudar um número, não caçar quatro valores soltos.

Existe **uma exceção documentada**: o contador redondo do badge, 19x19, porque é um número solto e não uma caixa de texto. Não crie outras.

## Components

**IMPORTE, NAO RECRIE.** Os componentes prontos existem em código e o caminho é este:

```tsx
import { Button } from '@/componentes/Button/Button'
import { Badge } from '@/componentes/Badge/Badge'

<Button variant="primary">Avaliar terreno</Button>
<Badge tone="success" weight="solid">Viável</Badge>
```

**Fora deste repositório** (protótipo HTML, Claude no navegador), não há de onde importar: carregue as folhas publicadas em `https://dataland-design-system.pages.dev/estilo/` (`00-fonte.css`, `00-tokens.css`, `01-mundo.css`, `30-botao.css`, `31-badge.css`) e use as mesmas classes que os componentes React aplicam. Button: `.btn` + `.btn-marca` (primary) / `.btn-contorno` (outline) / `.btn-fantasma` (ghost) / `.btn-risco` (danger), `.btn-sm` pro tamanho pequeno. Badge: `.bdg` + `.bdg-marca` / `.bdg-ok` / `.bdg-atencao` / `.bdg-risco` / `.bdg-calado` pra cor, `.bdg-solido` / `.bdg-contorno` / `.bdg-fantasma` pro preenchimento, `.bdg-sm` / `.bdg-lg` pro tamanho. As classes continuam em português porque são as mesmas do protótipo; só a API React foi pra inglês.

Este aviso existe por um resultado MEDIDO, não por precaução: a Atlassian testou o formato DESIGN.md contra um servidor MCP na mesma tarefa e registrou que, por descrever especificação em vez de apontar pro pacote, o DESIGN.md **torna o agente mais propenso a recriar o componente do que a usar o que existe**. Se a peça está na lista acima, importe. Se não está, ela não existe — veja Pendencias e pergunte, não construa.

O CSS de componente mora em `estilo/30-botao.css` e `estilo/31-badge.css`, e **é a mesma folha que o protótipo carrega**. Uma cópia só: mudar aqui muda no produto.

**Componente não escolhe cor, pede papel.** Nunca escreva hexadecimal, `rgba()`, nem pilha de fonte dentro de um componente — peça `{colors.acao}`, `{colors.sup-2}`, `{colors.borda}`. Se falta um papel, crie o token; não resolva com valor solto.

**Cinco estados, sempre**: normal, hover, selecionado, desabilitado, foco. Foco visível por teclado é obrigatório. O anel de foco é **global e único** — não crie um por componente.

**Composição, não configuração.** Sintoma de caminho errado: a prop nova que você quer adicionar é um booleano que muda layout. Três booleanos são oito combinações, e você testou duas.

**Não implemente comportamento do zero.** Popover, select, combobox, dialog, tooltip e campo de data vem da primitiva do shadcn/ui (Base UI ou Radix) e são estilizados. A tooltip com link dentro foi feita à mão aqui e tomou três rodadas; as três piores armadilhas só apareceram rodando no navegador.

Duas decisões do sistema **não cabem no bloco de tokens acima**, porque o vocabulário de componente desta spec não tem lugar pra elas — e as duas são obrigatórias:

- **Anel de foco**: um só, global, cinza neutro translúcido de 3px com 1px de deslocamento. Não crie anel por componente.
- **Realce da ação primária**: a única sombra colorida do sistema, derivada da cor de ação. Só o botão de variant primary a usa; as outras sombras são profundidade neutra.

## Do's and Don'ts

**Faça**

- Declare a origem de todo número: público, referência, premissa ou derivado.
- Use o par `-tx` para texto e o tom base para preenchimento e borda.
- Use `t2` para texto secundário, em qualquer superfície.
- Trate as quatro saídas de toda tela com dado: carregando, erro, vazio, sucesso.
- Escreva vazio como resposta do produto, não como desculpa: "nenhum cenário viável para este terreno" é informação.
- Meça contraste no navegador, nos dois temas, antes de dizer que acabou.

**Evite**

- Inventar um valor plausível para preencher a tela. Não mostrar é melhor.
- Escrever hexadecimal, `rgba()` ou pilha de fonte dentro de um componente.
- `var(--x, #fallback)` onde `--x` não existe: é literal disfarcado de token.
- Usar o tom de risco para ação que não é destrutiva: vermelho significa "isso não volta atrás", não "isso é importante".
- Dar ícone ao badge. O rótulo já diz tudo, e ícone seria um segundo sinal para a mesma informação no tamanho exato em que ícone falha.
- Clarear texto até sumir para criar hierarquia. Use tamanho e peso.
- Mais de uma ação primária por tela.
- Criar endpoint, mexer em autenticação ou incluir dado de cliente real: isso é de engenharia, não da camada de view.

## Pendencias

O que este design system **ainda não resolve**. Se você é um agente e a tarefa cair aqui, **pare e pergunte** em vez de preencher a lacuna com algo plausível — design plausível é perigoso justamente porque parece pronto.

- **O tema escuro não está no bloco de tokens acima.** Ele existe e funciona, mas a spec alpha do DESIGN.md não tem conceito de tema, e inventar um seria adivinhar formato. As inversões que importam estão descritas na seção Colors.
- **Sombra, borda e anel de foco não são expressáveis** no vocabulário de componente desta spec (só backgroundColor, textColor, typography, rounded, padding, size, height, width). O realce da ação primária e o anel de foco global viraram prosa em Components.
- **Os tingimentos de fundo do tema claro** (`ok-t`, `at-t`, `no-t`, `info-t`) são hexadecimal herdado da paleta anterior, não derivados do oklch atual.
- **A cor de ação no tema escuro não passou pelo manual de marca.** É derivação necessária, porque o roxo oficial é invisível sobre canvas escuro — mas é proposta, não decisão aprovada.
- **`ok` como componente reprova sobre o fundo da janela** (2,88:1 contra o 3:1 exigido). Passa sobre a folha (3,22:1). Não corrigido porque subir o tom mexe na paleta dos dois produtos e precisa passar pelo padrão visual.
- **Muitos tokens de cor aparecem como órfãos no lint** — a categórica (`c1` a `c5`), `mundo`, `dourado`, `decor` e os tons de texto. Não é defeito: eles servem mapa, fundo de janela e régua, não componente. O aviso está correto e a resposta é esta linha, não apagar o token.
- **O aviso `contrast-ratio` do validador oficial dá falso-positivo em fundo translúcido, e não deve ser usado como prova de acessibilidade.** Ele trata `rgba(20,20,34,.05)` como cor opaca em vez de compor sobre a página. Medido no navegador: `badge-neutral` dá **7,2:1** onde o validador afirma 2,05:1, e `badge-primary` dá **10,1:1** onde ele afirma 1,00:1. Os dois passam. O gate de contraste real deste repositório é o axe rodando em Chromium sobre toda story, não este lint — aqui o lint vale pela checagem ESTRUTURAL (referência quebrada, token inválido), que é onde ele acerta.
- **O validador também não conhece o limiar de 3:1 da WCAG 1.4.11** para elemento não-textual (borda, rail, ícone). Ele só checa 4,5:1. O sistema de pares `--X`/`--X-tx` deste design system é mais rigoroso que o validador nesse ponto: não relaxe a regra porque o lint passou.
