# Representação, Picker, Radio, Tabs, Media Card e Live — contrato v1.5

## Emoji

Emoji é uma representação configurável, não uma família alternativa de ícones de ação.

| Papel | Classe | Caixa |
|---|---|---:|
| Compact | `.b-emoji--sm` | 16 × 16px |
| Default | `.b-emoji` | 20 × 20px |
| Large | `.b-emoji--lg` | 24 × 24px |
| Display | `.b-emoji--xl` | 32 × 32px |

A caixa, o `font-size` e o `line-height` avançam juntos. Use a pilha nativa de emoji colorido. Emoji decorativo recebe `aria-hidden="true"`; o controle ou texto adjacente carrega o significado. Não use emoji cru fora de `.b-emoji`, exceto em exemplos de código. O detector inclui pictogramas, pares Regional Indicator e keycaps.

## Picker

O Picker preserva a anatomia do Mark Selector de referência:

- frame border-box de 378px, derivado de 10 × 36px + 8px por lado + bordas;
- categoria com 42px e tipografia 14px/400/21px, igual ao sidebar;
- um painel visível por vez, com 320px para preservar a proporção 390/372 da referência após a normalização de largura;
- dez células fixas por linha em qualquer viewport; abaixo da largura natural, a rolagem fica contida no painel;
- células 36 × 36px, Squircle 16px, com emoji e ícone em caixa 20px igual à navegação lateral;
- indicador de tab com 2px, compartilhado com Tabs, deslocamento lateral animado e direção lógica em RTL;
- tabs com roving tabindex, setas, Home e End;
- cada listbox visual mantém uma única parada de Tab; setas percorrem célula/linha e Home/End percorrem os extremos;
- seleção única atualiza `aria-selected`, input hidden, `data-value`, `data-kind` e live region; `baluarte:picker-change` só é emitido quando a opção efetivamente muda;
- controles desabilitados são ignorados por setas, Home e End e nunca recebem seleção ou `tabindex="0"`;
- marcação inicial inválida com seleção ausente, múltipla ou desabilitada é normalizada para uma única opção habilitada; valor, tipo, hidden input e anúncio inicial são sincronizados sem disparar evento de mudança;
- upload real por clique ou drop, com validação de imagem, label acessível e inset lateral simétrico;
- células e upload permanecem Squircle; categorias permanecem Rounded e alteram somente a superfície interna no hover.

A referência usava `width: 100%` no upload dentro de uma área com padding de 8px. No Baluarte, isso resulta em 9px por lado quando a borda externa de 1px é incluída.

O comportamento público vive em `assets/js/components.js`; consumidores não carregam `portal.js`. A fixture `fixtures/consumer-representation-v1.5.html` comprova CSS e runtime fora do shell documental. Rodadas editoriais preservam integralmente essa apresentação e não alteram a anatomia do Picker ou de Tabs.

## Radio

`.b-radio-group[role="radiogroup"]` pertence ao runtime público `assets/js/components.js`, nunca ao shell do portal. O grupo normaliza seleção inicial, mantém um único `aria-checked="true"` e um único `tabindex="0"`, ignora radios desabilitados e responde a clique, setas, Home e End. Mudanças reais emitem `baluarte:radio-change`; clique repetido ou navegação em grupo com uma única opção habilitada são silenciosos. O ponto interno sólido de 8px é parte da anatomia selecionada.

## Tabs

A anatomia separa a célula `.b-tab` do conteúdo `.b-tab__inner`. Tabs usam 14px/400/21px, igual ao sidebar; ícones associados ao título permanecem em 16px. Hover e active alteram apenas a superfície interna. Seleção usa um indicador único de 2px que anima `inset-inline-start` e largura, com direção lógica em RTL; o Picker consome a mesma espessura e duração. Foco permanece azul e não depende do hover.

## Media Card

A mídia é quadrada. O footer é um bloco de largura integral com padding 10 × 12px. Nome e meta são blocos separados; os insets esquerdo, direito e inferior do footer em relação ao card têm delta geométrico zero.

Hover preserva a borda original e aplica `--elevation-2`, como o Card Interactive. Active retorna a `--elevation-1`; não use borda escura nem `transform` para simular profundidade. O glyph usa o ícone Phosphor específico da extensão e a cor categórica `--file-*` correspondente.

## Estados Publicado e Live

Os estados são separados porque disponibilidade pública e atividade em tempo real não são equivalentes.

### Publicado

`.b-status-indicator--published` significa conteúdo publicado ou publicamente disponível.

- slot estável de 14 × 14px;
- ponto central azul de 6px;
- anel azul limitado ao slot, expandindo em 1 segundo;
- em `prefers-reduced-motion: reduce`, o pulso vira halo estático.

### Live

`.b-status-indicator--live` significa sessão, transmissão ou processo efetivamente em andamento.

- ponto verde estável de 8px;
- halo sem animação;
- label textual `Live` obrigatório.

Cor e movimento nunca são o único sinal. Warning, success, Publicado, Live e loading permanecem estados distintos. A referência ClickAgents usa o slot azul de 14px para disponibilidade; o Baluarte torna a distinção semântica explícita.

## Aprovação

Validar:

- Chromium, Firefox e WebKit;
- claro, escuro, desktop, mobile e 320px;
- reduced motion;
- caixas 16/20/24/32;
- Picker 378/42/320px, dez colunas de 36px, representações 20px e Squircle 16px;
- Picker com um único tab/panel ativo, seleção observável e uma parada de Tab por listbox;
- clique, teclado em saltos de dez, evento de mudança, file chooser e drop;
- Tabs e categorias do Picker em 14px/400/21px, indicador 2px e movimento lateral real;
- hover das Tabs e células diferente de default;
- Picker e Media Card com delta de perímetro até 0,1px CSS;
- footer do Media Card com padding 10 × 12px, rows em bloco e gap de 2px;
- hover do Media Card sem mudança de borda, com `--elevation-2`, e active com `--elevation-1`;
- extensão e glyph Phosphor do Media Card coerentes;
- Publicado azul pulsante e Live verde estático, ambos com texto;
- nenhum emoji visível fora da API governada.
