---
version: alpha
name: pedro-mantovani-design-analysis
description: Uma interface editorial e técnica para o portfólio de um designer de produto e marca. O sistema roda um canvas de papel quase branco, ritmado por zonas full-bleed grafite e preto, um único azul elétrico usado com restrição, e uma voz monoespaçada nos rótulos técnicos. A tipografia é uma família só, Inter, dividida entre um peso de display fino com tracking negativo apertado e um corpo humanista. A assinatura é uma marca radial de quatro pontas, navegação em pílulas flutuantes, e movimento de reveal na rolagem construído sobre molas interrompíveis. O fio condutor é craft como prova: nada é decorativo, cada valor é uma escolha defensável, e o mesmo documento é lido por pessoas e pela IA que constrói com ele.

colors:
  primary: "#2B49FF"
  primary-active: "#1E38D8"
  primary-soft: "#EDEFFF"
  ink: "#0A0A0A"
  body: "#6E6E70"
  faint: "#737376"
  faint-decorative: "#9B9B9E"
  hairline: "#E6E6E6"
  hairline-soft: "#F0F0F0"
  canvas: "#FAFAFA"
  surface-card: "#FFFFFF"
  surface-soft: "#F4F4F6"
  surface-pill: "#F2F2F4"
  surface-graphite: "#111116"
  surface-black: "#060608"
  on-primary: "#FFFFFF"
  on-dark: "#F4F4F6"
  on-dark-soft: "#9A9AA0"
  success: "#12B76A"
  success-soft: "#E4F6EC"
  danger: "#E5484D"
  danger-soft: "#FCEBEC"
  warning: "#D4A017"
  focus-ring: "rgba(43,73,255,0.20)"
  overlay: "rgba(10,10,20,0.32)"
  scrim: "rgba(250,250,250,0.55)"

colors-dark:
  primary: "#6E8BFF"
  primary-soft: "#171B36"
  ink: "#F4F4F6"
  body: "#9A9AA0"
  faint: "#8B8B92"
  faint-decorative: "#5A5A62"
  hairline: "#22222A"
  canvas: "#0C0C10"
  surface-card: "#16161C"
  surface-soft: "#1D1D25"
  surface-pill: "#1A1A21"
  on-dark: "#F4F4F6"

typography:
  display-xl:
    fontFamily: "Inter, sans-serif"
    fontSize: 60px
    fontWeight: 200
    lineHeight: 1.05
    letterSpacing: -1.8px
  display-lg:
    fontFamily: "Inter, sans-serif"
    fontSize: 48px
    fontWeight: 200
    lineHeight: 1.07
    letterSpacing: -1.4px
  display-md:
    fontFamily: "Inter, sans-serif"
    fontSize: 34px
    fontWeight: 200
    lineHeight: 1.1
    letterSpacing: -0.8px
  title-lg:
    fontFamily: "Inter, sans-serif"
    fontSize: 22px
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: -0.3px
  title-md:
    fontFamily: "Inter, sans-serif"
    fontSize: 17px
    fontWeight: 600
    lineHeight: 1.3
    letterSpacing: -0.2px
  body-lg:
    fontFamily: "Inter, sans-serif"
    fontSize: 17px
    fontWeight: 400
    lineHeight: 1.62
    letterSpacing: 0
  body-md:
    fontFamily: "Inter, sans-serif"
    fontSize: 15px
    fontWeight: 400
    lineHeight: 1.6
    letterSpacing: 0
  label:
    fontFamily: "Inter, sans-serif"
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.2
    letterSpacing: -0.05px
  eyebrow:
    fontFamily: "SF Mono, ui-monospace, Menlo, monospace"
    fontSize: 11px
    fontWeight: 400
    lineHeight: 1.3
    letterSpacing: 2.2px
    textTransform: uppercase
  caption:
    fontFamily: "SF Mono, ui-monospace, Menlo, monospace"
    fontSize: 12px
    fontWeight: 400
    lineHeight: 1.5
    letterSpacing: 0.5px
  button:
    fontFamily: "Inter, sans-serif"
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1
    letterSpacing: -0.05px
  nav-link:
    fontFamily: "Inter, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1
    letterSpacing: -0.05px
  code:
    fontFamily: "SF Mono, ui-monospace, Menlo, monospace"
    fontSize: 12.5px
    fontWeight: 400
    lineHeight: 1.7
    letterSpacing: 0
  metric:
    fontFamily: "Inter, sans-serif"
    fontSize: 40px
    fontWeight: 200
    lineHeight: 1
    letterSpacing: -1.2px

rounded:
  xs: 8px
  sm: 10px
  md: 14px
  lg: 18px
  xl: 24px
  pill: 999px

spacing:
  base: 4px
  xxs: 4px
  xs: 8px
  sm: 12px
  md: 16px
  lg: 24px
  xl: 40px
  xxl: 64px
  gutter: "clamp(20px, 4.5vw, 64px)"
  section: "clamp(64px, 10vh, 120px)"

motion:
  duration-fast: 120ms
  duration-base: 220ms
  duration-slow: 420ms
  easing-standard: "cubic-bezier(.32,.72,0,1)"
  easing-enter: "cubic-bezier(.16,1,.3,1)"
  easing-exit: "cubic-bezier(.4,0,1,1)"
  spring-damping: 0.82
  spring-response: 0.4
  reveal-distance: 16px
  reduced-motion: "troca slide e mola por cross-fade de opacidade; sem overshoot"

components:
  top-bar:
    layout: pílulas flutuantes, não uma barra sólida
    backgroundColor: transparent
    scrollEdge: "véu de backdrop-blur(16px) no mobile/tablet para o conteúdo passar por baixo, nunca pelos vãos"
    height: 54px
  logo-button:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    border: "1px solid {colors.hairline}"
    rounded: "{rounded.pill}"
    size: 54px
    note: "marca radial de quatro pontas, gira 45deg no hover"
  nav-pill:
    backgroundColor: "rgba(255,255,255,0.88)"
    textColor: "{colors.body}"
    typography: "{typography.label}"
    rounded: "{rounded.pill}"
    material: "backdrop-blur(16px) saturate(180%)"
    height: 54px
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.label}"
    rounded: "{rounded.sm}"
    padding: 11px 20px
  button-secondary:
    backgroundColor: "{colors.surface-pill}"
    textColor: "{colors.ink}"
    border: "1px solid {colors.hairline}"
    typography: "{typography.label}"
    rounded: "{rounded.sm}"
    padding: 11px 20px
  button-ghost:
    backgroundColor: transparent
    textColor: "{colors.body}"
    typography: "{typography.label}"
  button-danger:
    backgroundColor: transparent
    textColor: "{colors.danger}"
    border: "1px solid rgba(229,72,77,0.42)"
    rounded: "{rounded.sm}"
  card:
    backgroundColor: "{colors.surface-card}"
    border: "1px solid {colors.hairline}"
    rounded: "{rounded.md}"
    padding: "{spacing.xl}"
    shadow: "0 14px 34px -22px rgba(10,10,40,0.28)"
  section-eyebrow:
    typography: "{typography.eyebrow}"
    textColor: "{colors.faint}"
    note: "régua + número + nome; o meta da direita cai abaixo de 900px"
  badge:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.ink}"
    typography: "{typography.caption}"
    rounded: "{rounded.pill}"
    padding: 4px 12px
    note: "success usa {colors.success}, aguardando usa {colors.primary}; nunca {colors.primary} para estado destrutivo"
  input:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    border: "1px solid {colors.hairline}"
    typography: "{typography.body-md}"
    rounded: "{rounded.sm}"
    padding: 11px 14px
    height: 44px
  segmented-toggle:
    backgroundColor: "{colors.surface-pill}"
    textColor: "{colors.body}"
    typography: "{typography.eyebrow}"
    rounded: "{rounded.pill}"
  text-link:
    backgroundColor: transparent
    textColor: "{colors.primary}"
    typography: "{typography.body-md}"
    note: "sublinhado fino; ênfase, não botão"
  icon-button:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    border: "1px solid {colors.hairline}"
    rounded: "{rounded.pill}"
    size: 44px
  toast:
    backgroundColor: "{colors.ink}"
    textColor: "{colors.canvas}"
    rounded: "{rounded.sm}"
    padding: 9px 13px
    note: "aviso rotineiro; não bloqueia o fluxo"
  modal:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    rounded: "{rounded.md}"
    scrim: "{colors.overlay}"
    note: "só para decisão que bloqueia o fluxo"
  table-row:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    typography: "{typography.body-md}"
    note: "valor monetário tabular, alinhado à direita"
  code-window:
    backgroundColor: "{colors.surface-black}"
    textColor: "{colors.on-dark}"
    typography: "{typography.code}"
    rounded: "{rounded.md}"
    padding: 24px
  tab:
    backgroundColor: transparent
    textColor: "{colors.faint}"
    typography: "{typography.eyebrow}"
    note: "aba ativa recebe superfície de card + tinta ink"
  metric-figure:
    textColor: "{colors.ink}"
    typography: "{typography.metric}"
    note: "número grande em display fino; unidade em mono"
  cta-band:
    backgroundColor: "{colors.surface-black}"
    textColor: "{colors.on-dark}"
    typography: "{typography.display-md}"
    rounded: 0
    padding: "{spacing.section}"
    note: "zona escura full-bleed com uma única ação principal"
  footer:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.faint}"
    typography: "{typography.caption}"
    border: "1px solid {colors.hairline}"
  tooltip:
    backgroundColor: "{colors.ink}"
    textColor: "{colors.canvas}"
    typography: "{typography.caption}"
    rounded: "{rounded.xs}"
    padding: 6px 10px
---

## Visão geral

pedromantovani.com é um portfólio editorial e técnico: um **canvas de papel** quase branco (`{colors.canvas}` — #FAFAFA) ritmado por zonas full-bleed **grafite** (`{colors.surface-graphite}` — #111116) e **preto** (`{colors.surface-black}` — #060608). O ritmo claro para escuro é a cadência da página, não decoração. As zonas escuras são onde o trabalho vai para um palco.

A voltagem da marca vem de **um azul elétrico** (`{colors.primary}` — #2B49FF) usado com restrição deliberada, contra tinta preta e uma voz técnica monoespaçada. Não existe um segundo acento. Onde a maioria dos portfólios apela para gradiente e vidro flutuante, este sistema apela para tipografia, espaçamento e movimento.

A tipografia é uma **família só, Inter**, dividida em duas vozes: um **display fino** (200) com tracking negativo apertado para os títulos, e um **corpo humanista** (400) para a leitura. Rótulos técnicos, números de seção e legendas correm numa face **monoespaçada** (SF Mono) em caixa alta com tracking aberto, a voz de "especificação" que sinaliza que isto é um sistema em uso, não um folheto.

As marcas de assinatura são a **glifo radial de quatro pontas** (uma marca tipo asterisco usada como logo e como marcador de conteúdo), a **navegação em pílulas flutuantes** em vez de uma barra sólida, e o **reveal na rolagem** construído sobre molas interrompíveis.

**Características-chave:**
- Canvas de papel quase branco (`{colors.canvas}`) com tinta quase preta (`{colors.ink}` — #0A0A0A), ritmado por zonas full-bleed grafite e preto.
- Um único acento azul elétrico (`{colors.primary}`), escasso por regra. Ele marca a ação principal e o estado ativo/ao vivo, nada além.
- Uma família tipográfica, Inter: display fino em peso 200 com tracking negativo, corpo humanista em 400. Uma face monoespaçada carrega eyebrows, números e legendas.
- Navegação em pílulas flutuantes (logo circular + pílula de nav + CTA azul) que lê como chrome, nunca como uma barra. No mobile ela ganha um véu de backdrop-blur na borda de rolagem para o conteúdo passar por baixo, nunca pelos vãos.
- Reveal na rolagem com um stagger curto e easing de mola; as letras do título têm um hover de peso variável. Todo movimento é interrompível e respeita `prefers-reduced-motion`.
- Nada decorativo flutua. Cada card, regra e animação senta sobre conteúdo real e justifica o próprio lugar.

## Arquitetura de token e movimento

### Camadas
O token vive em três camadas, e nada pula a fila:
1. **Primitivo:** o valor cru, sem opinião de uso. `blue-600` = #2B49FF, a rampa de tinta, a rampa de papel.
2. **Semântico:** o papel que o valor cumpre. `primary` aponta para `blue-600`; `canvas` aponta para o papel mais claro. É a camada que a interface consome.
3. **Componente:** o token amarrado a um lugar. `button-primary-bg` aponta para `primary`.

A regra: a interface e a IA consomem o **semântico**, nunca o primitivo. É isso que faz o tema escuro ser uma troca na camada semântica, não uma segunda versão de cada tela, e que faz uma marca nova herdar o sistema trocando só a base primitiva.

### Movimento como token
Movimento não é enfeite colado depois, é camada de token com o mesmo rigor da cor. Duração em três passos (`{motion.duration-fast}` 120ms para press e hover, `{motion.duration-base}` 220ms para reveal e troca de estado, `{motion.duration-slow}` 420ms para transição de superfície). Easing padrão `{motion.easing-standard}`, com curvas separadas de entrada e saída. Gestos usam mola (`{motion.spring-damping}` / `{motion.spring-response}`), interrompível, partindo do valor atual em tela. O reveal desloca no máximo `{motion.reveal-distance}` (16px). Sob `prefers-reduced-motion`, tudo vira cross-fade de opacidade, sem overshoot.

## Cores

### Marca e acento
- `{colors.primary}` #2B49FF — o único acento. CTA principal, estado ativo/ao vivo, ênfase de link.
- `{colors.primary-active}` #1E38D8 — profundidade de pressionado/ativo para o primário.
- `{colors.primary-soft}` #EDEFFF — lavagem do acento atrás de estados selecionados ou destacados.

### Superfície
- `{colors.canvas}` #FAFAFA — piso padrão do corpo.
- `{colors.surface-card}` #FFFFFF — cards e contêineres elevados.
- `{colors.surface-soft}` #F4F4F6 — insets, molduras de código, painéis secundários.
- `{colors.surface-pill}` #F2F2F4 — fundos de pílula e segmentos.
- `{colors.surface-graphite}` #111116 — primeira zona escura, full-bleed.
- `{colors.surface-black}` #060608 — zona mais profunda, o palco do produto ao vivo.

### Texto
- `{colors.ink}` #0A0A0A — títulos e texto principal.
- `{colors.body}` #6E6E70 — corpo de texto.
- `{colors.faint}` #9B9B9E — eyebrows, meta, legendas.
- Nas zonas escuras, o texto inverte para `{colors.on-dark}` #F4F4F6 e `{colors.on-dark-soft}` #9A9AA0.

### Semântica
- `{colors.success}` #12B76A — estado confirmado/concluído.
- `{colors.danger}` #E5484D — ação destrutiva e erro apenas.

Um **tema escuro** espelha cada token (`colors-dark`): canvas #0C0C10, card #16161C, e o acento sobe para #6E8BFF para segurar contraste no escuro. O tema é um atributo de dado na raiz; a página inteira re-tematiza a partir dos tokens, nunca por override de tela.

## Tipografia

### Família
- **Inter** (100–700) — a única família da interface. Display e corpo são a mesma face em pesos diferentes.
- **SF Mono / ui-monospace** — eyebrows, números de seção, legendas e anotação técnica.

### Hierarquia
- `{typography.display-xl}` — título de herói, Inter 200, tracking negativo apertado.
- `{typography.display-md}` — título de seção.
- `{typography.title-lg}` / `title-md` — títulos de componente e card, peso 600.
- `{typography.body-lg}` / `body-md` — texto de leitura.
- `{typography.eyebrow}` — mono, caixa alta, +2.2px de tracking. A voz de "especificação".

### Princípios
- Tracking é específico do tamanho: display grande vai negativo, corpo fica em zero, eyebrow mono vai positivo. Nunca um valor único de tracking para todos os tamanhos.
- Peso carrega mais hierarquia do que tamanho. O display é fino de propósito; deixá-lo em negrito quebra a voz.
- A entrelinha aperta conforme o tamanho cresce: ~1.05 no display, ~1.6 no corpo.

### Nota sobre substitutos de fonte
Se a Inter não estiver disponível, o fallback é `system-ui`. O peso fino do display é essencial, não substitua por uma face sem um 200 usável.

## Layout

### Sistema de espaçamento
Unidade base **4px**, nunca um número mágico. Escala: 4 / 8 / 12 / 16 / 24 / 40 / 64. O ritmo de seção é fluido: `{spacing.section}` = clamp(64px, 10vh, 120px). A goteira da página é `{spacing.gutter}` = clamp(20px, 4.5vw, 64px), então respira no desktop e aperta para 20px no mobile.

### Grid e contêiner
Largura máxima de conteúdo entre 1180 e 1680px conforme a seção, centralizada. O corpo de texto limita em ~62ch para leitura. O conteúdo é uma coluna por padrão; múltiplas colunas só onde a relação é real.

### Filosofia de espaço em branco
O espaço em branco é estrutural, não sobra. As seções abrem com uma régua fina e um eyebrow, depois respiram antes do título. A densidade reduz nas telas menores em vez de encolher por igual.

## Elevação e profundidade

A profundidade é discreta: bordas de fio (`{colors.hairline}`) mais sombras longas, suaves e de baixa opacidade (`0 14px 34px -22px rgba(10,10,40,0.28)`). Navegação e materiais usam backdrop-blur para o conteúdo ler através deles. O peso do material codifica hierarquia: uma superfície maior recebe um blur mais forte e uma sombra mais profunda. Nunca empilhe uma superfície translúcida sobre outra.

### Profundidade decorativa
Não existe, por regra. Sem vidro flutuante, sem card órfão, sem ornamento que não esteja preso a conteúdo real.

## Formas

### Escala de raio de borda
- `{rounded.sm}` 10px — botões e inputs.
- `{rounded.md}` 14px — cards e contêineres de conteúdo.
- `{rounded.lg}` 18px — painéis grandes.
- `{rounded.pill}` 999px — nav, badges, toggles segmentados.

### Fotografia e ilustração
Chrome de produto real sobre ilustração abstrata: telas de verdade, mockups reais, componentes ao vivo. Quando uma imagem não justifica o próprio lugar, ela vira um índice de texto em vez de enchimento.

## Componentes

### Navegação superior
Pílulas flutuantes, não uma barra: um logo circular, uma pílula de nav central com material de backdrop-blur, e um CTA azul. Lê como chrome. No mobile/tablet, um véu de backdrop-blur na borda de rolagem senta atrás das pílulas para o conteúdo rolar por baixo, nunca pelos vãos.

### Botões
- `{components.button-primary}` — preenchimento azul. **Um por tela.**
- `{components.button-secondary}` — pílula neutra, borda de fio.
- `{components.button-ghost}` — só texto, para Cancelar e ações de baixo peso.
- `{components.button-danger}` — contorno vermelho. Destrutivo apenas, nunca azul.

### Cards e contêineres
Superfície branca, borda de fio, raio de 14px, padding generoso de 40px, sombra longa e suave. Nas zonas escuras trocam para `{colors-dark.surface-card}`.

### Inputs e formulários
Fundo canvas, borda de fio, altura mínima de 44px para toque. O foco sobe a borda para `{colors.primary}` com um anel suave. Erros explicam a causa e o caminho de saída inline, nunca um "inválido" seco.

### Tags e badges
Pílula sobre `{colors.surface-soft}`, legenda mono. Success usa `{colors.success}`, aguardando usa `{colors.primary}`.

### Aba e filtro
Toggle segmentado sobre um fundo de pílula; o segmento ativo ganha uma superfície de card elevada. Usado para trocar tema e idioma.

### CTA e rodapé
Zona escura full-bleed com uma única ação principal. O CTA azul inverte para branco sobre azul quando senta na faixa azul, para nunca sumir.

## Estados

Um componente sem estado documentado empurra a decisão para quem implementa, e é onde a IA e o júnior mais erram. Todo componente interativo carrega a matriz; toda superfície de dado carrega os estados de tela.

### Estados de componente
- **default:** repouso.
- **hover:** feedback no ponteiro. O primário escurece para `{colors.primary-active}`; o resto ganha um leve fundo neutro.
- **focus:** anel visível de `{colors.focus-ring}`, nunca só a mudança de cor. Vale para teclado e para leitor de tela.
- **active/press:** encolhe para 0.97 com `{motion.duration-fast}`.
- **disabled:** opacidade reduzida, sem sombra, cursor bloqueado. Nunca só a cor, para não depender de percepção de cor.
- **loading:** spinner no lugar do rótulo e o clique bloqueado, para não disparar a ação duas vezes.
- **error:** só em campo e formulário. Borda `{colors.danger}` mais mensagem que diz a causa e o caminho.

### Estados de tela
- **empty:** o que aparece quando ainda não há dado. Uma linha do que é, uma do porquê está vazio, uma ação para começar. Nunca uma tela em branco.
- **loading:** skeleton no formato do conteúdo final, não um spinner solto no meio da tela.
- **error:** o que aparece quando a busca falha. A causa em linguagem clara e um botão para tentar de novo, nunca um código seco.

## Faça e não faça

Estas são as regras de comportamento, a camada que diz *quando*, em português claro, ao lado dos tokens. É o que um colega novo, ou uma IA montando uma tela, erra sem ser avisado.

### Faça
- **Um botão primário por tela.** O preenchimento azul marca a única ação principal; o resto é secundário ou ghost.
- **Reserve `{colors.primary}` para a ação principal e o estado ativo/ao vivo.** A escassez é o que faz ele ler como importante.
- **Dê à ação destrutiva o estilo `{components.button-danger}`, e ponha ao lado um Cancelar neutro.** Excluir nunca parece Salvar.
- **Use um toast para uma confirmação rotineira; reserve o modal para a decisão que bloqueia o fluxo.** Interrompa só quando o usuário precisa escolher.
- **Mantenha o Cancelar ao lado da ação principal, sempre em estilo neutro (ghost/secundário).** Toda tela tem um caminho de volta.
- **Renderize valor monetário tabular e alinhado à direita.** As colunas de valor precisam alinhar para o olho comparar.
- **Reduza informação nas telas pequenas.** Solte o meta da seção, esconda o grafo pesado, mantenha a história. Nem tudo precisa viajar para o mobile.
- **Espace em tokens.** Se um valor não está na escala de 4px ou num token nomeado, não entra.
- **Alterne as bandas: papel, grafite, preto.** O claro para escuro é a cadência; use a zona escura como palco do produto ao vivo, não como decoração.
- **Eyebrows e números em mono, caixa alta.** É a voz de especificação que sinaliza sistema em uso.

### Não faça
- **Não coloque dois botões azuis numa tela.** Dois primários é nenhum primário.
- **Não pinte de azul uma ação destrutiva.** Mesmo peso de Salvar é uma armadilha que o token evita.
- **Não transforme um aviso rotineiro em modal.** Um toast informa sem parar a tarefa.
- **Não use um segundo acento.** O azul único é a voltagem da marca; um arco-íris de estados dilui.
- **Não flutue vidro decorativo ou card órfão.** Se um elemento não está sobre conteúdo real, ele não pertence.
- **Não deixe o display fino em negrito.** Peso 200 com tracking é a voz; um título em negrito quebra.
- **Não use travessão na copy de interface ou de marca.** Reescreva com dois-pontos, vírgula ou ponto. Lê como texto de máquina.
- **Não fixe cor ou espaçamento na mão.** Se não é token, não escala nem tematiza.
- **Não repita o mesmo modo de superfície em duas bandas seguidas.** O ritmo alterna; duas zonas iguais matam a cadência.
- **Não encha a tela de movimento.** Reveal ≤16px com easing de mola; nada de slide duro ou parallax gratuito.

## Acessibilidade

Acessibilidade é spec com número, não intenção. O sistema documenta o contraste por par de token e não deixa texto significativo abaixo de AA (WCAG 4.5:1 para texto normal).

### Contraste sobre o canvas (tema claro)
| Par | Ratio | Nível |
|---|---|---|
| `ink` #0A0A0A sobre `canvas` | 19.1:1 | AAA |
| `primary` #2B49FF sobre `canvas` | 5.7:1 | AA |
| `body` #6E6E70 sobre `canvas` | 4.9:1 | AA |
| `faint` #737376 sobre `canvas` | 4.5:1 | AA |
| `on-primary` #FFFFFF sobre `primary` | 6.0:1 | AA |
| `faint-decorative` #9B9B9E sobre `canvas` | 2.6:1 | só ornamental |

`faint-decorative` fica abaixo de AA de propósito e por isso **nunca carrega texto que precise ser lido**: só régua, hairline e marcador `##`. A versão anterior usava esse valor no eyebrow e no meta, o que reprovava em AA. Corrigido.

### Regra de craft que sai daqui
A hierarquia do texto secundário vem do **registro** (mono, caixa alta, tracking aberto), não de contraste abaixo de AA. Eyebrow lê como secundário porque muda de voz, não porque some.

### Foco, alvo e movimento
- **Foco visível** é obrigatório: anel de `{colors.focus-ring}`, nunca só troca de cor. `:focus-visible` para não poluir o clique de mouse.
- **Alvo de toque** ≥ 44px em qualquer controle no mobile.
- **prefers-reduced-motion:** slide e mola viram cross-fade; **prefers-reduced-transparency:** materiais ficam sólidos; **prefers-contrast: more:** bordas quase sólidas.

## Comportamento responsivo

### Breakpoints
- ≥1200px — grid de desktop completo, o herói divide em copy + agente ao vivo.
- 820–1199px — tablet; os itens da pílula de nav colapsam num único controle Menu.
- ≤767px — mobile; tudo empilha em uma coluna, o display reduz de tamanho.
- ≤560px — compacto; o logo e o CTA encolhem para círculos de 46px, o texto do CTA cai para o ícone.

### Alvos de toque
Alvos interativos ficam ≥44px. Botões e inputs nunca caem abaixo disso no mobile.

### Estratégia de colapso
Reduzir, não encolher por igual. No mobile e tablet: o meta da direita some, o grafo de conhecimento (force-directed) é trocado pelo texto (vira ruído quando espremido), e a nav ganha um véu de backdrop-blur na borda de rolagem para o conteúdo ler por baixo com limpeza.

### Comportamento de imagem
Imagens limitam em 100% da largura; conteúdo largo (tabelas, diagramas, código) rola dentro do próprio contêiner, então o corpo da página nunca rola para o lado.

## Guia de iteração

- Adicione um token antes de adicionar um valor. Cor ou espaçamento novo entra primeiro na escala.
- Todo componente novo documenta a regra de comportamento em Faça e não faça, não só a aparência.
- Movimento é desenhado junto com os pixels, não colado depois. Transições novas partem do valor atual em tela e continuam interrompíveis.
- Quando um valor é questionado, ele deve ser defensável a partir deste documento. Nada é aleatório.

## Lacunas conhecidas

- A escala de tipo está documentada em tamanhos fixos aqui; em produção ela é fluida (clamp) e reduz por breakpoint.
- Tokens de texto por opacidade (`{colors.body}`, `{colors.faint}`) vêm como aproximações em hex chapado por portabilidade; o sistema ao vivo usa alfa sobre o canvas.
- Tokens de visualização de dados e gráficos ainda não estão formalizados. Gráficos hoje herdam tinta, acento e fio de forma ad hoc.
- **Modelo operacional** (governança de contribuição, versionamento Semver, métrica de adoção, pipeline token para código via Style Dictionary) é a próxima camada de maturidade. Fica fora deste documento de propósito: é a parte que só faz sentido escrita contra um time real, e encenar processo de time num sistema de uma pessoa seria teatro, não craft.
